From 390eea03ce71b5c3a6dcb493812d744a8986c241 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Thu, 11 Aug 2011 15:13:48 +0200 Subject: qemu help --- target/ppc/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/target/ppc/Makefile b/target/ppc/Makefile index a60d376a9..c643d6c5c 100644 --- a/target/ppc/Makefile +++ b/target/ppc/Makefile @@ -20,9 +20,17 @@ imageinstall: $(BIN_DIR)/$(INITRAMFS) @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_PPC),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-ppc -M mac99 -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' +endif endif ifeq ($(ADK_TARGET_FS),initramfs-piggyback) imageinstall: ${BUILD_DIR}/${INITRAMFS_PIGGYBACK} createinitramfs @cp $(KERNEL) $(BIN_DIR)/${TARGET_KERNEL} @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_PPC),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-ppc -M mac99 -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' +endif endif -- cgit v1.2.3 From 262c556759cc36fecca894721c91b06a6ce3b8f0 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Fri, 12 Aug 2011 13:23:46 +0200 Subject: enable ipv6 module by default --- target/linux/config/Config.in.network | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/config/Config.in.network b/target/linux/config/Config.in.network index 6e4267857..2ec253111 100644 --- a/target/linux/config/Config.in.network +++ b/target/linux/config/Config.in.network @@ -158,7 +158,7 @@ config ADK_KPACKAGE_KMOD_NET_IPGRE config ADK_KPACKAGE_KMOD_IPV6 prompt "kmod-ipv6......................... IPv6 support" tristate - default n + default m help This is complemental support for the IP version 6. You will still be able to do traditional IPv4 networking as well. -- cgit v1.2.3 From 432ae1a94f4d543da3aa2ed226cd3c00e350e3c4 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 21 Aug 2011 10:28:27 +0200 Subject: use qemu to execute sizer binary, remove pregenerated stuff --- jtools/openjdk/files/sizes.32 | 790 --------------------------- jtools/openjdk/files/sizes.64 | 790 --------------------------- package/openjdk/Makefile | 4 - package/openjdk/patches/disable-sizers.patch | 12 - package/openjdk/patches/qemu-sizer.patch | 22 + 5 files changed, 22 insertions(+), 1596 deletions(-) delete mode 100644 jtools/openjdk/files/sizes.32 delete mode 100644 jtools/openjdk/files/sizes.64 delete mode 100644 package/openjdk/patches/disable-sizers.patch create mode 100644 package/openjdk/patches/qemu-sizer.patch diff --git a/jtools/openjdk/files/sizes.32 b/jtools/openjdk/files/sizes.32 deleted file mode 100644 index 2277d4039..000000000 --- a/jtools/openjdk/files/sizes.32 +++ /dev/null @@ -1,790 +0,0 @@ -long 4 -int 4 -short 2 -ptr 4 -Bool 4 -Atom 4 -Window 4 -Screen.ext_data 0 -Screen.display 4 -Screen.root 8 -Screen.width 12 -Screen.height 16 -Screen.mwidth 20 -Screen.mheight 24 -Screen.ndepths 28 -Screen.depths 32 -Screen.root_depth 36 -Screen.root_visual 40 -Screen.default_gc 44 -Screen.cmap 48 -Screen.white_pixel 52 -Screen.black_pixel 56 -Screen.max_maps 60 -Screen.min_maps 64 -Screen.backing_store 68 -Screen.save_unders 72 -Screen.root_input_mask 76 -Screen 80 -XMapRequestEvent.type 0 -XMapRequestEvent.serial 4 -XMapRequestEvent.send_event 8 -XMapRequestEvent.display 12 -XMapRequestEvent.parent 16 -XMapRequestEvent.window 20 -XMapRequestEvent 24 -AwtScreenData.numConfigs 0 -AwtScreenData.root 4 -AwtScreenData.whitepixel 8 -AwtScreenData.blackpixel 12 -AwtScreenData.defaultConfig 16 -AwtScreenData.configs 20 -AwtScreenData 24 -XIMPreeditCaretCallbackStruct.position 0 -XIMPreeditCaretCallbackStruct.direction 4 -XIMPreeditCaretCallbackStruct.style 8 -XIMPreeditCaretCallbackStruct 12 -XTimeCoord.time 0 -XTimeCoord.x 4 -XTimeCoord.y 6 -XTimeCoord 8 -XWindowChanges.x 0 -XWindowChanges.y 4 -XWindowChanges.width 8 -XWindowChanges.height 12 -XWindowChanges.border_width 16 -XWindowChanges.sibling 20 -XWindowChanges.stack_mode 24 -XWindowChanges 28 -XSelectionClearEvent.type 0 -XSelectionClearEvent.serial 4 -XSelectionClearEvent.send_event 8 -XSelectionClearEvent.display 12 -XSelectionClearEvent.window 16 -XSelectionClearEvent.selection 20 -XSelectionClearEvent.time 24 -XSelectionClearEvent 28 -XKeyboardControl.key_click_percent 0 -XKeyboardControl.bell_percent 4 -XKeyboardControl.bell_pitch 8 -XKeyboardControl.bell_duration 12 -XKeyboardControl.led 16 -XKeyboardControl.led_mode 20 -XKeyboardControl.key 24 -XKeyboardControl.auto_repeat_mode 28 -XKeyboardControl 32 -XIMStatusDrawCallbackStruct.type 0 -XIMStatusDrawCallbackStruct.data 4 -XIMStatusDrawCallbackStruct 8 -XOMCharSetList.charset_count 0 -XOMCharSetList.charset_list 4 -XOMCharSetList 8 -XOMFontInfo.num_font 0 -XOMFontInfo.font_struct_list 4 -XOMFontInfo.font_name_list 8 -XOMFontInfo 12 -XIMStringConversionCallbackStruct.position 0 -XIMStringConversionCallbackStruct.direction 4 -XIMStringConversionCallbackStruct.operation 8 -XIMStringConversionCallbackStruct.factor 10 -XIMStringConversionCallbackStruct.text 12 -XIMStringConversionCallbackStruct 16 -XCirculateEvent.type 0 -XCirculateEvent.serial 4 -XCirculateEvent.send_event 8 -XCirculateEvent.display 12 -XCirculateEvent.event 16 -XCirculateEvent.window 20 -XCirculateEvent.place 24 -XCirculateEvent 28 -XIMHotKeyTrigger.keysym 0 -XIMHotKeyTrigger.modifier 4 -XIMHotKeyTrigger.modifier_mask 8 -XIMHotKeyTrigger 12 -XExtData.number 0 -XExtData.next 4 -XExtData.free_private 8 -XExtData.private_data 12 -XExtData 16 -XTextProperty.value 0 -XTextProperty.encoding 4 -XTextProperty.format 8 -XTextProperty.nitems 12 -XTextProperty 16 -XColor.pixel 0 -XColor.red 4 -XColor.green 6 -XColor.blue 8 -XColor.flags 10 -XColor.pad 11 -XColor 12 -XGraphicsExposeEvent.type 0 -XGraphicsExposeEvent.serial 4 -XGraphicsExposeEvent.send_event 8 -XGraphicsExposeEvent.display 12 -XGraphicsExposeEvent.drawable 16 -XGraphicsExposeEvent.x 20 -XGraphicsExposeEvent.y 24 -XGraphicsExposeEvent.width 28 -XGraphicsExposeEvent.height 32 -XGraphicsExposeEvent.count 36 -XGraphicsExposeEvent.major_code 40 -XGraphicsExposeEvent.minor_code 44 -XGraphicsExposeEvent 48 -XStandardColormap.colormap 0 -XStandardColormap.red_max 4 -XStandardColormap.red_mult 8 -XStandardColormap.green_max 12 -XStandardColormap.green_mult 16 -XStandardColormap.blue_max 20 -XStandardColormap.blue_mult 24 -XStandardColormap.base_pixel 28 -XStandardColormap.visualid 32 -XStandardColormap.killid 36 -XStandardColormap 40 -XPropertyEvent.type 0 -XPropertyEvent.serial 4 -XPropertyEvent.send_event 8 -XPropertyEvent.display 12 -XPropertyEvent.window 16 -XPropertyEvent.atom 20 -XPropertyEvent.time 24 -XPropertyEvent.state 28 -XPropertyEvent 32 -ColorEntry.r 0 -ColorEntry.g 1 -ColorEntry.b 2 -ColorEntry.flags 3 -ColorEntry 4 -XResizeRequestEvent.type 0 -XResizeRequestEvent.serial 4 -XResizeRequestEvent.send_event 8 -XResizeRequestEvent.display 12 -XResizeRequestEvent.window 16 -XResizeRequestEvent.width 20 -XResizeRequestEvent.height 24 -XResizeRequestEvent 28 -XFontStruct.ext_data 0 -XFontStruct.fid 4 -XFontStruct.direction 8 -XFontStruct.min_char_or_byte2 12 -XFontStruct.max_char_or_byte2 16 -XFontStruct.min_byte1 20 -XFontStruct.max_byte1 24 -XFontStruct.all_chars_exist 28 -XFontStruct.n_properties 36 -XFontStruct.properties 40 -XFontStruct.min_bounds 44 -XFontStruct.max_bounds 56 -XFontStruct.per_char 68 -XFontStruct.ascent 72 -XFontStruct.descent 76 -XFontStruct 80 -XNoExposeEvent.type 0 -XNoExposeEvent.serial 4 -XNoExposeEvent.send_event 8 -XNoExposeEvent.display 12 -XNoExposeEvent.drawable 16 -XNoExposeEvent.major_code 20 -XNoExposeEvent.minor_code 24 -XNoExposeEvent 28 -XErrorEvent.type 0 -XErrorEvent.display 4 -XErrorEvent.resourceid 8 -XErrorEvent.serial 12 -XErrorEvent.error_code 16 -XErrorEvent.request_code 17 -XErrorEvent.minor_code 18 -XErrorEvent 20 -XArc.x 0 -XArc.y 2 -XArc.width 4 -XArc.height 6 -XArc.angle1 8 -XArc.angle2 10 -XArc 12 -XSelectionEvent.type 0 -XSelectionEvent.serial 4 -XSelectionEvent.send_event 8 -XSelectionEvent.display 12 -XSelectionEvent.requestor 16 -XSelectionEvent.selection 20 -XSelectionEvent.target 24 -XSelectionEvent.property 28 -XSelectionEvent.time 32 -XSelectionEvent 36 -XVisibilityEvent.type 0 -XVisibilityEvent.serial 4 -XVisibilityEvent.send_event 8 -XVisibilityEvent.display 12 -XVisibilityEvent.window 16 -XVisibilityEvent.state 20 -XVisibilityEvent 24 -XFontProp.name 0 -XFontProp.card32 4 -XFontProp 8 -XTextItem16.chars 0 -XTextItem16.nchars 4 -XTextItem16.delta 8 -XTextItem16.font 12 -XTextItem16 16 -XIMPreeditDrawCallbackStruct.caret 0 -XIMPreeditDrawCallbackStruct.chg_first 4 -XIMPreeditDrawCallbackStruct.chg_length 8 -XIMPreeditDrawCallbackStruct.text 12 -XIMPreeditDrawCallbackStruct 16 -XRectangle.x 0 -XRectangle.y 2 -XRectangle.width 4 -XRectangle.height 6 -XRectangle 8 -PropMwmHints.flags 0 -PropMwmHints.functions 4 -PropMwmHints.decorations 8 -PropMwmHints.inputMode 12 -PropMwmHints.status 16 -PropMwmHints 20 -XConfigureEvent.type 0 -XConfigureEvent.serial 4 -XConfigureEvent.send_event 8 -XConfigureEvent.display 12 -XConfigureEvent.event 16 -XConfigureEvent.window 20 -XConfigureEvent.x 24 -XConfigureEvent.y 28 -XConfigureEvent.width 32 -XConfigureEvent.height 36 -XConfigureEvent.border_width 40 -XConfigureEvent.above 44 -XConfigureEvent.override_redirect 48 -XConfigureEvent 52 -XClientMessageEvent.type 0 -XClientMessageEvent.serial 4 -XClientMessageEvent.send_event 8 -XClientMessageEvent.display 12 -XClientMessageEvent.window 16 -XClientMessageEvent.message_type 20 -XClientMessageEvent.format 24 -XClientMessageEvent.data 28 -XClientMessageEvent 48 -XIconSize.min_width 0 -XIconSize.min_height 4 -XIconSize.max_width 8 -XIconSize.max_height 12 -XIconSize.width_inc 16 -XIconSize.height_inc 20 -XIconSize 24 -XSegment.x1 0 -XSegment.y1 2 -XSegment.x2 4 -XSegment.y2 6 -XSegment 8 -XPoint.x 0 -XPoint.y 2 -XPoint 4 -XIMStringConversionText.length 0 -XIMStringConversionText.feedback 4 -XIMStringConversionText.encoding_is_wchar 8 -XIMStringConversionText.string 12 -XIMStringConversionText 16 -XPixmapFormatValues.depth 0 -XPixmapFormatValues.bits_per_pixel 4 -XPixmapFormatValues.scanline_pad 8 -XPixmapFormatValues 12 -XExposeEvent.type 0 -XExposeEvent.serial 4 -XExposeEvent.send_event 8 -XExposeEvent.display 12 -XExposeEvent.window 16 -XExposeEvent.x 20 -XExposeEvent.y 24 -XExposeEvent.width 28 -XExposeEvent.height 32 -XExposeEvent.count 36 -XExposeEvent 40 -XIMStyles.count_styles 0 -XIMStyles.supported_styles 4 -XIMStyles 8 -XSizeHints.flags 0 -XSizeHints.x 4 -XSizeHints.y 8 -XSizeHints.width 12 -XSizeHints.height 16 -XSizeHints.min_width 20 -XSizeHints.min_height 24 -XSizeHints.max_width 28 -XSizeHints.max_height 32 -XSizeHints.width_inc 36 -XSizeHints.height_inc 40 -XSizeHints.min_aspect.x 44 -XSizeHints.min_aspect.y 48 -XSizeHints.max_aspect.x 52 -XSizeHints.max_aspect.y 56 -XSizeHints.base_width 60 -XSizeHints.base_height 64 -XSizeHints.win_gravity 68 -XSizeHints 72 -XMappingEvent.type 0 -XMappingEvent.serial 4 -XMappingEvent.send_event 8 -XMappingEvent.display 12 -XMappingEvent.window 16 -XMappingEvent.request 20 -XMappingEvent.first_keycode 24 -XMappingEvent.count 28 -XMappingEvent 32 -XClassHint.res_name 0 -XClassHint.res_class 4 -XClassHint 8 -XmbTextItem.chars 0 -XmbTextItem.nchars 4 -XmbTextItem.delta 8 -XmbTextItem.font_set 12 -XmbTextItem 16 -XWindowAttributes.x 0 -XWindowAttributes.y 4 -XWindowAttributes.width 8 -XWindowAttributes.height 12 -XWindowAttributes.border_width 16 -XWindowAttributes.depth 20 -XWindowAttributes.visual 24 -XWindowAttributes.root 28 -XWindowAttributes.class 32 -XWindowAttributes.bit_gravity 36 -XWindowAttributes.win_gravity 40 -XWindowAttributes.backing_store 44 -XWindowAttributes.backing_planes 48 -XWindowAttributes.backing_pixel 52 -XWindowAttributes.save_under 56 -XWindowAttributes.colormap 60 -XWindowAttributes.map_installed 64 -XWindowAttributes.map_state 68 -XWindowAttributes.all_event_masks 72 -XWindowAttributes.your_event_mask 76 -XWindowAttributes.do_not_propagate_mask 80 -XWindowAttributes.override_redirect 84 -XWindowAttributes.screen 88 -XWindowAttributes 92 -XSetWindowAttributes.background_pixmap 0 -XSetWindowAttributes.background_pixel 4 -XSetWindowAttributes.border_pixmap 8 -XSetWindowAttributes.border_pixel 12 -XSetWindowAttributes.bit_gravity 16 -XSetWindowAttributes.win_gravity 20 -XSetWindowAttributes.backing_store 24 -XSetWindowAttributes.backing_planes 28 -XSetWindowAttributes.backing_pixel 32 -XSetWindowAttributes.save_under 36 -XSetWindowAttributes.event_mask 40 -XSetWindowAttributes.do_not_propagate_mask 44 -XSetWindowAttributes.override_redirect 48 -XSetWindowAttributes.colormap 52 -XSetWindowAttributes.cursor 56 -XSetWindowAttributes 60 -XOMOrientation.num_orientation 0 -XOMOrientation.orientation 4 -XOMOrientation 8 -Visual.ext_data 0 -Visual.visualid 4 -Visual.class 8 -Visual.red_mask 12 -Visual.green_mask 16 -Visual.blue_mask 20 -Visual.bits_per_rgb 24 -Visual.map_entries 28 -Visual 32 -XGravityEvent.type 0 -XGravityEvent.serial 4 -XGravityEvent.send_event 8 -XGravityEvent.display 12 -XGravityEvent.event 16 -XGravityEvent.window 20 -XGravityEvent.x 24 -XGravityEvent.y 28 -XGravityEvent 32 -XReparentEvent.type 0 -XReparentEvent.serial 4 -XReparentEvent.send_event 8 -XReparentEvent.display 12 -XReparentEvent.event 16 -XReparentEvent.window 20 -XReparentEvent.parent 24 -XReparentEvent.x 28 -XReparentEvent.y 32 -XReparentEvent.override_redirect 36 -XReparentEvent 40 -XCirculateRequestEvent.type 0 -XCirculateRequestEvent.serial 4 -XCirculateRequestEvent.send_event 8 -XCirculateRequestEvent.display 12 -XCirculateRequestEvent.parent 16 -XCirculateRequestEvent.window 20 -XCirculateRequestEvent.place 24 -XCirculateRequestEvent 28 -XKeyEvent.type 0 -XKeyEvent.serial 4 -XKeyEvent.send_event 8 -XKeyEvent.display 12 -XKeyEvent.window 16 -XKeyEvent.root 20 -XKeyEvent.subwindow 24 -XKeyEvent.time 28 -XKeyEvent.x 32 -XKeyEvent.y 36 -XKeyEvent.x_root 40 -XKeyEvent.y_root 44 -XKeyEvent.state 48 -XKeyEvent.keycode 52 -XKeyEvent.same_screen 56 -XKeyEvent 60 -XCharStruct.lbearing 0 -XCharStruct.rbearing 2 -XCharStruct.width 4 -XCharStruct.ascent 6 -XCharStruct.descent 8 -XCharStruct.attributes 10 -XCharStruct 12 -XModifierKeymap.max_keypermod 0 -XModifierKeymap.modifiermap 4 -XModifierKeymap 8 -XTextItem.chars 0 -XTextItem.nchars 4 -XTextItem.delta 8 -XTextItem.font 12 -XTextItem 16 -XdbeSwapInfo.swap_window 0 -XdbeSwapInfo.swap_action 4 -XdbeSwapInfo 8 -XImage.width 0 -XImage.height 4 -XImage.xoffset 8 -XImage.format 12 -XImage.data 16 -XImage.byte_order 20 -XImage.bitmap_unit 24 -XImage.bitmap_bit_order 28 -XImage.bitmap_pad 32 -XImage.depth 36 -XImage.bytes_per_line 40 -XImage.bits_per_pixel 44 -XImage.red_mask 48 -XImage.green_mask 52 -XImage.blue_mask 56 -XImage.obdata 60 -XImage.f.create_image 64 -XImage.f.destroy_image 68 -XImage.f.get_pixel 72 -XImage.f.put_pixel 76 -XImage.f.sub_image 80 -XImage.f.add_pixel 84 -XImage 88 -XChar2b.byte1 0 -XChar2b.byte2 1 -XChar2b 2 -XwcTextItem.chars 0 -XwcTextItem.nchars 4 -XwcTextItem.delta 8 -XwcTextItem.font_set 12 -XwcTextItem 16 -XUnmapEvent.type 0 -XUnmapEvent.serial 4 -XUnmapEvent.send_event 8 -XUnmapEvent.display 12 -XUnmapEvent.event 16 -XUnmapEvent.window 20 -XUnmapEvent.from_configure 24 -XUnmapEvent 28 -awtImageData.Depth 0 -awtImageData.wsImageFormat 4 -awtImageData.clrdata 16 -awtImageData.convert 48 -awtImageData 304 -XGCValues.function 0 -XGCValues.plane_mask 4 -XGCValues.foreground 8 -XGCValues.background 12 -XGCValues.line_width 16 -XGCValues.line_style 20 -XGCValues.cap_style 24 -XGCValues.join_style 28 -XGCValues.fill_style 32 -XGCValues.fill_rule 36 -XGCValues.arc_mode 40 -XGCValues.tile 44 -XGCValues.stipple 48 -XGCValues.ts_x_origin 52 -XGCValues.ts_y_origin 56 -XGCValues.font 60 -XGCValues.subwindow_mode 64 -XGCValues.graphics_exposures 68 -XGCValues.clip_x_origin 72 -XGCValues.clip_y_origin 76 -XGCValues.clip_mask 80 -XGCValues.dash_offset 84 -XGCValues.dashes 88 -XGCValues 92 -XFocusChangeEvent.type 0 -XFocusChangeEvent.serial 4 -XFocusChangeEvent.send_event 8 -XFocusChangeEvent.display 12 -XFocusChangeEvent.window 16 -XFocusChangeEvent.mode 20 -XFocusChangeEvent.detail 24 -XFocusChangeEvent 28 -XMapEvent.type 0 -XMapEvent.serial 4 -XMapEvent.send_event 8 -XMapEvent.display 12 -XMapEvent.event 16 -XMapEvent.window 20 -XMapEvent.override_redirect 24 -XMapEvent 28 -XIMHotKeyTriggers.num_hot_key 0 -XIMHotKeyTriggers.key 4 -XIMHotKeyTriggers 8 -XKeyboardState.key_click_percent 0 -XKeyboardState.bell_percent 4 -XKeyboardState.bell_pitch 8 -XKeyboardState.bell_duration 12 -XKeyboardState.led_mask 16 -XKeyboardState.global_auto_repeat 20 -XKeyboardState.auto_repeats 24 -XKeyboardState 56 -XMotionEvent.type 0 -XMotionEvent.serial 4 -XMotionEvent.send_event 8 -XMotionEvent.display 12 -XMotionEvent.window 16 -XMotionEvent.root 20 -XMotionEvent.subwindow 24 -XMotionEvent.time 28 -XMotionEvent.x 32 -XMotionEvent.y 36 -XMotionEvent.x_root 40 -XMotionEvent.y_root 44 -XMotionEvent.state 48 -XMotionEvent.is_hint 52 -XMotionEvent.same_screen 56 -XMotionEvent 60 -XIMPreeditStateNotifyCallbackStruct.state 0 -XIMPreeditStateNotifyCallbackStruct 4 -XAnyEvent.type 0 -XAnyEvent.serial 4 -XAnyEvent.send_event 8 -XAnyEvent.display 12 -XAnyEvent.window 16 -XAnyEvent 20 -XIMCallback.client_data 0 -XIMCallback.callback 4 -XIMCallback 8 -XVisualInfo.visual 0 -XVisualInfo.visualid 4 -XVisualInfo.screen 8 -XVisualInfo.depth 12 -XVisualInfo.class 16 -XVisualInfo.red_mask 20 -XVisualInfo.green_mask 24 -XVisualInfo.blue_mask 28 -XVisualInfo.colormap_size 32 -XVisualInfo.bits_per_rgb 36 -XVisualInfo 40 -XCreateWindowEvent.type 0 -XCreateWindowEvent.serial 4 -XCreateWindowEvent.send_event 8 -XCreateWindowEvent.display 12 -XCreateWindowEvent.parent 16 -XCreateWindowEvent.window 20 -XCreateWindowEvent.x 24 -XCreateWindowEvent.y 28 -XCreateWindowEvent.width 32 -XCreateWindowEvent.height 36 -XCreateWindowEvent.border_width 40 -XCreateWindowEvent.override_redirect 44 -XCreateWindowEvent 48 -XIMValuesList.count_values 0 -XIMValuesList.supported_values 4 -XIMValuesList 8 -XKeymapEvent.type 0 -XKeymapEvent.serial 4 -XKeymapEvent.send_event 8 -XKeymapEvent.display 12 -XKeymapEvent.window 16 -XKeymapEvent.key_vector 20 -XKeymapEvent 52 -XButtonEvent.type 0 -XButtonEvent.serial 4 -XButtonEvent.send_event 8 -XButtonEvent.display 12 -XButtonEvent.window 16 -XButtonEvent.root 20 -XButtonEvent.subwindow 24 -XButtonEvent.time 28 -XButtonEvent.x 32 -XButtonEvent.y 36 -XButtonEvent.x_root 40 -XButtonEvent.y_root 44 -XButtonEvent.state 48 -XButtonEvent.button 52 -XButtonEvent.same_screen 56 -XButtonEvent 60 -XWMHints.flags 0 -XWMHints.initial_state 8 -XWMHints.icon_pixmap 12 -XWMHints.icon_window 16 -XWMHints.icon_x 20 -XWMHints.icon_y 24 -XWMHints.icon_mask 28 -XWMHints.input 4 -XWMHints.window_group 32 -XWMHints 36 -ScreenFormat.ext_data 0 -ScreenFormat.depth 4 -ScreenFormat.bits_per_pixel 8 -ScreenFormat.scanline_pad 12 -ScreenFormat 16 -XCrossingEvent.type 0 -XCrossingEvent.serial 4 -XCrossingEvent.send_event 8 -XCrossingEvent.display 12 -XCrossingEvent.window 16 -XCrossingEvent.root 20 -XCrossingEvent.subwindow 24 -XCrossingEvent.time 28 -XCrossingEvent.x 32 -XCrossingEvent.y 36 -XCrossingEvent.x_root 40 -XCrossingEvent.y_root 44 -XCrossingEvent.mode 48 -XCrossingEvent.detail 52 -XCrossingEvent.same_screen 56 -XCrossingEvent.focus 60 -XCrossingEvent.state 64 -XCrossingEvent 68 -XConfigureRequestEvent.type 0 -XConfigureRequestEvent.serial 4 -XConfigureRequestEvent.send_event 8 -XConfigureRequestEvent.display 12 -XConfigureRequestEvent.parent 16 -XConfigureRequestEvent.window 20 -XConfigureRequestEvent.x 24 -XConfigureRequestEvent.y 28 -XConfigureRequestEvent.width 32 -XConfigureRequestEvent.height 36 -XConfigureRequestEvent.border_width 40 -XConfigureRequestEvent.above 44 -XConfigureRequestEvent.detail 48 -XConfigureRequestEvent.value_mask 52 -XConfigureRequestEvent 56 -XSelectionRequestEvent.type 0 -XSelectionRequestEvent.serial 4 -XSelectionRequestEvent.send_event 8 -XSelectionRequestEvent.display 12 -XSelectionRequestEvent.owner 16 -XSelectionRequestEvent.requestor 20 -XSelectionRequestEvent.selection 24 -XSelectionRequestEvent.target 28 -XSelectionRequestEvent.property 32 -XSelectionRequestEvent.time 36 -XSelectionRequestEvent 40 -XFontSetExtents.max_ink_extent 0 -XFontSetExtents.max_logical_extent 8 -XFontSetExtents 16 -XExtCodes.extension 0 -XExtCodes.major_opcode 4 -XExtCodes.first_event 8 -XExtCodes.first_error 12 -XExtCodes 16 -XHostAddress.family 0 -XHostAddress.length 4 -XHostAddress.address 8 -XHostAddress 12 -ColorData.awt_Colors 0 -ColorData.awt_numICMcolors 4 -ColorData.awt_icmLUT 8 -ColorData.awt_icmLUT2Colors 12 -ColorData.img_grays 16 -ColorData.img_clr_tbl 20 -ColorData.img_oda_red 24 -ColorData.img_oda_green 28 -ColorData.img_oda_blue 32 -ColorData.pGrayInverseLutData 36 -ColorData.screendata 40 -ColorData 44 -XColormapEvent.type 0 -XColormapEvent.serial 4 -XColormapEvent.send_event 8 -XColormapEvent.display 12 -XColormapEvent.window 16 -XColormapEvent.colormap 20 -XColormapEvent.new 24 -XColormapEvent.state 28 -XColormapEvent 32 -Depth.depth 0 -Depth.nvisuals 4 -Depth.visuals 8 -Depth 12 -XEvent.type 0 -XEvent.xany 0 -XEvent.xkey 0 -XEvent.xbutton 0 -XEvent.xmotion 0 -XEvent.xcrossing 0 -XEvent.xfocus 0 -XEvent.xexpose 0 -XEvent.xgraphicsexpose 0 -XEvent.xnoexpose 0 -XEvent.xvisibility 0 -XEvent.xcreatewindow 0 -XEvent.xdestroywindow 0 -XEvent.xunmap 0 -XEvent.xmap 0 -XEvent.xmaprequest 0 -XEvent.xreparent 0 -XEvent.xconfigure 0 -XEvent.xgravity 0 -XEvent.xresizerequest 0 -XEvent.xconfigurerequest 0 -XEvent.xcirculate 0 -XEvent.xcirculaterequest 0 -XEvent.xproperty 0 -XEvent.xselectionclear 0 -XEvent.xselectionrequest 0 -XEvent.xselection 0 -XEvent.xcolormap 0 -XEvent.xclient 0 -XEvent.xmapping 0 -XEvent.xerror 0 -XEvent.xkeymap 0 -XEvent.pad 0 -XEvent 96 -XDestroyWindowEvent.type 0 -XDestroyWindowEvent.serial 4 -XDestroyWindowEvent.send_event 8 -XDestroyWindowEvent.display 12 -XDestroyWindowEvent.event 16 -XDestroyWindowEvent.window 20 -XDestroyWindowEvent 24 -XComposeStatus.compose_ptr 0 -XComposeStatus.chars_matched 4 -XComposeStatus 8 -AwtGraphicsConfigData.awt_depth 0 -AwtGraphicsConfigData.awt_cmap 4 -AwtGraphicsConfigData.awt_visInfo 8 -AwtGraphicsConfigData.awt_num_colors 48 -AwtGraphicsConfigData.awtImage 52 -AwtGraphicsConfigData.AwtColorMatch 56 -AwtGraphicsConfigData.monoImage 60 -AwtGraphicsConfigData.monoPixmap 64 -AwtGraphicsConfigData.monoPixmapWidth 68 -AwtGraphicsConfigData.monoPixmapHeight 72 -AwtGraphicsConfigData.monoPixmapGC 76 -AwtGraphicsConfigData.pixelStride 80 -AwtGraphicsConfigData.color_data 84 -AwtGraphicsConfigData.glxInfo 88 -AwtGraphicsConfigData.isTranslucencySupported 92 -AwtGraphicsConfigData 96 -XIMText.length 0 -XIMText.feedback 4 -XIMText.encoding_is_wchar 8 -XIMText.string 12 -XIMText 16 diff --git a/jtools/openjdk/files/sizes.64 b/jtools/openjdk/files/sizes.64 deleted file mode 100644 index 9661f857f..000000000 --- a/jtools/openjdk/files/sizes.64 +++ /dev/null @@ -1,790 +0,0 @@ -long 8 -int 4 -short 2 -ptr 8 -Bool 4 -Atom 8 -Window 8 -Screen.ext_data 0 -Screen.display 8 -Screen.root 16 -Screen.width 24 -Screen.height 28 -Screen.mwidth 32 -Screen.mheight 36 -Screen.ndepths 40 -Screen.depths 48 -Screen.root_depth 56 -Screen.root_visual 64 -Screen.default_gc 72 -Screen.cmap 80 -Screen.white_pixel 88 -Screen.black_pixel 96 -Screen.max_maps 104 -Screen.min_maps 108 -Screen.backing_store 112 -Screen.save_unders 116 -Screen.root_input_mask 120 -Screen 128 -XMapRequestEvent.type 0 -XMapRequestEvent.serial 8 -XMapRequestEvent.send_event 16 -XMapRequestEvent.display 24 -XMapRequestEvent.parent 32 -XMapRequestEvent.window 40 -XMapRequestEvent 48 -AwtScreenData.numConfigs 0 -AwtScreenData.root 8 -AwtScreenData.whitepixel 16 -AwtScreenData.blackpixel 24 -AwtScreenData.defaultConfig 32 -AwtScreenData.configs 40 -AwtScreenData 48 -XIMPreeditCaretCallbackStruct.position 0 -XIMPreeditCaretCallbackStruct.direction 4 -XIMPreeditCaretCallbackStruct.style 8 -XIMPreeditCaretCallbackStruct 12 -XTimeCoord.time 0 -XTimeCoord.x 8 -XTimeCoord.y 10 -XTimeCoord 16 -XWindowChanges.x 0 -XWindowChanges.y 4 -XWindowChanges.width 8 -XWindowChanges.height 12 -XWindowChanges.border_width 16 -XWindowChanges.sibling 24 -XWindowChanges.stack_mode 32 -XWindowChanges 40 -XSelectionClearEvent.type 0 -XSelectionClearEvent.serial 8 -XSelectionClearEvent.send_event 16 -XSelectionClearEvent.display 24 -XSelectionClearEvent.window 32 -XSelectionClearEvent.selection 40 -XSelectionClearEvent.time 48 -XSelectionClearEvent 56 -XKeyboardControl.key_click_percent 0 -XKeyboardControl.bell_percent 4 -XKeyboardControl.bell_pitch 8 -XKeyboardControl.bell_duration 12 -XKeyboardControl.led 16 -XKeyboardControl.led_mode 20 -XKeyboardControl.key 24 -XKeyboardControl.auto_repeat_mode 28 -XKeyboardControl 32 -XIMStatusDrawCallbackStruct.type 0 -XIMStatusDrawCallbackStruct.data 8 -XIMStatusDrawCallbackStruct 16 -XOMCharSetList.charset_count 0 -XOMCharSetList.charset_list 8 -XOMCharSetList 16 -XOMFontInfo.num_font 0 -XOMFontInfo.font_struct_list 8 -XOMFontInfo.font_name_list 16 -XOMFontInfo 24 -XIMStringConversionCallbackStruct.position 0 -XIMStringConversionCallbackStruct.direction 4 -XIMStringConversionCallbackStruct.operation 8 -XIMStringConversionCallbackStruct.factor 10 -XIMStringConversionCallbackStruct.text 16 -XIMStringConversionCallbackStruct 24 -XCirculateEvent.type 0 -XCirculateEvent.serial 8 -XCirculateEvent.send_event 16 -XCirculateEvent.display 24 -XCirculateEvent.event 32 -XCirculateEvent.window 40 -XCirculateEvent.place 48 -XCirculateEvent 56 -XIMHotKeyTrigger.keysym 0 -XIMHotKeyTrigger.modifier 8 -XIMHotKeyTrigger.modifier_mask 12 -XIMHotKeyTrigger 16 -XExtData.number 0 -XExtData.next 8 -XExtData.free_private 16 -XExtData.private_data 24 -XExtData 32 -XTextProperty.value 0 -XTextProperty.encoding 8 -XTextProperty.format 16 -XTextProperty.nitems 24 -XTextProperty 32 -XColor.pixel 0 -XColor.red 8 -XColor.green 10 -XColor.blue 12 -XColor.flags 14 -XColor.pad 15 -XColor 16 -XGraphicsExposeEvent.type 0 -XGraphicsExposeEvent.serial 8 -XGraphicsExposeEvent.send_event 16 -XGraphicsExposeEvent.display 24 -XGraphicsExposeEvent.drawable 32 -XGraphicsExposeEvent.x 40 -XGraphicsExposeEvent.y 44 -XGraphicsExposeEvent.width 48 -XGraphicsExposeEvent.height 52 -XGraphicsExposeEvent.count 56 -XGraphicsExposeEvent.major_code 60 -XGraphicsExposeEvent.minor_code 64 -XGraphicsExposeEvent 72 -XStandardColormap.colormap 0 -XStandardColormap.red_max 8 -XStandardColormap.red_mult 16 -XStandardColormap.green_max 24 -XStandardColormap.green_mult 32 -XStandardColormap.blue_max 40 -XStandardColormap.blue_mult 48 -XStandardColormap.base_pixel 56 -XStandardColormap.visualid 64 -XStandardColormap.killid 72 -XStandardColormap 80 -XPropertyEvent.type 0 -XPropertyEvent.serial 8 -XPropertyEvent.send_event 16 -XPropertyEvent.display 24 -XPropertyEvent.window 32 -XPropertyEvent.atom 40 -XPropertyEvent.time 48 -XPropertyEvent.state 56 -XPropertyEvent 64 -ColorEntry.r 0 -ColorEntry.g 1 -ColorEntry.b 2 -ColorEntry.flags 3 -ColorEntry 4 -XResizeRequestEvent.type 0 -XResizeRequestEvent.serial 8 -XResizeRequestEvent.send_event 16 -XResizeRequestEvent.display 24 -XResizeRequestEvent.window 32 -XResizeRequestEvent.width 40 -XResizeRequestEvent.height 44 -XResizeRequestEvent 48 -XFontStruct.ext_data 0 -XFontStruct.fid 8 -XFontStruct.direction 16 -XFontStruct.min_char_or_byte2 20 -XFontStruct.max_char_or_byte2 24 -XFontStruct.min_byte1 28 -XFontStruct.max_byte1 32 -XFontStruct.all_chars_exist 36 -XFontStruct.n_properties 44 -XFontStruct.properties 48 -XFontStruct.min_bounds 56 -XFontStruct.max_bounds 68 -XFontStruct.per_char 80 -XFontStruct.ascent 88 -XFontStruct.descent 92 -XFontStruct 96 -XNoExposeEvent.type 0 -XNoExposeEvent.serial 8 -XNoExposeEvent.send_event 16 -XNoExposeEvent.display 24 -XNoExposeEvent.drawable 32 -XNoExposeEvent.major_code 40 -XNoExposeEvent.minor_code 44 -XNoExposeEvent 48 -XErrorEvent.type 0 -XErrorEvent.display 8 -XErrorEvent.resourceid 16 -XErrorEvent.serial 24 -XErrorEvent.error_code 32 -XErrorEvent.request_code 33 -XErrorEvent.minor_code 34 -XErrorEvent 40 -XArc.x 0 -XArc.y 2 -XArc.width 4 -XArc.height 6 -XArc.angle1 8 -XArc.angle2 10 -XArc 12 -XSelectionEvent.type 0 -XSelectionEvent.serial 8 -XSelectionEvent.send_event 16 -XSelectionEvent.display 24 -XSelectionEvent.requestor 32 -XSelectionEvent.selection 40 -XSelectionEvent.target 48 -XSelectionEvent.property 56 -XSelectionEvent.time 64 -XSelectionEvent 72 -XVisibilityEvent.type 0 -XVisibilityEvent.serial 8 -XVisibilityEvent.send_event 16 -XVisibilityEvent.display 24 -XVisibilityEvent.window 32 -XVisibilityEvent.state 40 -XVisibilityEvent 48 -XFontProp.name 0 -XFontProp.card32 8 -XFontProp 16 -XTextItem16.chars 0 -XTextItem16.nchars 8 -XTextItem16.delta 12 -XTextItem16.font 16 -XTextItem16 24 -XIMPreeditDrawCallbackStruct.caret 0 -XIMPreeditDrawCallbackStruct.chg_first 4 -XIMPreeditDrawCallbackStruct.chg_length 8 -XIMPreeditDrawCallbackStruct.text 16 -XIMPreeditDrawCallbackStruct 24 -XRectangle.x 0 -XRectangle.y 2 -XRectangle.width 4 -XRectangle.height 6 -XRectangle 8 -PropMwmHints.flags 0 -PropMwmHints.functions 8 -PropMwmHints.decorations 16 -PropMwmHints.inputMode 24 -PropMwmHints.status 32 -PropMwmHints 40 -XConfigureEvent.type 0 -XConfigureEvent.serial 8 -XConfigureEvent.send_event 16 -XConfigureEvent.display 24 -XConfigureEvent.event 32 -XConfigureEvent.window 40 -XConfigureEvent.x 48 -XConfigureEvent.y 52 -XConfigureEvent.width 56 -XConfigureEvent.height 60 -XConfigureEvent.border_width 64 -XConfigureEvent.above 72 -XConfigureEvent.override_redirect 80 -XConfigureEvent 88 -XClientMessageEvent.type 0 -XClientMessageEvent.serial 8 -XClientMessageEvent.send_event 16 -XClientMessageEvent.display 24 -XClientMessageEvent.window 32 -XClientMessageEvent.message_type 40 -XClientMessageEvent.format 48 -XClientMessageEvent.data 56 -XClientMessageEvent 96 -XIconSize.min_width 0 -XIconSize.min_height 4 -XIconSize.max_width 8 -XIconSize.max_height 12 -XIconSize.width_inc 16 -XIconSize.height_inc 20 -XIconSize 24 -XSegment.x1 0 -XSegment.y1 2 -XSegment.x2 4 -XSegment.y2 6 -XSegment 8 -XPoint.x 0 -XPoint.y 2 -XPoint 4 -XIMStringConversionText.length 0 -XIMStringConversionText.feedback 8 -XIMStringConversionText.encoding_is_wchar 16 -XIMStringConversionText.string 24 -XIMStringConversionText 32 -XPixmapFormatValues.depth 0 -XPixmapFormatValues.bits_per_pixel 4 -XPixmapFormatValues.scanline_pad 8 -XPixmapFormatValues 12 -XExposeEvent.type 0 -XExposeEvent.serial 8 -XExposeEvent.send_event 16 -XExposeEvent.display 24 -XExposeEvent.window 32 -XExposeEvent.x 40 -XExposeEvent.y 44 -XExposeEvent.width 48 -XExposeEvent.height 52 -XExposeEvent.count 56 -XExposeEvent 64 -XIMStyles.count_styles 0 -XIMStyles.supported_styles 8 -XIMStyles 16 -XSizeHints.flags 0 -XSizeHints.x 8 -XSizeHints.y 12 -XSizeHints.width 16 -XSizeHints.height 20 -XSizeHints.min_width 24 -XSizeHints.min_height 28 -XSizeHints.max_width 32 -XSizeHints.max_height 36 -XSizeHints.width_inc 40 -XSizeHints.height_inc 44 -XSizeHints.min_aspect.x 48 -XSizeHints.min_aspect.y 52 -XSizeHints.max_aspect.x 56 -XSizeHints.max_aspect.y 60 -XSizeHints.base_width 64 -XSizeHints.base_height 68 -XSizeHints.win_gravity 72 -XSizeHints 80 -XMappingEvent.type 0 -XMappingEvent.serial 8 -XMappingEvent.send_event 16 -XMappingEvent.display 24 -XMappingEvent.window 32 -XMappingEvent.request 40 -XMappingEvent.first_keycode 44 -XMappingEvent.count 48 -XMappingEvent 56 -XClassHint.res_name 0 -XClassHint.res_class 8 -XClassHint 16 -XmbTextItem.chars 0 -XmbTextItem.nchars 8 -XmbTextItem.delta 12 -XmbTextItem.font_set 16 -XmbTextItem 24 -XWindowAttributes.x 0 -XWindowAttributes.y 4 -XWindowAttributes.width 8 -XWindowAttributes.height 12 -XWindowAttributes.border_width 16 -XWindowAttributes.depth 20 -XWindowAttributes.visual 24 -XWindowAttributes.root 32 -XWindowAttributes.class 40 -XWindowAttributes.bit_gravity 44 -XWindowAttributes.win_gravity 48 -XWindowAttributes.backing_store 52 -XWindowAttributes.backing_planes 56 -XWindowAttributes.backing_pixel 64 -XWindowAttributes.save_under 72 -XWindowAttributes.colormap 80 -XWindowAttributes.map_installed 88 -XWindowAttributes.map_state 92 -XWindowAttributes.all_event_masks 96 -XWindowAttributes.your_event_mask 104 -XWindowAttributes.do_not_propagate_mask 112 -XWindowAttributes.override_redirect 120 -XWindowAttributes.screen 128 -XWindowAttributes 136 -XSetWindowAttributes.background_pixmap 0 -XSetWindowAttributes.background_pixel 8 -XSetWindowAttributes.border_pixmap 16 -XSetWindowAttributes.border_pixel 24 -XSetWindowAttributes.bit_gravity 32 -XSetWindowAttributes.win_gravity 36 -XSetWindowAttributes.backing_store 40 -XSetWindowAttributes.backing_planes 48 -XSetWindowAttributes.backing_pixel 56 -XSetWindowAttributes.save_under 64 -XSetWindowAttributes.event_mask 72 -XSetWindowAttributes.do_not_propagate_mask 80 -XSetWindowAttributes.override_redirect 88 -XSetWindowAttributes.colormap 96 -XSetWindowAttributes.cursor 104 -XSetWindowAttributes 112 -XOMOrientation.num_orientation 0 -XOMOrientation.orientation 8 -XOMOrientation 16 -Visual.ext_data 0 -Visual.visualid 8 -Visual.class 16 -Visual.red_mask 24 -Visual.green_mask 32 -Visual.blue_mask 40 -Visual.bits_per_rgb 48 -Visual.map_entries 52 -Visual 56 -XGravityEvent.type 0 -XGravityEvent.serial 8 -XGravityEvent.send_event 16 -XGravityEvent.display 24 -XGravityEvent.event 32 -XGravityEvent.window 40 -XGravityEvent.x 48 -XGravityEvent.y 52 -XGravityEvent 56 -XReparentEvent.type 0 -XReparentEvent.serial 8 -XReparentEvent.send_event 16 -XReparentEvent.display 24 -XReparentEvent.event 32 -XReparentEvent.window 40 -XReparentEvent.parent 48 -XReparentEvent.x 56 -XReparentEvent.y 60 -XReparentEvent.override_redirect 64 -XReparentEvent 72 -XCirculateRequestEvent.type 0 -XCirculateRequestEvent.serial 8 -XCirculateRequestEvent.send_event 16 -XCirculateRequestEvent.display 24 -XCirculateRequestEvent.parent 32 -XCirculateRequestEvent.window 40 -XCirculateRequestEvent.place 48 -XCirculateRequestEvent 56 -XKeyEvent.type 0 -XKeyEvent.serial 8 -XKeyEvent.send_event 16 -XKeyEvent.display 24 -XKeyEvent.window 32 -XKeyEvent.root 40 -XKeyEvent.subwindow 48 -XKeyEvent.time 56 -XKeyEvent.x 64 -XKeyEvent.y 68 -XKeyEvent.x_root 72 -XKeyEvent.y_root 76 -XKeyEvent.state 80 -XKeyEvent.keycode 84 -XKeyEvent.same_screen 88 -XKeyEvent 96 -XCharStruct.lbearing 0 -XCharStruct.rbearing 2 -XCharStruct.width 4 -XCharStruct.ascent 6 -XCharStruct.descent 8 -XCharStruct.attributes 10 -XCharStruct 12 -XModifierKeymap.max_keypermod 0 -XModifierKeymap.modifiermap 8 -XModifierKeymap 16 -XTextItem.chars 0 -XTextItem.nchars 8 -XTextItem.delta 12 -XTextItem.font 16 -XTextItem 24 -XdbeSwapInfo.swap_window 0 -XdbeSwapInfo.swap_action 8 -XdbeSwapInfo 16 -XImage.width 0 -XImage.height 4 -XImage.xoffset 8 -XImage.format 12 -XImage.data 16 -XImage.byte_order 24 -XImage.bitmap_unit 28 -XImage.bitmap_bit_order 32 -XImage.bitmap_pad 36 -XImage.depth 40 -XImage.bytes_per_line 44 -XImage.bits_per_pixel 48 -XImage.red_mask 56 -XImage.green_mask 64 -XImage.blue_mask 72 -XImage.obdata 80 -XImage.f.create_image 88 -XImage.f.destroy_image 96 -XImage.f.get_pixel 104 -XImage.f.put_pixel 112 -XImage.f.sub_image 120 -XImage.f.add_pixel 128 -XImage 136 -XChar2b.byte1 0 -XChar2b.byte2 1 -XChar2b 2 -XwcTextItem.chars 0 -XwcTextItem.nchars 8 -XwcTextItem.delta 12 -XwcTextItem.font_set 16 -XwcTextItem 24 -XUnmapEvent.type 0 -XUnmapEvent.serial 8 -XUnmapEvent.send_event 16 -XUnmapEvent.display 24 -XUnmapEvent.event 32 -XUnmapEvent.window 40 -XUnmapEvent.from_configure 48 -XUnmapEvent 56 -awtImageData.Depth 0 -awtImageData.wsImageFormat 4 -awtImageData.clrdata 16 -awtImageData.convert 48 -awtImageData 560 -XGCValues.function 0 -XGCValues.plane_mask 8 -XGCValues.foreground 16 -XGCValues.background 24 -XGCValues.line_width 32 -XGCValues.line_style 36 -XGCValues.cap_style 40 -XGCValues.join_style 44 -XGCValues.fill_style 48 -XGCValues.fill_rule 52 -XGCValues.arc_mode 56 -XGCValues.tile 64 -XGCValues.stipple 72 -XGCValues.ts_x_origin 80 -XGCValues.ts_y_origin 84 -XGCValues.font 88 -XGCValues.subwindow_mode 96 -XGCValues.graphics_exposures 100 -XGCValues.clip_x_origin 104 -XGCValues.clip_y_origin 108 -XGCValues.clip_mask 112 -XGCValues.dash_offset 120 -XGCValues.dashes 124 -XGCValues 128 -XFocusChangeEvent.type 0 -XFocusChangeEvent.serial 8 -XFocusChangeEvent.send_event 16 -XFocusChangeEvent.display 24 -XFocusChangeEvent.window 32 -XFocusChangeEvent.mode 40 -XFocusChangeEvent.detail 44 -XFocusChangeEvent 48 -XMapEvent.type 0 -XMapEvent.serial 8 -XMapEvent.send_event 16 -XMapEvent.display 24 -XMapEvent.event 32 -XMapEvent.window 40 -XMapEvent.override_redirect 48 -XMapEvent 56 -XIMHotKeyTriggers.num_hot_key 0 -XIMHotKeyTriggers.key 8 -XIMHotKeyTriggers 16 -XKeyboardState.key_click_percent 0 -XKeyboardState.bell_percent 4 -XKeyboardState.bell_pitch 8 -XKeyboardState.bell_duration 12 -XKeyboardState.led_mask 16 -XKeyboardState.global_auto_repeat 24 -XKeyboardState.auto_repeats 28 -XKeyboardState 64 -XMotionEvent.type 0 -XMotionEvent.serial 8 -XMotionEvent.send_event 16 -XMotionEvent.display 24 -XMotionEvent.window 32 -XMotionEvent.root 40 -XMotionEvent.subwindow 48 -XMotionEvent.time 56 -XMotionEvent.x 64 -XMotionEvent.y 68 -XMotionEvent.x_root 72 -XMotionEvent.y_root 76 -XMotionEvent.state 80 -XMotionEvent.is_hint 84 -XMotionEvent.same_screen 88 -XMotionEvent 96 -XIMPreeditStateNotifyCallbackStruct.state 0 -XIMPreeditStateNotifyCallbackStruct 8 -XAnyEvent.type 0 -XAnyEvent.serial 8 -XAnyEvent.send_event 16 -XAnyEvent.display 24 -XAnyEvent.window 32 -XAnyEvent 40 -XIMCallback.client_data 0 -XIMCallback.callback 8 -XIMCallback 16 -XVisualInfo.visual 0 -XVisualInfo.visualid 8 -XVisualInfo.screen 16 -XVisualInfo.depth 20 -XVisualInfo.class 24 -XVisualInfo.red_mask 32 -XVisualInfo.green_mask 40 -XVisualInfo.blue_mask 48 -XVisualInfo.colormap_size 56 -XVisualInfo.bits_per_rgb 60 -XVisualInfo 64 -XCreateWindowEvent.type 0 -XCreateWindowEvent.serial 8 -XCreateWindowEvent.send_event 16 -XCreateWindowEvent.display 24 -XCreateWindowEvent.parent 32 -XCreateWindowEvent.window 40 -XCreateWindowEvent.x 48 -XCreateWindowEvent.y 52 -XCreateWindowEvent.width 56 -XCreateWindowEvent.height 60 -XCreateWindowEvent.border_width 64 -XCreateWindowEvent.override_redirect 68 -XCreateWindowEvent 72 -XIMValuesList.count_values 0 -XIMValuesList.supported_values 8 -XIMValuesList 16 -XKeymapEvent.type 0 -XKeymapEvent.serial 8 -XKeymapEvent.send_event 16 -XKeymapEvent.display 24 -XKeymapEvent.window 32 -XKeymapEvent.key_vector 40 -XKeymapEvent 72 -XButtonEvent.type 0 -XButtonEvent.serial 8 -XButtonEvent.send_event 16 -XButtonEvent.display 24 -XButtonEvent.window 32 -XButtonEvent.root 40 -XButtonEvent.subwindow 48 -XButtonEvent.time 56 -XButtonEvent.x 64 -XButtonEvent.y 68 -XButtonEvent.x_root 72 -XButtonEvent.y_root 76 -XButtonEvent.state 80 -XButtonEvent.button 84 -XButtonEvent.same_screen 88 -XButtonEvent 96 -XWMHints.flags 0 -XWMHints.initial_state 12 -XWMHints.icon_pixmap 16 -XWMHints.icon_window 24 -XWMHints.icon_x 32 -XWMHints.icon_y 36 -XWMHints.icon_mask 40 -XWMHints.input 8 -XWMHints.window_group 48 -XWMHints 56 -ScreenFormat.ext_data 0 -ScreenFormat.depth 8 -ScreenFormat.bits_per_pixel 12 -ScreenFormat.scanline_pad 16 -ScreenFormat 24 -XCrossingEvent.type 0 -XCrossingEvent.serial 8 -XCrossingEvent.send_event 16 -XCrossingEvent.display 24 -XCrossingEvent.window 32 -XCrossingEvent.root 40 -XCrossingEvent.subwindow 48 -XCrossingEvent.time 56 -XCrossingEvent.x 64 -XCrossingEvent.y 68 -XCrossingEvent.x_root 72 -XCrossingEvent.y_root 76 -XCrossingEvent.mode 80 -XCrossingEvent.detail 84 -XCrossingEvent.same_screen 88 -XCrossingEvent.focus 92 -XCrossingEvent.state 96 -XCrossingEvent 104 -XConfigureRequestEvent.type 0 -XConfigureRequestEvent.serial 8 -XConfigureRequestEvent.send_event 16 -XConfigureRequestEvent.display 24 -XConfigureRequestEvent.parent 32 -XConfigureRequestEvent.window 40 -XConfigureRequestEvent.x 48 -XConfigureRequestEvent.y 52 -XConfigureRequestEvent.width 56 -XConfigureRequestEvent.height 60 -XConfigureRequestEvent.border_width 64 -XConfigureRequestEvent.above 72 -XConfigureRequestEvent.detail 80 -XConfigureRequestEvent.value_mask 88 -XConfigureRequestEvent 96 -XSelectionRequestEvent.type 0 -XSelectionRequestEvent.serial 8 -XSelectionRequestEvent.send_event 16 -XSelectionRequestEvent.display 24 -XSelectionRequestEvent.owner 32 -XSelectionRequestEvent.requestor 40 -XSelectionRequestEvent.selection 48 -XSelectionRequestEvent.target 56 -XSelectionRequestEvent.property 64 -XSelectionRequestEvent.time 72 -XSelectionRequestEvent 80 -XFontSetExtents.max_ink_extent 0 -XFontSetExtents.max_logical_extent 8 -XFontSetExtents 16 -XExtCodes.extension 0 -XExtCodes.major_opcode 4 -XExtCodes.first_event 8 -XExtCodes.first_error 12 -XExtCodes 16 -XHostAddress.family 0 -XHostAddress.length 4 -XHostAddress.address 8 -XHostAddress 16 -ColorData.awt_Colors 0 -ColorData.awt_numICMcolors 8 -ColorData.awt_icmLUT 16 -ColorData.awt_icmLUT2Colors 24 -ColorData.img_grays 32 -ColorData.img_clr_tbl 40 -ColorData.img_oda_red 48 -ColorData.img_oda_green 56 -ColorData.img_oda_blue 64 -ColorData.pGrayInverseLutData 72 -ColorData.screendata 80 -ColorData 88 -XColormapEvent.type 0 -XColormapEvent.serial 8 -XColormapEvent.send_event 16 -XColormapEvent.display 24 -XColormapEvent.window 32 -XColormapEvent.colormap 40 -XColormapEvent.new 48 -XColormapEvent.state 52 -XColormapEvent 56 -Depth.depth 0 -Depth.nvisuals 4 -Depth.visuals 8 -Depth 16 -XEvent.type 0 -XEvent.xany 0 -XEvent.xkey 0 -XEvent.xbutton 0 -XEvent.xmotion 0 -XEvent.xcrossing 0 -XEvent.xfocus 0 -XEvent.xexpose 0 -XEvent.xgraphicsexpose 0 -XEvent.xnoexpose 0 -XEvent.xvisibility 0 -XEvent.xcreatewindow 0 -XEvent.xdestroywindow 0 -XEvent.xunmap 0 -XEvent.xmap 0 -XEvent.xmaprequest 0 -XEvent.xreparent 0 -XEvent.xconfigure 0 -XEvent.xgravity 0 -XEvent.xresizerequest 0 -XEvent.xconfigurerequest 0 -XEvent.xcirculate 0 -XEvent.xcirculaterequest 0 -XEvent.xproperty 0 -XEvent.xselectionclear 0 -XEvent.xselectionrequest 0 -XEvent.xselection 0 -XEvent.xcolormap 0 -XEvent.xclient 0 -XEvent.xmapping 0 -XEvent.xerror 0 -XEvent.xkeymap 0 -XEvent.pad 0 -XEvent 192 -XDestroyWindowEvent.type 0 -XDestroyWindowEvent.serial 8 -XDestroyWindowEvent.send_event 16 -XDestroyWindowEvent.display 24 -XDestroyWindowEvent.event 32 -XDestroyWindowEvent.window 40 -XDestroyWindowEvent 48 -XComposeStatus.compose_ptr 0 -XComposeStatus.chars_matched 8 -XComposeStatus 16 -AwtGraphicsConfigData.awt_depth 0 -AwtGraphicsConfigData.awt_cmap 8 -AwtGraphicsConfigData.awt_visInfo 16 -AwtGraphicsConfigData.awt_num_colors 80 -AwtGraphicsConfigData.awtImage 88 -AwtGraphicsConfigData.AwtColorMatch 96 -AwtGraphicsConfigData.monoImage 104 -AwtGraphicsConfigData.monoPixmap 112 -AwtGraphicsConfigData.monoPixmapWidth 120 -AwtGraphicsConfigData.monoPixmapHeight 124 -AwtGraphicsConfigData.monoPixmapGC 128 -AwtGraphicsConfigData.pixelStride 136 -AwtGraphicsConfigData.color_data 144 -AwtGraphicsConfigData.glxInfo 152 -AwtGraphicsConfigData.isTranslucencySupported 160 -AwtGraphicsConfigData 168 -XIMText.length 0 -XIMText.feedback 8 -XIMText.encoding_is_wchar 16 -XIMText.string 24 -XIMText 32 diff --git a/package/openjdk/Makefile b/package/openjdk/Makefile index ad8f29778..1f8264f67 100644 --- a/package/openjdk/Makefile +++ b/package/openjdk/Makefile @@ -154,10 +154,6 @@ pre-configure: --with-gcj=$(STAGING_JAVA_HOST_DIR)/usr/bin/gcj \ --with-ecj-jar=$(STAGING_JAVA_HOST_DIR)/usr/share/java/ecj.jar \ --without-rhino ;\ - mkdir -p $(WRKBUILD)/generated/sun/awt/X11/generator/ ; \ - mkdir -p $(WRKBUILD)/openjdk.build/gensrc/sun/awt/X11/generator/ ; \ - cp $(TOPDIR)/jtools/openjdk/files/sizes.* $(WRKBUILD)/generated/sun/awt/X11/generator/; \ - cp $(TOPDIR)/jtools/openjdk/files/sizes.* $(WRKBUILD)/openjdk.build/gensrc/sun/awt/X11/generator/; \ env ${OPENJDK_NATIVE_ENV} $(MAKE) icedtea-ecj # fixup symlinks to bootstrap jdk ln -sf $(BOOTSTRAPJDK)/bin/java $(WRKBUILD)/openjdk.build-ecj/j2sdk-image/bin/java diff --git a/package/openjdk/patches/disable-sizers.patch b/package/openjdk/patches/disable-sizers.patch deleted file mode 100644 index 46325008c..000000000 --- a/package/openjdk/patches/disable-sizers.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- w-openjdk-6.orig/openjdk-6/jdk/make/sun/xawt/Makefile 2011-02-28 17:06:12.000000000 +0100 -+++ w-openjdk-6/openjdk-6/jdk/make/sun/xawt/Makefile 2011-04-13 12:00:18.618922673 +0200 -@@ -237,7 +237,8 @@ - $(BOOT_JAVA_CMD) -cp $(WRAPPER_GENERATOR_TEMPDIR) WrapperGenerator \ - $(SIZER_DIR) $(XLIBTYPES) "sizer" $(subst .,,$(suffix $(basename $@))) - --$(SIZES): $(SIZERS) -+$(SIZES): -+ $(prep-target) - @if [ "$(DOHACK)$@" = "true$(PREDEFINED_SIZES)" ]; then \ - $(ECHO) COPYING $(PREDEFINED_SIZES_TMPL) into $@; \ - $(CP) $(PREDEFINED_SIZES_TMPL) $@; \ diff --git a/package/openjdk/patches/qemu-sizer.patch b/package/openjdk/patches/qemu-sizer.patch new file mode 100644 index 000000000..b0049e852 --- /dev/null +++ b/package/openjdk/patches/qemu-sizer.patch @@ -0,0 +1,22 @@ +--- w-openjdk-6.orig/openjdk-6/jdk/make/sun/xawt/Makefile 2011-02-28 17:06:12.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/make/sun/xawt/Makefile 2011-08-20 18:45:28.499240773 +0200 +@@ -225,7 +225,7 @@ + + $(SIZERS): $(SIZERS_C) + $(prep-target) +- $(CC) $(CFLAGS_$(subst .,,$(suffix $@))) $(CPPFLAGS) -o $@ $(SIZER)$(suffix $@).c ++ $(CC) -static $(CFLAGS_$(subst .,,$(suffix $@))) $(CPPFLAGS) -o $@ $(SIZER)$(suffix $@).c + + $(WRAPPER_GENERATOR_CLASS): $(WRAPPER_GENERATOR_JAVA) + $(prep-target) +@@ -243,8 +243,8 @@ + $(CP) $(PREDEFINED_SIZES_TMPL) $@; \ + $(CHMOD) +w $@;\ + else \ +- $(ECHO) GENERATING $@; \ +- $(WRAPPER_GENERATOR_DIR)/sizer$(suffix $@) > $@; \ ++ $(ECHO) GENERATING $@ via $(QEMU) $(WRAPPER_GENERATOR_DIR)/sizer..; \ ++ $(QEMU) $(WRAPPER_GENERATOR_DIR)/sizer$(suffix $@) > $@; \ + fi + @if [ "$(DOCOMPARE)$(suffix $@)" = "true.64" ]; then \ + $(ECHO) COMPARING $@ and $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \ -- cgit v1.2.3 From dcbfc98334c615ffd2dd05315a1aef936f65ad46 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 21 Aug 2011 11:49:58 +0200 Subject: cleanup duplicate environment variables, cosmetic changes --- package/openjdk/Makefile | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/package/openjdk/Makefile b/package/openjdk/Makefile index 1f8264f67..0cdea7b0d 100644 --- a/package/openjdk/Makefile +++ b/package/openjdk/Makefile @@ -24,7 +24,6 @@ PKG_SITES:= http://download.java.net/openjdk/jdk6/promoted/b22/ \ http://icedtea.classpath.org/download/drops/ \ http://icedtea.classpath.org/download/source/ -#PKG_CFLINE_OPENJDK:= depends on ADK_TARGET_LIB_GLIBC || ADK_TARGET_LIB_EGLIBC && !ADK_TARGET_SYSTEM_LEMOTE_YEELONG PKG_HOST_DEPENDS:= !darwin !cygwin !openbsd !netbsd !freebsd PKG_ARCH_DEPENDS:= arm mips x86 x86_64 PKG_SYSTEM_DEPENDS:= !lemote-yeelong !linksys-ag241 !fon-fon2100 @@ -55,7 +54,6 @@ PKGCD_ZERO:= zero-assembly backend PKGCD_SHARK:= Shark JIT backend (needs eglibc/glibc) PKGCB_SHARK:= llvm PKGCD_CACAO:= Cacao JIT backend -PKGCD_JAMVM:= JamVM backend include $(TOPDIR)/mk/package.mk @@ -75,9 +73,6 @@ endif ifeq ($(ADK_PACKAGE_OPENJDK_CACAO),y) CONFIGURE_BACKEND:= --enable-cacao endif -ifeq ($(ADK_PACKAGE_OPENJDK_JAMVM),y) -CONFIGURE_BACKEND:= --enable-jamvm -endif CONFIGURE_ARGS+= $(CONFIGURE_BACKEND) CONFIGURE_ARGS+= --disable-docs \ @@ -101,10 +96,10 @@ CONFIGURE_ENV+= PATH=$(STAGING_JAVA_HOST_DIR)/usr/bin:$${PATH}:${STAGING_TARGET MAKE_ENV+= ALT_COMPILER_PATH=$(STAGING_HOST_DIR)/$(REAL_GNU_TARGET_NAME) \ ADK_ECJ=$(STAGING_JAVA_HOST_DIR)/usr/bin/ecj \ PATH=$(STAGING_JAVA_HOST_DIR)/usr/bin:$${PATH}:${STAGING_TARGET_DIR}/usr/bin \ - GCC_HONOUR_COPTS=s \ + GCC_HONOUR_COPTS=s CROSS_COMPILE_ARCH=$(ARCH) \ TARGET_ALIAS=$(GNU_TARGET_NAME) BUILD_ALIAS=$(GNU_HOST_NAME) HOST_ALIAS=$(GNU_TARGET_NAME) -OPENJDK_NATIVE_ENV+= ALT_COMPILER_PATH=$(STAGING_HOST_DIR)/$(REAL_GNU_TARGET_NAME) \ +#OPENJDK_NATIVE_ENV+= ALT_COMPILER_PATH=$(STAGING_HOST_DIR)/$(REAL_GNU_TARGET_NAME) \ ADK_ECJ=$(STAGING_JAVA_HOST_DIR)/usr/bin/ecj \ PATH=$(STAGING_JAVA_HOST_DIR)/usr/bin:$${PATH}:${STAGING_TARGET_DIR}/usr/bin \ GCC_HONOUR_COPTS=s CROSS_COMPILE_ARCH=$(ARCH) \ @@ -128,7 +123,7 @@ do-extract: pre-configure: cd ${WRKBUILD}; rm -rf config.{cache,status}; \ - export $(MAKE_ENV) ${OPENJDK_NATIVE_ENV} ; ./configure \ + export $(MAKE_ENV); ./configure \ ${CONFIGURE_TRIPLE} \ $(CONFIGURE_BACKEND) \ --prefix=/usr \ @@ -154,7 +149,7 @@ pre-configure: --with-gcj=$(STAGING_JAVA_HOST_DIR)/usr/bin/gcj \ --with-ecj-jar=$(STAGING_JAVA_HOST_DIR)/usr/share/java/ecj.jar \ --without-rhino ;\ - env ${OPENJDK_NATIVE_ENV} $(MAKE) icedtea-ecj + env ${MAKE_ENV} $(MAKE) icedtea-ecj # fixup symlinks to bootstrap jdk ln -sf $(BOOTSTRAPJDK)/bin/java $(WRKBUILD)/openjdk.build-ecj/j2sdk-image/bin/java ln -sf $(BOOTSTRAPJDK)/bin/javac $(WRKBUILD)/openjdk.build-ecj/j2sdk-image/bin/javac -- cgit v1.2.3 From 23c5e02a837eb148c87cf85309bdba6039022e2a Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 22 Aug 2011 04:55:35 +0200 Subject: unify configure arguments --- package/openjdk/Makefile | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/package/openjdk/Makefile b/package/openjdk/Makefile index 0cdea7b0d..58f54c3ea 100644 --- a/package/openjdk/Makefile +++ b/package/openjdk/Makefile @@ -74,9 +74,7 @@ ifeq ($(ADK_PACKAGE_OPENJDK_CACAO),y) CONFIGURE_BACKEND:= --enable-cacao endif -CONFIGURE_ARGS+= $(CONFIGURE_BACKEND) -CONFIGURE_ARGS+= --disable-docs \ - --disable-bootstrap \ +CONFIGURE_COMMON:= --disable-docs \ --enable-openjdk-cross-compilation \ --with-openjdk-src-dir=$(WRKDIST)/$(PKG_NAME)-$(PKG_VERSION) \ --with-xalan2-jar=${WRKDIST}/${XALAN_NAME}_${XALAN_VERSION}/xalan.jar \ @@ -92,18 +90,16 @@ CONFIGURE_ARGS+= --disable-docs \ --with-gcj=$(STAGING_JAVA_HOST_DIR)/usr/bin/gcj \ --without-rhino +CONFIGURE_ARGS+= $(CONFIGURE_BACKEND) +CONFIGURE_ARGS+= $(CONFIGURE_COMMON) +CONFIGURE_ARGS+= --disable-bootstrap + CONFIGURE_ENV+= PATH=$(STAGING_JAVA_HOST_DIR)/usr/bin:$${PATH}:${STAGING_TARGET_DIR}/usr/bin MAKE_ENV+= ALT_COMPILER_PATH=$(STAGING_HOST_DIR)/$(REAL_GNU_TARGET_NAME) \ ADK_ECJ=$(STAGING_JAVA_HOST_DIR)/usr/bin/ecj \ PATH=$(STAGING_JAVA_HOST_DIR)/usr/bin:$${PATH}:${STAGING_TARGET_DIR}/usr/bin \ GCC_HONOUR_COPTS=s CROSS_COMPILE_ARCH=$(ARCH) \ TARGET_ALIAS=$(GNU_TARGET_NAME) BUILD_ALIAS=$(GNU_HOST_NAME) HOST_ALIAS=$(GNU_TARGET_NAME) - -#OPENJDK_NATIVE_ENV+= ALT_COMPILER_PATH=$(STAGING_HOST_DIR)/$(REAL_GNU_TARGET_NAME) \ - ADK_ECJ=$(STAGING_JAVA_HOST_DIR)/usr/bin/ecj \ - PATH=$(STAGING_JAVA_HOST_DIR)/usr/bin:$${PATH}:${STAGING_TARGET_DIR}/usr/bin \ - GCC_HONOUR_COPTS=s CROSS_COMPILE_ARCH=$(ARCH) \ - TARGET_ALIAS=$(GNU_TARGET_NAME) BUILD_ALIAS=$(GNU_HOST_NAME) HOST_ALIAS=$(GNU_TARGET_NAME) ALL_TARGET:= icedtea # add include path for Xrender.h from staging directory @@ -134,21 +130,7 @@ pre-configure: --localstatedir=/var \ --sysconfdir=/etc \ --enable-bootstrap \ - --enable-openjdk-cross-compilation \ - --with-openjdk-src-dir=$(WRKDIST)/$(PKG_NAME)-$(PKG_VERSION) \ - --with-xalan2-jar=${WRKDIST}/${XALAN_NAME}_${XALAN_VERSION}/xalan.jar \ - --with-xalan2-serializer-jar=${WRKDIST}/${XALAN_NAME}_${XALAN_VERSION}/serializer.jar \ - --with-xerces2-jar=${WRKDIST}/${XALAN_NAME}_${XALAN_VERSION}/xercesImpl.jar \ - --with-jdk-home=$(BOOTSTRAPJDK) \ - --with-java=$(BOOTSTRAPJDK)/bin/java \ - --with-javac=$(BOOTSTRAPJDK)/bin/javac \ - --with-javah=$(BOOTSTRAPJDK)/bin/javah \ - --with-jar=$(BOOTSTRAPJDK)/bin/jar \ - --with-rmic=$(BOOTSTRAPJDK)/bin/rmic \ - --with-native2ascii=$(BOOTSTRAPJDK)/bin/native2ascii \ - --with-gcj=$(STAGING_JAVA_HOST_DIR)/usr/bin/gcj \ - --with-ecj-jar=$(STAGING_JAVA_HOST_DIR)/usr/share/java/ecj.jar \ - --without-rhino ;\ + $(CONFIGURE_COMMON) ;\ env ${MAKE_ENV} $(MAKE) icedtea-ecj # fixup symlinks to bootstrap jdk ln -sf $(BOOTSTRAPJDK)/bin/java $(WRKBUILD)/openjdk.build-ecj/j2sdk-image/bin/java -- cgit v1.2.3 From f41e4877defd5be85457121c5fd9b923a943d8ed Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 22 Aug 2011 06:26:22 +0200 Subject: fix the help for usb boot, root= is required for now --- target/mips/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/mips/Makefile b/target/mips/Makefile index 7fc44a976..5d606046f 100644 --- a/target/mips/Makefile +++ b/target/mips/Makefile @@ -135,7 +135,8 @@ imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) ifeq ($(ADK_TARGET_SYSTEM_LEMOTE_YEELONG),y) @echo "Startup the netbook and type del to enter PMON:" @echo "PMON> load /dev/fs/ext2@usb0/boot/kernel" - @echo "PMON> g console=tty no_auto_cmd" + @echo "PMON> g root=/dev/sdc1" + @echo "The root parameter have to be changed." endif endif ifeq ($(ADK_TARGET_FS),cf) -- cgit v1.2.3 From a2d86599cb6ba6fb5ca5c8cea98557a4e426df14 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 22 Aug 2011 06:30:17 +0200 Subject: uClibc nowadays works for pagesize != 4kb, so lemote is supported --- target/config/Config.in | 1 - 1 file changed, 1 deletion(-) diff --git a/target/config/Config.in b/target/config/Config.in index 5e89eb8f6..38dca4b19 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -334,7 +334,6 @@ config ADK_TARGET_LIB_UCLIBC boolean select ADK_uclibc depends on \ - !ADK_TARGET_SYSTEM_LEMOTE_YEELONG && \ !ADK_LINUX_SPARC64 && \ !ADK_LINUX_PPC64 && \ !ADK_LINUX_NATIVE -- cgit v1.2.3 From ea1aef3da3e68a062f28718a3e697b3148eef1fe Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 22 Aug 2011 06:31:02 +0200 Subject: allow FETCH_STYLE=manual to succeed. simplify fetch loop. --- mk/buildhlp.mk | 18 +++++++++++++++--- mk/fetch.mk | 7 ------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/mk/buildhlp.mk b/mk/buildhlp.mk index 3c79fc1e8..19b761f46 100644 --- a/mk/buildhlp.mk +++ b/mk/buildhlp.mk @@ -49,15 +49,27 @@ ifeq (${_CHECKSUM_COOKIE},) endif ifeq ($(EXTRACT_OVERRIDE),1) ${MAKE} do-extract -else +else ${EXTRACT_CMD} endif @${MAKE} post-extract $(MAKE_TRACE) touch $@ __use_generic_patch_target:=42 -else ifeq ($(strip ${_IN_PACKAGE}),1) -$(warning This package does not use the generic extraction and patch target; it's most likely to fail.) +else +include ${TOPDIR}/mk/fetch.mk +${WRKDIST}/.extract_done: ${_CHECKSUM_COOKIE} + $(MAKE) fetch +ifeq (${_CHECKSUM_COOKIE},) + rm -rf ${WRKDIST} ${WRKSRC} ${WRKBUILD} +endif +ifeq ($(EXTRACT_OVERRIDE),1) + ${MAKE} do-extract +else + ${EXTRACT_CMD} +endif + @${MAKE} post-extract $(MAKE_TRACE) + touch $@ endif ifeq ($(strip ${__use_generic_patch_target}),42) diff --git a/mk/fetch.mk b/mk/fetch.mk index 5c3edf918..a2590d467 100644 --- a/mk/fetch.mk +++ b/mk/fetch.mk @@ -59,14 +59,7 @@ endif define FETCH_template $(1): @fullname='$(1)'; \ - subname=$$$${fullname##$${DISTDIR}/}; \ filename=$$$${fullname##*/}; \ - i='$${LOCAL_DISTDIR}'; \ - if [[ -n $$$$i && -e $$$$i/$$$$subname ]]; then \ - cd "$$$$i"; \ - echo pax -rw "$$$$subname" '$${DISTDIR}/'; \ - exec pax -rw "$$$$subname" '$${DISTDIR}/'; \ - fi; \ mkdir -p "$$$${fullname%%/$$$$filename}"; \ cd "$$$${fullname%%/$$$$filename}"; \ for site in $${PKG_SITES} $${MASTER_SITE_BACKUP}; do \ -- cgit v1.2.3 From 2a8f18f0aa29136e8d5dce664de031336e531360 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 22 Aug 2011 08:00:09 +0200 Subject: simplify patch, remove unused cruft --- package/openjdk/Makefile | 3 +- package/openjdk/patches/icedtea6-Makefile_in.patch | 46 ---------------------- 2 files changed, 1 insertion(+), 48 deletions(-) diff --git a/package/openjdk/Makefile b/package/openjdk/Makefile index 58f54c3ea..347f3b01d 100644 --- a/package/openjdk/Makefile +++ b/package/openjdk/Makefile @@ -98,8 +98,7 @@ CONFIGURE_ENV+= PATH=$(STAGING_JAVA_HOST_DIR)/usr/bin:$${PATH}:${STAGING_TARGET MAKE_ENV+= ALT_COMPILER_PATH=$(STAGING_HOST_DIR)/$(REAL_GNU_TARGET_NAME) \ ADK_ECJ=$(STAGING_JAVA_HOST_DIR)/usr/bin/ecj \ PATH=$(STAGING_JAVA_HOST_DIR)/usr/bin:$${PATH}:${STAGING_TARGET_DIR}/usr/bin \ - GCC_HONOUR_COPTS=s CROSS_COMPILE_ARCH=$(ARCH) \ - TARGET_ALIAS=$(GNU_TARGET_NAME) BUILD_ALIAS=$(GNU_HOST_NAME) HOST_ALIAS=$(GNU_TARGET_NAME) + GCC_HONOUR_COPTS=s CROSS_COMPILE_ARCH=$(ARCH) ALL_TARGET:= icedtea # add include path for Xrender.h from staging directory diff --git a/package/openjdk/patches/icedtea6-Makefile_in.patch b/package/openjdk/patches/icedtea6-Makefile_in.patch index 193e008aa..7febd6cac 100644 --- a/package/openjdk/patches/icedtea6-Makefile_in.patch +++ b/package/openjdk/patches/icedtea6-Makefile_in.patch @@ -1,41 +1,5 @@ --- w-openjdk-6-1.orig/icedtea6-1.10/Makefile.in 2011-03-02 20:48:45.000000000 +0100 +++ w-openjdk-6-1/icedtea6-1.10/Makefile.in 2011-04-02 23:33:17.000000000 +0200 -@@ -328,7 +328,7 @@ - am__untar = @am__untar@ - bindir = @bindir@ - build = @build@ --build_alias = @build_alias@ -+build_alias = ${BUILD_ALIAS} - build_cpu = @build_cpu@ - build_os = @build_os@ - build_vendor = @build_vendor@ -@@ -339,7 +339,7 @@ - dvidir = @dvidir@ - exec_prefix = @exec_prefix@ - host = @host@ --host_alias = @host_alias@ -+host_alias = ${HOST_ALIAS} - host_cpu = @host_cpu@ - host_os = @host_os@ - host_vendor = @host_vendor@ -@@ -362,7 +362,7 @@ - sharedstatedir = @sharedstatedir@ - srcdir = @srcdir@ - sysconfdir = @sysconfdir@ --target_alias = @target_alias@ -+target_alias = ${TARGET_ALIAS} - top_build_prefix = @top_build_prefix@ - top_builddir = @top_builddir@ - top_srcdir = @top_srcdir@ -@@ -1329,7 +1329,7 @@ stamps/extract-openjdk.stamp: stamps/dow - @OPENJDK_SRC_DIR_FOUND_TRUE@ cp -pPR $(OPENJDK_SRC_DIR_LINK) $(OPENJDK_SRC_DIR) openjdk ; \ - @OPENJDK_SRC_DIR_FOUND_TRUE@ fi - @OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_TRUE@ if ! test -d openjdk ; then \ --@OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_TRUE@ cp -pPRl openjdk.hg openjdk ; \ -+@OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_TRUE@ cp -pPR openjdk.hg openjdk ; \ - @OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_TRUE@ fi - @OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_FALSE@ set -e ; \ - @OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_FALSE@ if ! test -d openjdk ; \ @@ -1576,7 +1576,7 @@ clean-overlay: # FIXME (missing): Rename to clone-ecj. stamps/extract-ecj.stamp: $(OPENJDK_TREE) @@ -66,13 +30,3 @@ touch stamps/native-ecj.stamp clean-native-ecj: -@@ -2167,6 +2167,9 @@ - stamps/jamvm.stamp: $(OPENJDK_TREE) stamps/rt.stamp - @BUILD_JAMVM_TRUE@ cd jamvm/jamvm && \ - @BUILD_JAMVM_TRUE@ ./autogen.sh --with-java-runtime-library=openjdk \ -+@BUILD_JAMVM_TRUE@ --host=$(host_alias) \ -+@BUILD_JAMVM_TRUE@ --build=$(build_alias) \ -+@BUILD_JAMVM_TRUE@ --target=$(target_alias) \ - @BUILD_JAMVM_TRUE@ --prefix=$(abs_top_builddir)/jamvm/install ; \ - @BUILD_JAMVM_TRUE@ $(MAKE) ; \ - @BUILD_JAMVM_TRUE@ $(MAKE) install -- cgit v1.2.3 From ce867d683d2e8414bf95c307a34dae9e4df21623 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 22 Aug 2011 08:40:05 +0200 Subject: implement submodel for foxboard lx. resolves duplicate full build for this systems --- mk/modules.mk | 4 +--- target/config/Config.in | 14 ++++++++++++++ target/cris/sys-available/foxboard-lx416 | 9 --------- target/cris/sys-available/foxboard-lx832 | 9 --------- target/linux/config/Config.in.block | 9 +++------ target/linux/config/Config.in.debug | 3 +-- target/linux/config/Config.in.fs | 3 +-- target/linux/config/Config.in.input | 3 +-- target/linux/config/Config.in.kernel | 18 +++++++++--------- target/linux/config/Config.in.netdevice | 6 ++---- target/linux/config/Config.in.usb | 15 +++++---------- 11 files changed, 37 insertions(+), 56 deletions(-) delete mode 100644 target/cris/sys-available/foxboard-lx416 delete mode 100644 target/cris/sys-available/foxboard-lx832 diff --git a/mk/modules.mk b/mk/modules.mk index c9819c697..e51732a4c 100644 --- a/mk/modules.mk +++ b/mk/modules.mk @@ -1180,13 +1180,11 @@ $(eval $(call KMOD_template,INPUT_EVDEV,input-evdev,\ # USB # -ifeq ($(ADK_TARGET_SYSTEM_FOXBOARD_LX832),) -ifeq ($(ADK_TARGET_SYSTEM_FOXBOARD_LX416),) +ifeq ($(ADK_TARGET_SYSTEM_FOXBOARD_LX),) $(eval $(call KMOD_template,USB,usb,\ $(MODULES_DIR)/kernel/drivers/usb/core/usbcore \ ,50)) endif -endif $(eval $(call KMOD_template,USB_EHCI_HCD,usb-ehci-hcd,\ $(MODULES_DIR)/kernel/drivers/usb/host/ehci-hcd \ diff --git a/target/config/Config.in b/target/config/Config.in index 38dca4b19..a15e42e27 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -73,6 +73,19 @@ config ADK_TARGET_ABI_N64 endchoice +# submodel support +choice +prompt "Foxboard LX Model" +depends on ADK_TARGET_SYSTEM_FOXBOARD_LX + +config ADK_TARGET_FOXBOARD_MODEL_LX416 + boolean "Foxboard LX 4x16" + +config ADK_TARGET_FOXBOARD_MODEL_LX832 + boolean "Foxboard LX 8x32" + +endchoice + choice prompt "Broadcom BCM47xx Model" depends on ADK_TARGET_SYSTEM_BROADCOM_BCM47XX @@ -302,6 +315,7 @@ config ADK_TARGET_CMDLINE default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_IBM_X40 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 + default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_FOXBOARD_LX default "" # c library diff --git a/target/cris/sys-available/foxboard-lx416 b/target/cris/sys-available/foxboard-lx416 deleted file mode 100644 index 2dce884c5..000000000 --- a/target/cris/sys-available/foxboard-lx416 +++ /dev/null @@ -1,9 +0,0 @@ -config ADK_TARGET_SYSTEM_FOXBOARD_LX416 - bool "FOX Board LX416" - select ADK_cris - select ADK_foxboard_lx416 - select ADK_TARGET_WITH_MTD - select ADK_TARGET_WITH_USB - help - Build a system for FOX Board LX416. - diff --git a/target/cris/sys-available/foxboard-lx832 b/target/cris/sys-available/foxboard-lx832 deleted file mode 100644 index a5e3de1e0..000000000 --- a/target/cris/sys-available/foxboard-lx832 +++ /dev/null @@ -1,9 +0,0 @@ -config ADK_TARGET_SYSTEM_FOXBOARD_LX832 - bool "FOX Board LX832" - select ADK_cris - select ADK_foxboard_lx832 - select ADK_TARGET_WITH_MTD - select ADK_TARGET_WITH_USB - help - Build a system for FOX Board LX832. - diff --git a/target/linux/config/Config.in.block b/target/linux/config/Config.in.block index 7e7d6cd9c..78e7b1bd5 100644 --- a/target/linux/config/Config.in.block +++ b/target/linux/config/Config.in.block @@ -274,8 +274,7 @@ config ADK_KPACKAGE_KMOD_BLK_DEV_MD tristate depends on !ADK_KERNEL_BLK_DEV_MD select ADK_KERNEL_MD - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX help config ADK_KERNEL_MD_RAID0 @@ -310,8 +309,7 @@ config ADK_KPACKAGE_KMOD_BLK_DEV_DM prompt "kmod-blk-dev-dm................... Device Mapper support" select ADK_KERNEL_MD depends on !ADK_KERNEL_BLK_DEV_DM - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX tristate help Device-mapper is a low level volume manager. It works by allowing @@ -359,8 +357,7 @@ config ADK_KPACKAGE_KMOD_BLK_DEV_DRBD tristate select ADK_KERNEL_BLK_DEV select ADK_KERNEL_CONNECTOR - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX help DRBD - http://www.drbd.org diff --git a/target/linux/config/Config.in.debug b/target/linux/config/Config.in.debug index 891a00c6e..0aed48de9 100644 --- a/target/linux/config/Config.in.debug +++ b/target/linux/config/Config.in.debug @@ -60,8 +60,7 @@ config ADK_KPACKAGE_KMOD_OPROFILE prompt "kernel support for oprofile" tristate select ADK_KERNEL_PROFILING - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX default n help use oprofile package to make use of the kernel support. diff --git a/target/linux/config/Config.in.fs b/target/linux/config/Config.in.fs index ee2adc39f..60b331755 100644 --- a/target/linux/config/Config.in.fs +++ b/target/linux/config/Config.in.fs @@ -190,8 +190,7 @@ config ADK_KPACKAGE_KMOD_XFS_FS tristate select ADK_KERNEL_EXPORTFS depends on !ADK_KERNEL_XFS_FS - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX default n help XFS is a high performance journaling filesystem which originated diff --git a/target/linux/config/Config.in.input b/target/linux/config/Config.in.input index 4a18af573..b8566e569 100644 --- a/target/linux/config/Config.in.input +++ b/target/linux/config/Config.in.input @@ -61,8 +61,7 @@ config ADK_KPACKAGE_KMOD_USB_HID select ADK_KERNEL_INPUT select ADK_KERNEL_HID select ADK_PACKAGE_KMOD_USB_CONTROLLER - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX depends on ADK_TARGET_WITH_USB default n diff --git a/target/linux/config/Config.in.kernel b/target/linux/config/Config.in.kernel index 0400d8db6..696f7afc9 100644 --- a/target/linux/config/Config.in.kernel +++ b/target/linux/config/Config.in.kernel @@ -3,21 +3,21 @@ config ADK_KERNEL_EXPERIMENTAL config ADK_KERNEL_ETRAX_MTD_SIZE hex - depends on ADK_TARGET_SYSTEM_FOXBOARD_LX416 || ADK_TARGET_SYSTEM_FOXBOARD_LX832 - default "0x00400000" if ADK_TARGET_SYSTEM_FOXBOARD_LX416 - default "0x00800000" if ADK_TARGET_SYSTEM_FOXBOARD_LX832 + depends on ADK_TARGET_SYSTEM_FOXBOARD_LX + default "0x00400000" if ADK_TARGET_FOXBOARD_MODEL_LX416 + default "0x00800000" if ADK_TARGET_FOXBOARD_MODEL_LX832 config ADK_KERNEL_ETRAX_DRAM_SIZE int - depends on ADK_TARGET_SYSTEM_FOXBOARD_LX416 || ADK_TARGET_SYSTEM_FOXBOARD_LX832 - default "16" if ADK_TARGET_SYSTEM_FOXBOARD_LX416 - default "32" if ADK_TARGET_SYSTEM_FOXBOARD_LX832 + depends on ADK_TARGET_SYSTEM_FOXBOARD_LX + default "16" if ADK_TARGET_FOXBOARD_MODEL_LX416 + default "32" if ADK_TARGET_FOXBOARD_MODEL_LX832 config ADK_KERNEL_ETRAX_DEF_R_SDRAM_TIMING hex - depends on ADK_TARGET_SYSTEM_FOXBOARD_LX416 || ADK_TARGET_SYSTEM_FOXBOARD_LX832 - default "0x80608002" if ADK_TARGET_SYSTEM_FOXBOARD_LX416 - default "0x80008002" if ADK_TARGET_SYSTEM_FOXBOARD_LX832 + depends on ADK_TARGET_SYSTEM_FOXBOARD_LX + default "0x80608002" if ADK_TARGET_FOXBOARD_MODEL_LX416 + default "0x80008002" if ADK_TARGET_FOXBOARD_MODEL_LX832 config ADK_KERNEL_BLK_DEV_INITRD boolean diff --git a/target/linux/config/Config.in.netdevice b/target/linux/config/Config.in.netdevice index 14820b810..b7ae9c655 100644 --- a/target/linux/config/Config.in.netdevice +++ b/target/linux/config/Config.in.netdevice @@ -373,8 +373,7 @@ config ADK_KPACKAGE_KMOD_RTL8187 prompt "kmod-rtl8187................. Realtek RTL8187/RTL8187B wireless cards" tristate depends on ADK_TARGET_WITH_USB - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX default n help Driver for Realtek RTL8187/RTL8187B wireless chips. @@ -389,8 +388,7 @@ config ADK_KPACKAGE_KMOD_P54_USB select ADK_KPACKAGE_KMOD_MAC80211 select ADK_KPACKAGE_KMOD_CRC_CCITT depends on ADK_PACKAGE_KMOD_USB_CONTROLLER - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX default n help Driver for Prism54 USB adaptors. diff --git a/target/linux/config/Config.in.usb b/target/linux/config/Config.in.usb index 2bc8d73db..ba004a59b 100644 --- a/target/linux/config/Config.in.usb +++ b/target/linux/config/Config.in.usb @@ -75,8 +75,7 @@ config ADK_KPACKAGE_KMOD_USB_UHCI_HCD depends on ADK_KPACKAGE_KMOD_USB depends on !ADK_KERNEL_USB_UHCI_HCD depends on !ADK_TARGET_SYSTEM_ACMESYSTEMS_FOXG20 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG @@ -97,8 +96,7 @@ config ADK_KPACKAGE_KMOD_USB_OHCI_HCD select ADK_PACKAGE_KMOD_USB_CONTROLLER depends on ADK_KPACKAGE_KMOD_USB #depends on !ADK_TARGET_SYSTEM_ACMESYSTEMS_FOXG20 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 @@ -120,8 +118,7 @@ config ADK_KPACKAGE_KMOD_USB_ISP116X_HCD select ADK_PACKAGE_KMOD_USB_CONTROLLER depends on ADK_KPACKAGE_KMOD_USB depends on !ADK_TARGET_SYSTEM_ACMESYSTEMS_FOXG20 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX default n help The ISP1160 and ISP1161 chips are USB host controllers. Enable this @@ -135,8 +132,7 @@ config ADK_KPACKAGE_KMOD_USB_SL811_HCD select ADK_PACKAGE_KMOD_USB_CONTROLLER depends on ADK_KPACKAGE_KMOD_USB depends on !ADK_TARGET_SYSTEM_ACMESYSTEMS_FOXG20 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX default n help The SL811HS is a single-port USB controller that supports either @@ -151,8 +147,7 @@ config ADK_KPACKAGE_KMOD_USB_EHCI_HCD select ADK_PACKAGE_KMOD_USB_CONTROLLER depends on !ADK_KERNEL_USB_EHCI_HCD depends on !ADK_TARGET_SYSTEM_ACMESYSTEMS_FOXG20 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX832 - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX416 + depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX depends on ADK_KPACKAGE_KMOD_USB default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 -- cgit v1.2.3 From 3c6574084fc00de09699604cda24c75cb616c874 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 22 Aug 2011 09:55:30 +0200 Subject: refresh kernel config, enable WLAN symbol, enable USB by default --- target/cris/kernel.config | 96 +- target/cris/sys-available/foxboard-lx | 9 + target/linux/config/Config.in.netdevice | 2 +- target/linux/config/Config.in.usb | 3 +- target/linux/patches/2.6.39/cris.patch | 7665 +------------------------------ 5 files changed, 181 insertions(+), 7594 deletions(-) create mode 100644 target/cris/sys-available/foxboard-lx diff --git a/target/cris/kernel.config b/target/cris/kernel.config index 755927166..8fbd0d9c7 100644 --- a/target/cris/kernel.config +++ b/target/cris/kernel.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.36 -# Tue Dec 28 18:58:02 2010 +# Linux/cris 2.6.39 Kernel Configuration +# Mon Aug 22 09:21:47 2011 # CONFIG_MMU=y CONFIG_ZONE_DMA=y @@ -36,29 +36,36 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_FHANDLE is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_SHOW=y # # RCU Subsystem # -CONFIG_TREE_RCU=y -# CONFIG_TINY_RCU is not set +CONFIG_TINY_RCU=y +# CONFIG_PREEMPT_RCU is not set # CONFIG_RCU_TRACE is not set -CONFIG_RCU_FANOUT=32 -# CONFIG_RCU_FANOUT_EXACT is not set # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -# CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set # CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y -CONFIG_EMBEDDED=y +CONFIG_EXPERT=y CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y # CONFIG_KALLSYMS is not set @@ -74,6 +81,7 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_EMBEDDED=y # # Kernel Performance Events And Counters @@ -148,7 +156,6 @@ CONFIG_INLINE_WRITE_UNLOCK_IRQ=y CONFIG_BINFMT_ELF=y # CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set -CONFIG_GENERIC_HARDIRQS=y CONFIG_ETRAX_CMDLINE="" CONFIG_ETRAX_WATCHDOG=y # CONFIG_ETRAX_WATCHDOG_NICE_DOGGY is not set @@ -164,12 +171,14 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NEED_PER_CPU_KM=y # # Hardware setup @@ -183,6 +192,7 @@ CONFIG_ETRAX100LX_V2=y CONFIG_ETRAX_ARCH_V10=y # CONFIG_ETRAX_ARCH_V32 is not set CONFIG_ETRAX_DRAM_SIZE=16 +CONFIG_ETRAX_MTD_SIZE=0x00800000 CONFIG_ETRAX_FLASH_BUSWIDTH=2 CONFIG_ETRAX_NANDFLASH_BUSWIDTH=1 CONFIG_ETRAX_FLASH1_SIZE=0 @@ -232,10 +242,9 @@ CONFIG_UNIX=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set +# CONFIG_NET_IPGRE_DEMUX is not set # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set @@ -277,6 +286,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set # CONFIG_DCB is not set +# CONFIG_BATMAN_ADV is not set # # Network testing @@ -287,11 +297,18 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set # # Drivers for built-in interfaces @@ -354,9 +371,7 @@ CONFIG_DEVTMPFS_MOUNT=y CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_TESTS is not set -CONFIG_MTD_CONCAT=y CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_ROOTFS_ROOT_DEV=y # CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_CMDLINE_PARTS is not set # CONFIG_MTD_AR7_PARTS is not set @@ -367,6 +382,7 @@ CONFIG_MTD_ROOTFS_ROOT_DEV=y CONFIG_MTD_CHAR=y CONFIG_MTD_BLKDEVS=y CONFIG_MTD_BLOCK=y +CONFIG_MTD_BLOCK_RO=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set @@ -411,6 +427,7 @@ CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_LATCH_ADDR is not set # # Self-contained MTD device drivers @@ -433,15 +450,21 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # LPDDR flash memory drivers # # CONFIG_MTD_LPDDR is not set - -# -# UBI - Unsorted block images -# # CONFIG_MTD_UBI is not set # CONFIG_PARPORT is not set # CONFIG_BLK_DEV is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_MEDIA_SUPPORT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -449,9 +472,9 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set +CONFIG_MII=y # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y -CONFIG_MII=y # CONFIG_ETHOC is not set # CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set @@ -464,7 +487,9 @@ CONFIG_MII=y # CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set -# CONFIG_WLAN is not set +CONFIG_WLAN=y +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -507,9 +532,12 @@ CONFIG_MII=y # Character devices # # CONFIG_VT is not set -# CONFIG_DEVKMEM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_N_GSM is not set +# CONFIG_DEVKMEM is not set # # Serial drivers @@ -522,9 +550,7 @@ CONFIG_MII=y # CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set # CONFIG_SERIAL_ALTERA_UART is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set +# CONFIG_TTY_PRINTK is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_RTC is not set @@ -546,17 +572,18 @@ CONFIG_UNIX98_PTYS=y # CONFIG_EXT4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set # CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y -# CONFIG_FSNOTIFY is not set +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set +# CONFIG_FANOTIFY is not set # CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set +# CONFIG_QUOTACTL is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -599,7 +626,6 @@ CONFIG_TMPFS=y # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set -# CONFIG_DLM is not set # CONFIG_SOUND is not set CONFIG_USB_SUPPORT=y # CONFIG_USB_ARCH_HAS_HCD is not set @@ -681,6 +707,7 @@ CONFIG_USB=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set # CONFIG_USB_GADGET is not set # @@ -694,6 +721,7 @@ CONFIG_USB=y # # CONFIG_SYSTEM_PROFILER is not set CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=1024 @@ -702,19 +730,22 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_SAMPLES is not set +# CONFIG_TEST_KSTRTOX is not set # CONFIG_NO_SEGFAULT_TERMINATION is not set # # Security options # # CONFIG_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set CONFIG_DEFAULT_SECURITY_DAC=y @@ -739,6 +770,9 @@ CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC32=y # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set CONFIG_HAS_IOMEM=y CONFIG_HAS_DMA=y CONFIG_NLATTR=y +# CONFIG_AVERAGE is not set diff --git a/target/cris/sys-available/foxboard-lx b/target/cris/sys-available/foxboard-lx new file mode 100644 index 000000000..0b4c81c68 --- /dev/null +++ b/target/cris/sys-available/foxboard-lx @@ -0,0 +1,9 @@ +config ADK_TARGET_SYSTEM_FOXBOARD_LX + bool "FOX Board LX" + select ADK_cris + select ADK_foxboard_lx + select ADK_TARGET_WITH_MTD + select ADK_TARGET_WITH_USB + help + Build a system for FOX Board LX models. + diff --git a/target/linux/config/Config.in.netdevice b/target/linux/config/Config.in.netdevice index b7ae9c655..1a84f6bcc 100644 --- a/target/linux/config/Config.in.netdevice +++ b/target/linux/config/Config.in.netdevice @@ -244,6 +244,7 @@ config ADK_KPACKAGE_KMOD_R8169 endmenu config ADK_KERNEL_WIRELESS + select ADK_KERNEL_NETDEVICES boolean config ADK_KERNEL_WIRELESS_EXT @@ -388,7 +389,6 @@ config ADK_KPACKAGE_KMOD_P54_USB select ADK_KPACKAGE_KMOD_MAC80211 select ADK_KPACKAGE_KMOD_CRC_CCITT depends on ADK_PACKAGE_KMOD_USB_CONTROLLER - depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX default n help Driver for Prism54 USB adaptors. diff --git a/target/linux/config/Config.in.usb b/target/linux/config/Config.in.usb index ba004a59b..f16ef7dab 100644 --- a/target/linux/config/Config.in.usb +++ b/target/linux/config/Config.in.usb @@ -30,7 +30,6 @@ config ADK_KPACKAGE_KMOD_USB tristate select ADK_KERNEL_NLS depends on !ADK_KERNEL_USB - #depends on !ADK_TARGET_SYSTEM_ACMESYSTEMS_FOXG20 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 @@ -38,6 +37,7 @@ config ADK_KPACKAGE_KMOD_USB default y if ADK_NATIVE_SYSTEM_IBM_X40 default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG default y if ADK_TARGET_SYSTEM_ACMESYSTEMS_FOXG20 + default y if ADK_TARGET_SYSTEM_FOXBOARD_LX default n help Universal Serial Bus (USB) is a specification for a serial bus @@ -178,6 +178,7 @@ config ADK_KPACKAGE_KMOD_USB_EHCI_HCD config ADK_PACKAGE_KMOD_USB_CONTROLLER tristate default y if ADK_TARGET_SYSTEM_ACMESYSTEMS_FOXG20 + default y if ADK_TARGET_SYSTEM_FOXBOARD_LX default n config ADK_KPACKAGE_KMOD_USB_ACM diff --git a/target/linux/patches/2.6.39/cris.patch b/target/linux/patches/2.6.39/cris.patch index f58391a5d..3bdc0acb8 100644 --- a/target/linux/patches/2.6.39/cris.patch +++ b/target/linux/patches/2.6.39/cris.patch @@ -1,6 +1,6 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/axisflashmap.c linux-2.6.39/arch/cris/arch-v10/drivers/axisflashmap.c --- linux-2.6.39.orig/arch/cris/arch-v10/drivers/axisflashmap.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/arch-v10/drivers/axisflashmap.c 2011-07-28 16:16:35.633425525 +0200 ++++ linux-2.6.39/arch/cris/arch-v10/drivers/axisflashmap.c 2011-08-22 08:58:55.057980882 +0200 @@ -113,7 +113,7 @@ /* If no partition-table was found, we use this default-set. */ @@ -146,443 +146,9 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/axisflashmap.c linux-2.6. return err; } -diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/axisflashmap.c.orig linux-2.6.39/arch/cris/arch-v10/drivers/axisflashmap.c.orig ---- linux-2.6.39.orig/arch/cris/arch-v10/drivers/axisflashmap.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/cris/arch-v10/drivers/axisflashmap.c.orig 2011-05-19 06:06:34.000000000 +0200 -@@ -0,0 +1,430 @@ -+/* -+ * Physical mapping layer for MTD using the Axis partitiontable format -+ * -+ * Copyright (c) 2001, 2002 Axis Communications AB -+ * -+ * This file is under the GPL. -+ * -+ * First partition is always sector 0 regardless of if we find a partitiontable -+ * or not. In the start of the next sector, there can be a partitiontable that -+ * tells us what other partitions to define. If there isn't, we use a default -+ * partition split defined below. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#ifdef CONFIG_CRIS_LOW_MAP -+#define FLASH_UNCACHED_ADDR KSEG_8 -+#define FLASH_CACHED_ADDR KSEG_5 -+#else -+#define FLASH_UNCACHED_ADDR KSEG_E -+#define FLASH_CACHED_ADDR KSEG_F -+#endif -+ -+#if CONFIG_ETRAX_FLASH_BUSWIDTH==1 -+#define flash_data __u8 -+#elif CONFIG_ETRAX_FLASH_BUSWIDTH==2 -+#define flash_data __u16 -+#elif CONFIG_ETRAX_FLASH_BUSWIDTH==4 -+#define flash_data __u32 -+#endif -+ -+/* From head.S */ -+extern unsigned long romfs_start, romfs_length, romfs_in_flash; -+ -+/* The master mtd for the entire flash. */ -+struct mtd_info* axisflash_mtd = NULL; -+ -+/* Map driver functions. */ -+ -+static map_word flash_read(struct map_info *map, unsigned long ofs) -+{ -+ map_word tmp; -+ tmp.x[0] = *(flash_data *)(map->map_priv_1 + ofs); -+ return tmp; -+} -+ -+static void flash_copy_from(struct map_info *map, void *to, -+ unsigned long from, ssize_t len) -+{ -+ memcpy(to, (void *)(map->map_priv_1 + from), len); -+} -+ -+static void flash_write(struct map_info *map, map_word d, unsigned long adr) -+{ -+ *(flash_data *)(map->map_priv_1 + adr) = (flash_data)d.x[0]; -+} -+ -+/* -+ * The map for chip select e0. -+ * -+ * We run into tricky coherence situations if we mix cached with uncached -+ * accesses to we only use the uncached version here. -+ * -+ * The size field is the total size where the flash chips may be mapped on the -+ * chip select. MTD probes should find all devices there and it does not matter -+ * if there are unmapped gaps or aliases (mirrors of flash devices). The MTD -+ * probes will ignore them. -+ * -+ * The start address in map_priv_1 is in virtual memory so we cannot use -+ * MEM_CSE0_START but must rely on that FLASH_UNCACHED_ADDR is the start -+ * address of cse0. -+ */ -+static struct map_info map_cse0 = { -+ .name = "cse0", -+ .size = MEM_CSE0_SIZE, -+ .bankwidth = CONFIG_ETRAX_FLASH_BUSWIDTH, -+ .read = flash_read, -+ .copy_from = flash_copy_from, -+ .write = flash_write, -+ .map_priv_1 = FLASH_UNCACHED_ADDR -+}; -+ -+/* -+ * The map for chip select e1. -+ * -+ * If there was a gap between cse0 and cse1, map_priv_1 would get the wrong -+ * address, but there isn't. -+ */ -+static struct map_info map_cse1 = { -+ .name = "cse1", -+ .size = MEM_CSE1_SIZE, -+ .bankwidth = CONFIG_ETRAX_FLASH_BUSWIDTH, -+ .read = flash_read, -+ .copy_from = flash_copy_from, -+ .write = flash_write, -+ .map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE -+}; -+ -+/* If no partition-table was found, we use this default-set. */ -+#define MAX_PARTITIONS 7 -+#define NUM_DEFAULT_PARTITIONS 3 -+ -+/* -+ * Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the -+ * size of one flash block and "filesystem"-partition needs 5 blocks to be able -+ * to use JFFS. -+ */ -+static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = { -+ { -+ .name = "boot firmware", -+ .size = CONFIG_ETRAX_PTABLE_SECTOR, -+ .offset = 0 -+ }, -+ { -+ .name = "kernel", -+ .size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR), -+ .offset = CONFIG_ETRAX_PTABLE_SECTOR -+ }, -+ { -+ .name = "filesystem", -+ .size = 5 * CONFIG_ETRAX_PTABLE_SECTOR, -+ .offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR) -+ } -+}; -+ -+/* Initialize the ones normally used. */ -+static struct mtd_partition axis_partitions[MAX_PARTITIONS] = { -+ { -+ .name = "part0", -+ .size = CONFIG_ETRAX_PTABLE_SECTOR, -+ .offset = 0 -+ }, -+ { -+ .name = "part1", -+ .size = 0, -+ .offset = 0 -+ }, -+ { -+ .name = "part2", -+ .size = 0, -+ .offset = 0 -+ }, -+ { -+ .name = "part3", -+ .size = 0, -+ .offset = 0 -+ }, -+ { -+ .name = "part4", -+ .size = 0, -+ .offset = 0 -+ }, -+ { -+ .name = "part5", -+ .size = 0, -+ .offset = 0 -+ }, -+ { -+ .name = "part6", -+ .size = 0, -+ .offset = 0 -+ }, -+}; -+ -+#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE -+/* Main flash device */ -+static struct mtd_partition main_partition = { -+ .name = "main", -+ .size = 0, -+ .offset = 0 -+}; -+#endif -+ -+/* -+ * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash -+ * chips in that order (because the amd_flash-driver is faster). -+ */ -+static struct mtd_info *probe_cs(struct map_info *map_cs) -+{ -+ struct mtd_info *mtd_cs = NULL; -+ -+ printk(KERN_INFO -+ "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n", -+ map_cs->name, map_cs->size, map_cs->map_priv_1); -+ -+#ifdef CONFIG_MTD_CFI -+ mtd_cs = do_map_probe("cfi_probe", map_cs); -+#endif -+#ifdef CONFIG_MTD_JEDECPROBE -+ if (!mtd_cs) -+ mtd_cs = do_map_probe("jedec_probe", map_cs); -+#endif -+ -+ return mtd_cs; -+} -+ -+/* -+ * Probe each chip select individually for flash chips. If there are chips on -+ * both cse0 and cse1, the mtd_info structs will be concatenated to one struct -+ * so that MTD partitions can cross chip boundries. -+ * -+ * The only known restriction to how you can mount your chips is that each -+ * chip select must hold similar flash chips. But you need external hardware -+ * to do that anyway and you can put totally different chips on cse0 and cse1 -+ * so it isn't really much of a restriction. -+ */ -+static struct mtd_info *flash_probe(void) -+{ -+ struct mtd_info *mtd_cse0; -+ struct mtd_info *mtd_cse1; -+ struct mtd_info *mtd_cse; -+ -+ mtd_cse0 = probe_cs(&map_cse0); -+ mtd_cse1 = probe_cs(&map_cse1); -+ -+ if (!mtd_cse0 && !mtd_cse1) { -+ /* No chip found. */ -+ return NULL; -+ } -+ -+ if (mtd_cse0 && mtd_cse1) { -+ struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 }; -+ -+ /* Since the concatenation layer adds a small overhead we -+ * could try to figure out if the chips in cse0 and cse1 are -+ * identical and reprobe the whole cse0+cse1 window. But since -+ * flash chips are slow, the overhead is relatively small. -+ * So we use the MTD concatenation layer instead of further -+ * complicating the probing procedure. -+ */ -+ mtd_cse = mtd_concat_create(mtds, ARRAY_SIZE(mtds), -+ "cse0+cse1"); -+ if (!mtd_cse) { -+ printk(KERN_ERR "%s and %s: Concatenation failed!\n", -+ map_cse0.name, map_cse1.name); -+ -+ /* The best we can do now is to only use what we found -+ * at cse0. -+ */ -+ mtd_cse = mtd_cse0; -+ map_destroy(mtd_cse1); -+ } -+ } else { -+ mtd_cse = mtd_cse0? mtd_cse0 : mtd_cse1; -+ } -+ -+ return mtd_cse; -+} -+ -+/* -+ * Probe the flash chip(s) and, if it succeeds, read the partition-table -+ * and register the partitions with MTD. -+ */ -+static int __init init_axis_flash(void) -+{ -+ struct mtd_info *mymtd; -+ int err = 0; -+ int pidx = 0; -+ struct partitiontable_head *ptable_head = NULL; -+ struct partitiontable_entry *ptable; -+ int use_default_ptable = 1; /* Until proven otherwise. */ -+ const char pmsg[] = " /dev/flash%d at 0x%08x, size 0x%08x\n"; -+ -+ if (!(mymtd = flash_probe())) { -+ /* There's no reason to use this module if no flash chip can -+ * be identified. Make sure that's understood. -+ */ -+ printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); -+ } else { -+ printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", -+ mymtd->name, mymtd->size); -+ axisflash_mtd = mymtd; -+ } -+ -+ if (mymtd) { -+ mymtd->owner = THIS_MODULE; -+ ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + -+ CONFIG_ETRAX_PTABLE_SECTOR + -+ PARTITION_TABLE_OFFSET); -+ } -+ pidx++; /* First partition is always set to the default. */ -+ -+ if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) -+ && (ptable_head->size < -+ (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + -+ PARTITIONTABLE_END_MARKER_SIZE)) -+ && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) + -+ ptable_head->size - -+ PARTITIONTABLE_END_MARKER_SIZE) -+ == PARTITIONTABLE_END_MARKER)) { -+ /* Looks like a start, sane length and end of a -+ * partition table, lets check csum etc. -+ */ -+ int ptable_ok = 0; -+ struct partitiontable_entry *max_addr = -+ (struct partitiontable_entry *) -+ ((unsigned long)ptable_head + sizeof(*ptable_head) + -+ ptable_head->size); -+ unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR; -+ unsigned char *p; -+ unsigned long csum = 0; -+ -+ ptable = (struct partitiontable_entry *) -+ ((unsigned long)ptable_head + sizeof(*ptable_head)); -+ -+ /* Lets be PARANOID, and check the checksum. */ -+ p = (unsigned char*) ptable; -+ -+ while (p <= (unsigned char*)max_addr) { -+ csum += *p++; -+ csum += *p++; -+ csum += *p++; -+ csum += *p++; -+ } -+ ptable_ok = (csum == ptable_head->checksum); -+ -+ /* Read the entries and use/show the info. */ -+ printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n", -+ (ptable_ok ? " valid" : "n invalid"), ptable_head, -+ max_addr); -+ -+ /* We have found a working bootblock. Now read the -+ * partition table. Scan the table. It ends when -+ * there is 0xffffffff, that is, empty flash. -+ */ -+ while (ptable_ok -+ && ptable->offset != 0xffffffff -+ && ptable < max_addr -+ && pidx < MAX_PARTITIONS) { -+ -+ axis_partitions[pidx].offset = offset + ptable->offset; -+ axis_partitions[pidx].size = ptable->size; -+ -+ printk(pmsg, pidx, axis_partitions[pidx].offset, -+ axis_partitions[pidx].size); -+ pidx++; -+ ptable++; -+ } -+ use_default_ptable = !ptable_ok; -+ } -+ -+ if (romfs_in_flash) { -+ /* Add an overlapping device for the root partition (romfs). */ -+ -+ axis_partitions[pidx].name = "romfs"; -+ axis_partitions[pidx].size = romfs_length; -+ axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; -+ axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; -+ -+ printk(KERN_INFO -+ " Adding readonly flash partition for romfs image:\n"); -+ printk(pmsg, pidx, axis_partitions[pidx].offset, -+ axis_partitions[pidx].size); -+ pidx++; -+ } -+ -+#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE -+ if (mymtd) { -+ main_partition.size = mymtd->size; -+ err = add_mtd_partitions(mymtd, &main_partition, 1); -+ if (err) -+ panic("axisflashmap: Could not initialize " -+ "partition for whole main mtd device!\n"); -+ } -+#endif -+ -+ if (mymtd) { -+ if (use_default_ptable) { -+ printk(KERN_INFO " Using default partition table.\n"); -+ err = add_mtd_partitions(mymtd, axis_default_partitions, -+ NUM_DEFAULT_PARTITIONS); -+ } else { -+ err = add_mtd_partitions(mymtd, axis_partitions, pidx); -+ } -+ -+ if (err) -+ panic("axisflashmap could not add MTD partitions!\n"); -+ } -+ -+ if (!romfs_in_flash) { -+ /* Create an RAM device for the root partition (romfs). */ -+ -+#if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) -+ /* No use trying to boot this kernel from RAM. Panic! */ -+ printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM " -+ "device due to kernel (mis)configuration!\n"); -+ panic("This kernel cannot boot from RAM!\n"); -+#else -+ struct mtd_info *mtd_ram; -+ -+ mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); -+ if (!mtd_ram) -+ panic("axisflashmap couldn't allocate memory for " -+ "mtd_info!\n"); -+ -+ printk(KERN_INFO " Adding RAM partition for romfs image:\n"); -+ printk(pmsg, pidx, (unsigned)romfs_start, -+ (unsigned)romfs_length); -+ -+ err = mtdram_init_device(mtd_ram, -+ (void *)romfs_start, -+ romfs_length, -+ "romfs"); -+ if (err) -+ panic("axisflashmap could not initialize MTD RAM " -+ "device!\n"); -+#endif -+ } -+ return err; -+} -+ -+/* This adds the above to the kernels init-call chain. */ -+module_init(init_axis_flash); -+ -+EXPORT_SYMBOL(axisflash_mtd); diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/ds1302.c linux-2.6.39/arch/cris/arch-v10/drivers/ds1302.c --- linux-2.6.39.orig/arch/cris/arch-v10/drivers/ds1302.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/arch-v10/drivers/ds1302.c 2011-07-28 16:16:35.863415658 +0200 ++++ linux-2.6.39/arch/cris/arch-v10/drivers/ds1302.c 2011-08-22 08:58:55.157980341 +0200 @@ -22,6 +22,7 @@ #include #include @@ -617,7 +183,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/ds1302.c linux-2.6.39/arc } diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/gpio.c linux-2.6.39/arch/cris/arch-v10/drivers/gpio.c --- linux-2.6.39.orig/arch/cris/arch-v10/drivers/gpio.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/arch-v10/drivers/gpio.c 2011-07-28 16:16:36.023425394 +0200 ++++ linux-2.6.39/arch/cris/arch-v10/drivers/gpio.c 2011-08-22 08:58:55.227980067 +0200 @@ -20,6 +20,7 @@ #include #include @@ -653,7 +219,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/gpio.c linux-2.6.39/arch/ CRIS_LED_NETWORK_SET(0); diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/lib/hw_settings.S linux-2.6.39/arch/cris/arch-v10/lib/hw_settings.S --- linux-2.6.39.orig/arch/cris/arch-v10/lib/hw_settings.S 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/arch-v10/lib/hw_settings.S 2011-07-28 16:16:36.163758404 +0200 ++++ linux-2.6.39/arch/cris/arch-v10/lib/hw_settings.S 2011-08-22 08:58:55.287980084 +0200 @@ -58,3 +58,5 @@ .dword R_PORT_PB_SET .dword PB_SET_VALUE @@ -662,7 +228,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/lib/hw_settings.S linux-2.6.39/ar + .dword 0xdeadc0de diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/mm/init.c linux-2.6.39/arch/cris/arch-v10/mm/init.c --- linux-2.6.39.orig/arch/cris/arch-v10/mm/init.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/arch-v10/mm/init.c 2011-07-28 16:16:36.313421347 +0200 ++++ linux-2.6.39/arch/cris/arch-v10/mm/init.c 2011-08-22 08:58:55.347981214 +0200 @@ -184,6 +184,9 @@ free_area_init_node(0, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0); @@ -675,7 +241,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/mm/init.c linux-2.6.39/arch/cris/ * is called before any driver is initialized. diff -Nur linux-2.6.39.orig/arch/cris/boot/compressed/Makefile linux-2.6.39/arch/cris/boot/compressed/Makefile --- linux-2.6.39.orig/arch/cris/boot/compressed/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/boot/compressed/Makefile 2011-07-28 16:16:36.453421314 +0200 ++++ linux-2.6.39/arch/cris/boot/compressed/Makefile 2011-08-22 08:58:55.427980567 +0200 @@ -18,7 +18,7 @@ OBJECTS-$(CONFIG_ETRAX_ARCH_V32) = $(obj)/head_v32.o OBJECTS-$(CONFIG_ETRAX_ARCH_V10) = $(obj)/head_v10.o @@ -687,7 +253,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/boot/compressed/Makefile linux-2.6.39/arch cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@ diff -Nur linux-2.6.39.orig/arch/cris/boot/Makefile linux-2.6.39/arch/cris/boot/Makefile --- linux-2.6.39.orig/arch/cris/boot/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/boot/Makefile 2011-07-28 16:16:36.573671907 +0200 ++++ linux-2.6.39/arch/cris/boot/Makefile 2011-08-22 08:58:55.507980367 +0200 @@ -5,7 +5,7 @@ objcopyflags-$(CONFIG_ETRAX_ARCH_V10) += -R .note -R .comment objcopyflags-$(CONFIG_ETRAX_ARCH_V32) += --remove-section=.bss --remove-section=.note.gnu.build-id @@ -707,7 +273,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/boot/Makefile linux-2.6.39/arch/cris/boot/ @cp $< $@ diff -Nur linux-2.6.39.orig/arch/cris/Kconfig linux-2.6.39/arch/cris/Kconfig --- linux-2.6.39.orig/arch/cris/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/Kconfig 2011-07-28 16:16:36.713417234 +0200 ++++ linux-2.6.39/arch/cris/Kconfig 2011-08-22 08:58:55.587980284 +0200 @@ -168,6 +168,12 @@ help Size of DRAM (decimal in MB) typically 2, 8 or 16. @@ -751,7126 +317,103 @@ diff -Nur linux-2.6.39.orig/arch/cris/Kconfig linux-2.6.39/arch/cris/Kconfig source "drivers/usb/Kconfig" source "drivers/uwb/Kconfig" -diff -Nur linux-2.6.39.orig/arch/cris/Kconfig.orig linux-2.6.39/arch/cris/Kconfig.orig ---- linux-2.6.39.orig/arch/cris/Kconfig.orig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/cris/Kconfig.orig 2011-05-19 06:06:34.000000000 +0200 -@@ -0,0 +1,690 @@ -+config MMU -+ bool -+ default y -+ -+config ZONE_DMA -+ bool -+ default y -+ -+config RWSEM_GENERIC_SPINLOCK -+ bool -+ default y -+ -+config RWSEM_XCHGADD_ALGORITHM -+ bool -+ -+config GENERIC_CMOS_UPDATE -+ def_bool y -+ -+config ARCH_USES_GETTIMEOFFSET -+ def_bool n -+ -+config GENERIC_IOMAP -+ bool -+ default y -+ -+config ARCH_HAS_ILOG2_U32 -+ bool -+ default n -+ -+config ARCH_HAS_ILOG2_U64 -+ bool -+ default n -+ -+config GENERIC_FIND_NEXT_BIT -+ bool -+ default y -+ -+config GENERIC_HWEIGHT -+ bool -+ default y -+ -+config GENERIC_CALIBRATE_DELAY -+ bool -+ default y -+ -+config NO_IOPORT -+ def_bool y -+ -+config FORCE_MAX_ZONEORDER -+ int -+ default 6 -+ -+config CRIS -+ bool -+ default y -+ select HAVE_IDE -+ select HAVE_GENERIC_HARDIRQS -+ select GENERIC_IRQ_SHOW -+ -+config HZ -+ int -+ default 100 -+ -+source "init/Kconfig" -+ -+source "kernel/Kconfig.freezer" -+ -+menu "General setup" -+ -+source "fs/Kconfig.binfmt" -+ -+config ETRAX_CMDLINE -+ string "Kernel command line" -+ default "root=/dev/mtdblock3" -+ help -+ Pass additional commands to the kernel. -+ -+config ETRAX_WATCHDOG -+ bool "Enable ETRAX watchdog" -+ help -+ Enable the built-in watchdog timer support on ETRAX based embedded -+ network computers. -+ -+config ETRAX_WATCHDOG_NICE_DOGGY -+ bool "Disable watchdog during Oops printouts" -+ depends on ETRAX_WATCHDOG -+ help -+ By enabling this you make sure that the watchdog does not bite while -+ printing oopses. Recommended for development systems but not for -+ production releases. -+ -+config ETRAX_FAST_TIMER -+ bool "Enable ETRAX fast timer API" -+ help -+ This options enables the API to a fast timer implementation using -+ timer1 to get sub jiffie resolution timers (primarily one-shot -+ timers). -+ This is needed if CONFIG_ETRAX_SERIAL_FAST_TIMER is enabled. -+ -+config ETRAX_KMALLOCED_MODULES -+ bool "Enable module allocation with kmalloc" -+ help -+ Enable module allocation with kmalloc instead of vmalloc. -+ -+config OOM_REBOOT -+ bool "Enable reboot at out of memory" -+ -+source "kernel/Kconfig.preempt" -+ -+source mm/Kconfig -+ -+endmenu -+ -+menu "Hardware setup" -+ -+choice -+ prompt "Processor type" -+ default ETRAX100LX -+ -+config ETRAX100LX -+ bool "ETRAX-100LX-v1" -+ select ARCH_USES_GETTIMEOFFSET -+ help -+ Support version 1 of the ETRAX 100LX. +diff -Nur linux-2.6.39.orig/arch/cris/Makefile linux-2.6.39/arch/cris/Makefile +--- linux-2.6.39.orig/arch/cris/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/cris/Makefile 2011-08-22 08:58:55.837980069 +0200 +@@ -40,10 +40,10 @@ + + LD = $(CROSS_COMPILE)ld -mcrislinux + +-OBJCOPYFLAGS := -O binary -R .note -R .comment -S ++OBJCOPYFLAGS := -O binary -R .bss -R .note -R .note.gnu.build-id -R .comment -S + + KBUILD_AFLAGS += -mlinux -march=$(arch-y) $(inc) +-KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe $(inc) ++KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe -fno-peephole2 $(inc) + KBUILD_CPPFLAGS += $(inc) + + ifdef CONFIG_FRAME_POINTER +diff -Nur linux-2.6.39.orig/arch/cris/mm/init.c linux-2.6.39/arch/cris/mm/init.c +--- linux-2.6.39.orig/arch/cris/mm/init.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/cris/mm/init.c 2011-08-22 08:58:55.897980391 +0200 +@@ -16,6 +16,7 @@ + DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); + + unsigned long empty_zero_page; ++EXPORT_SYMBOL(empty_zero_page); + + extern char _stext, _edata, _etext; /* From linkerscript */ + extern char __init_begin, __init_end; +@@ -81,3 +82,10 @@ + printk (KERN_INFO "Freeing unused kernel memory: %luk freed\n", + (unsigned long)((&__init_end - &__init_begin) >> 10)); + } + -+config ETRAX100LX_V2 -+ bool "ETRAX-100LX-v2" -+ select ARCH_USES_GETTIMEOFFSET -+ help -+ Support version 2 of the ETRAX 100LX. ++#ifdef CONFIG_BLK_DEV_INITRD ++void free_initrd_mem(unsigned long start, unsigned long end) ++{ ++ return 0; ++} ++#endif +diff -Nur linux-2.6.39.orig/drivers/net/cris/eth_v10.c linux-2.6.39/drivers/net/cris/eth_v10.c +--- linux-2.6.39.orig/drivers/net/cris/eth_v10.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/cris/eth_v10.c 2011-08-22 08:58:55.987980420 +0200 +@@ -1714,7 +1714,7 @@ + static void + e100_netpoll(struct net_device* netdev) + { +- e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL); ++ e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev); + } + #endif + +diff -Nur linux-2.6.39.orig/drivers/tty/serial/crisv10.c linux-2.6.39/drivers/tty/serial/crisv10.c +--- linux-2.6.39.orig/drivers/tty/serial/crisv10.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/tty/serial/crisv10.c 2011-08-22 08:58:56.137981508 +0200 +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -4430,6 +4431,7 @@ + #endif + }; + ++static struct class *rs_class; + static int __init rs_init(void) + { + int i; +@@ -4564,6 +4566,24 @@ + #endif + #endif /* CONFIG_SVINTO_SIM */ + ++ rs_class = class_create(THIS_MODULE, "rs_tty"); ++#ifdef CONFIG_ETRAX_SERIAL_PORT0 ++ device_create(rs_class, NULL, ++ MKDEV(TTY_MAJOR, 64), NULL, "ttyS0"); ++#endif ++#ifdef CONFIG_ETRAX_SERIAL_PORT1 ++ device_create(rs_class, NULL, ++ MKDEV(TTY_MAJOR, 65), NULL, "ttyS1"); ++#endif ++#ifdef CONFIG_ETRAX_SERIAL_PORT2 ++ device_create(rs_class, NULL, ++ MKDEV(TTY_MAJOR, 66), NULL, "ttyS2"); ++#endif ++#ifdef CONFIG_ETRAX_SERIAL_PORT3 ++ device_create(rs_class, NULL, ++ MKDEV(TTY_MAJOR, 67), NULL, "ttyS3"); ++#endif + -+config SVINTO_SIM -+ bool "ETRAX-100LX-for-xsim-simulator" -+ select ARCH_USES_GETTIMEOFFSET -+ help -+ Support the xsim ETRAX Simulator. -+ -+config ETRAXFS -+ bool "ETRAX-FS-V32" -+ help -+ Support CRIS V32. -+ -+config CRIS_MACH_ARTPEC3 -+ bool "ARTPEC-3" -+ help -+ Support Axis ARTPEC-3. -+ -+endchoice -+ -+config ETRAX_VCS_SIM -+ bool "VCS Simulator" -+ help -+ Setup hardware to be run in the VCS simulator. -+ -+config ETRAX_ARCH_V10 -+ bool -+ default y if ETRAX100LX || ETRAX100LX_V2 -+ default n if !(ETRAX100LX || ETRAX100LX_V2) -+ -+config ETRAX_ARCH_V32 -+ bool -+ default y if (ETRAXFS || CRIS_MACH_ARTPEC3) -+ default n if !(ETRAXFS || CRIS_MACH_ARTPEC3) -+ -+config ETRAX_DRAM_SIZE -+ int "DRAM size (dec, in MB)" -+ default "8" -+ help -+ Size of DRAM (decimal in MB) typically 2, 8 or 16. -+ -+config ETRAX_VMEM_SIZE -+ int "Video memory size (dec, in MB)" -+ depends on ETRAX_ARCH_V32 && !ETRAXFS -+ default 8 if !ETRAXFS -+ help -+ Size of Video accessible memory (decimal, in MB). -+ -+config ETRAX_FLASH_BUSWIDTH -+ int "Buswidth of NOR flash in bytes" -+ default "2" -+ help -+ Width in bytes of the NOR Flash bus (1, 2 or 4). Is usually 2. -+ -+config ETRAX_NANDFLASH_BUSWIDTH -+ int "Buswidth of NAND flash in bytes" -+ default "1" -+ help -+ Width in bytes of the NAND flash (1 or 2). -+ -+config ETRAX_FLASH1_SIZE -+ int "FLASH1 size (dec, in MB. 0 = Unknown)" -+ default "0" -+ -+choice -+ prompt "Product debug-port" -+ default ETRAX_DEBUG_PORT0 -+ -+config ETRAX_DEBUG_PORT0 -+ bool "Serial-0" -+ help -+ Choose a serial port for the ETRAX debug console. Default to -+ port 0. -+ -+config ETRAX_DEBUG_PORT1 -+ bool "Serial-1" -+ help -+ Use serial port 1 for the console. -+ -+config ETRAX_DEBUG_PORT2 -+ bool "Serial-2" -+ help -+ Use serial port 2 for the console. -+ -+config ETRAX_DEBUG_PORT3 -+ bool "Serial-3" -+ help -+ Use serial port 3 for the console. -+ -+config ETRAX_DEBUG_PORT_NULL -+ bool "disabled" -+ help -+ Disable serial-port debugging. -+ -+endchoice -+ -+choice -+ prompt "Kernel GDB port" -+ depends on ETRAX_KGDB -+ default ETRAX_KGDB_PORT0 -+ help -+ Choose a serial port for kernel debugging. NOTE: This port should -+ not be enabled under Drivers for built-in interfaces (as it has its -+ own initialization code) and should not be the same as the debug port. -+ -+config ETRAX_KGDB_PORT0 -+ bool "Serial-0" -+ help -+ Use serial port 0 for kernel debugging. -+ -+config ETRAX_KGDB_PORT1 -+ bool "Serial-1" -+ help -+ Use serial port 1 for kernel debugging. -+ -+config ETRAX_KGDB_PORT2 -+ bool "Serial-2" -+ help -+ Use serial port 2 for kernel debugging. -+ -+config ETRAX_KGDB_PORT3 -+ bool "Serial-3" -+ help -+ Use serial port 3 for kernel debugging. -+ -+endchoice -+ -+source arch/cris/arch-v10/Kconfig -+source arch/cris/arch-v32/Kconfig -+ -+endmenu -+ -+source "net/Kconfig" -+ -+# bring in ETRAX built-in drivers -+menu "Drivers for built-in interfaces" -+source arch/cris/arch-v10/drivers/Kconfig -+source arch/cris/arch-v32/drivers/Kconfig -+ -+config ETRAX_AXISFLASHMAP -+ bool "Axis flash-map support" -+ select MTD -+ select MTD_CFI -+ select MTD_CFI_AMDSTD -+ select MTD_JEDECPROBE if ETRAX_ARCH_V32 -+ select MTD_CHAR -+ select MTD_BLOCK -+ select MTD_PARTITIONS -+ select MTD_COMPLEX_MAPPINGS -+ help -+ This option enables MTD mapping of flash devices. Needed to use -+ flash memories. If unsure, say Y. -+ -+config ETRAX_RTC -+ bool "Real Time Clock support" -+ depends on ETRAX_I2C -+ help -+ Enables drivers for the Real-Time Clock battery-backed chips on -+ some products. The kernel reads the time when booting, and -+ the date can be set using ioctl(fd, RTC_SET_TIME, &rt) with rt a -+ rtc_time struct (see ) on the /dev/rtc -+ device. You can check the time with cat /proc/rtc, but -+ normal time reading should be done using libc function time and -+ friends. -+ -+choice -+ prompt "RTC chip" -+ depends on ETRAX_RTC -+ default ETRAX_DS1302 -+ -+config ETRAX_DS1302 -+ depends on ETRAX_ARCH_V10 -+ bool "DS1302" -+ help -+ Enables the driver for the DS1302 Real-Time Clock battery-backed -+ chip on some products. -+ -+config ETRAX_PCF8563 -+ bool "PCF8563" -+ help -+ Enables the driver for the PCF8563 Real-Time Clock battery-backed -+ chip on some products. -+ -+endchoice -+ -+config ETRAX_SYNCHRONOUS_SERIAL -+ bool "Synchronous serial-port support" -+ help -+ Select this to enable the synchronous serial port driver. -+ -+config ETRAX_SYNCHRONOUS_SERIAL_PORT0 -+ bool "Synchronous serial port 0 enabled" -+ depends on ETRAX_SYNCHRONOUS_SERIAL -+ help -+ Enabled synchronous serial port 0. -+ -+config ETRAX_SYNCHRONOUS_SERIAL0_DMA -+ bool "Enable DMA on synchronous serial port 0." -+ depends on ETRAX_SYNCHRONOUS_SERIAL_PORT0 -+ help -+ A synchronous serial port can run in manual or DMA mode. -+ Selecting this option will make it run in DMA mode. -+ -+config ETRAX_SYNCHRONOUS_SERIAL_PORT1 -+ bool "Synchronous serial port 1 enabled" -+ depends on ETRAX_SYNCHRONOUS_SERIAL && (ETRAXFS || ETRAX_ARCH_V10) -+ help -+ Enabled synchronous serial port 1. -+ -+config ETRAX_SYNCHRONOUS_SERIAL1_DMA -+ bool "Enable DMA on synchronous serial port 1." -+ depends on ETRAX_SYNCHRONOUS_SERIAL_PORT1 -+ help -+ A synchronous serial port can run in manual or DMA mode. -+ Selecting this option will make it run in DMA mode. -+ -+choice -+ prompt "Network LED behavior" -+ depends on ETRAX_ETHERNET -+ default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY -+ -+config ETRAX_NETWORK_LED_ON_WHEN_LINK -+ bool "LED_on_when_link" -+ help -+ Selecting LED_on_when_link will light the LED when there is a -+ connection and will flash off when there is activity. -+ -+ Selecting LED_on_when_activity will light the LED only when -+ there is activity. -+ -+ This setting will also affect the behaviour of other activity LEDs -+ e.g. Bluetooth. -+ -+config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY -+ bool "LED_on_when_activity" -+ help -+ Selecting LED_on_when_link will light the LED when there is a -+ connection and will flash off when there is activity. -+ -+ Selecting LED_on_when_activity will light the LED only when -+ there is activity. -+ -+ This setting will also affect the behaviour of other activity LEDs -+ e.g. Bluetooth. -+ -+endchoice -+ -+choice -+ prompt "Ser0 DMA out channel" -+ depends on ETRAX_SERIAL_PORT0 -+ default ETRAX_SERIAL_PORT0_DMA6_OUT if ETRAX_ARCH_V32 -+ default ETRAX_SERIAL_PORT0_NO_DMA_OUT if ETRAX_ARCH_V10 -+ -+config ETRAX_SERIAL_PORT0_NO_DMA_OUT -+ bool "Ser0 uses no DMA for output" -+ help -+ Do not use DMA for ser0 output. -+ -+config ETRAX_SERIAL_PORT0_DMA6_OUT -+ bool "Ser0 uses DMA6 for output" -+ depends on ETRAXFS -+ help -+ Enables the DMA6 output channel for ser0 (ttyS0). -+ If you do not enable DMA, an interrupt for each character will be -+ used when transmitting data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+config ETRAX_SERIAL_PORT0_DMA0_OUT -+ bool "Ser0 uses DMA0 for output" -+ depends on CRIS_MACH_ARTPEC3 -+ help -+ Enables the DMA0 output channel for ser0 (ttyS0). -+ If you do not enable DMA, an interrupt for each character will be -+ used when transmitting data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+endchoice -+ -+choice -+ prompt "Ser0 DMA in channel " -+ depends on ETRAX_SERIAL_PORT0 -+ default ETRAX_SERIAL_PORT0_NO_DMA_IN if ETRAX_ARCH_V32 -+ default ETRAX_SERIAL_PORT0_DMA7_IN if ETRAX_ARCH_V10 -+ help -+ What DMA channel to use for ser0. -+ -+config ETRAX_SERIAL_PORT0_NO_DMA_IN -+ bool "Ser0 uses no DMA for input" -+ help -+ Do not use DMA for ser0 input. -+ -+config ETRAX_SERIAL_PORT0_DMA7_IN -+ bool "Ser0 uses DMA7 for input" -+ depends on ETRAXFS -+ help -+ Enables the DMA7 input channel for ser0 (ttyS0). -+ If you do not enable DMA, an interrupt for each character will be -+ used when receiving data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+config ETRAX_SERIAL_PORT0_DMA1_IN -+ bool "Ser0 uses DMA1 for input" -+ depends on CRIS_MACH_ARTPEC3 -+ help -+ Enables the DMA1 input channel for ser0 (ttyS0). -+ If you do not enable DMA, an interrupt for each character will be -+ used when receiving data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+endchoice -+ -+choice -+ prompt "Ser1 DMA in channel " -+ depends on ETRAX_SERIAL_PORT1 -+ default ETRAX_SERIAL_PORT1_NO_DMA_IN if ETRAX_ARCH_V32 -+ default ETRAX_SERIAL_PORT1_DMA9_IN if ETRAX_ARCH_V10 -+ help -+ What DMA channel to use for ser1. -+ -+config ETRAX_SERIAL_PORT1_NO_DMA_IN -+ bool "Ser1 uses no DMA for input" -+ help -+ Do not use DMA for ser1 input. -+ -+config ETRAX_SERIAL_PORT1_DMA5_IN -+ bool "Ser1 uses DMA5 for input" -+ depends on ETRAX_ARCH_V32 -+ help -+ Enables the DMA5 input channel for ser1 (ttyS1). -+ If you do not enable DMA, an interrupt for each character will be -+ used when receiving data. -+ Normally you want this on, unless you use the DMA channel for -+ something else. -+ -+config ETRAX_SERIAL_PORT1_DMA9_IN -+ depends on ETRAX_ARCH_V10 -+ bool "Ser1 uses DMA9 for input" -+ -+endchoice -+ -+ -+choice -+ prompt "Ser1 DMA out channel" -+ depends on ETRAX_SERIAL_PORT1 -+ default ETRAX_SERIAL_PORT1_NO_DMA_OUT if ETRAX_ARCH_V32 -+ default ETRAX_SERIAL_PORT1_DMA8_OUT if ETRAX_ARCH_V10 -+ help -+ What DMA channel to use for ser1. -+ -+config ETRAX_SERIAL_PORT1_NO_DMA_OUT -+ bool "Ser1 uses no DMA for output" -+ help -+ Do not use DMA for ser1 output. -+ -+config ETRAX_SERIAL_PORT1_DMA8_OUT -+ depends on ETRAX_ARCH_V10 -+ bool "Ser1 uses DMA8 for output" -+ -+config ETRAX_SERIAL_PORT1_DMA4_OUT -+ depends on ETRAX_ARCH_V32 -+ bool "Ser1 uses DMA4 for output" -+ help -+ Enables the DMA4 output channel for ser1 (ttyS1). -+ If you do not enable DMA, an interrupt for each character will be -+ used when transmitting data. -+ Normally you want this on, unless you use the DMA channel for -+ something else. -+ -+endchoice -+ -+choice -+ prompt "Ser2 DMA out channel" -+ depends on ETRAX_SERIAL_PORT2 -+ default ETRAX_SERIAL_PORT2_NO_DMA_OUT if ETRAX_ARCH_V32 -+ default ETRAX_SERIAL_PORT2_DMA2_OUT if ETRAX_ARCH_V10 -+ -+config ETRAX_SERIAL_PORT2_NO_DMA_OUT -+ bool "Ser2 uses no DMA for output" -+ help -+ Do not use DMA for ser2 output. -+ -+config ETRAX_SERIAL_PORT2_DMA2_OUT -+ bool "Ser2 uses DMA2 for output" -+ depends on ETRAXFS || ETRAX_ARCH_V10 -+ help -+ Enables the DMA2 output channel for ser2 (ttyS2). -+ If you do not enable DMA, an interrupt for each character will be -+ used when transmitting data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+config ETRAX_SERIAL_PORT2_DMA6_OUT -+ bool "Ser2 uses DMA6 for output" -+ depends on CRIS_MACH_ARTPEC3 -+ help -+ Enables the DMA6 output channel for ser2 (ttyS2). -+ If you do not enable DMA, an interrupt for each character will be -+ used when transmitting data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+endchoice -+ -+choice -+ prompt "Ser2 DMA in channel" -+ depends on ETRAX_SERIAL_PORT2 -+ default ETRAX_SERIAL_PORT2_NO_DMA_IN if ETRAX_ARCH_V32 -+ default ETRAX_SERIAL_PORT2_DMA3_IN if ETRAX_ARCH_V10 -+ help -+ What DMA channel to use for ser2. -+ -+config ETRAX_SERIAL_PORT2_NO_DMA_IN -+ bool "Ser2 uses no DMA for input" -+ help -+ Do not use DMA for ser2 input. -+ -+config ETRAX_SERIAL_PORT2_DMA3_IN -+ bool "Ser2 uses DMA3 for input" -+ depends on ETRAXFS || ETRAX_ARCH_V10 -+ help -+ Enables the DMA3 input channel for ser2 (ttyS2). -+ If you do not enable DMA, an interrupt for each character will be -+ used when receiving data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+config ETRAX_SERIAL_PORT2_DMA7_IN -+ bool "Ser2 uses DMA7 for input" -+ depends on CRIS_MACH_ARTPEC3 -+ help -+ Enables the DMA7 input channel for ser2 (ttyS2). -+ If you do not enable DMA, an interrupt for each character will be -+ used when receiving data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+endchoice -+ -+choice -+ prompt "Ser3 DMA in channel" -+ depends on ETRAX_SERIAL_PORT3 -+ default ETRAX_SERIAL_PORT3_NO_DMA_IN if ETRAX_ARCH_V32 -+ default ETRAX_SERIAL_PORT3_DMA5_IN if ETRAX_ARCH_V10 -+ help -+ What DMA channel to use for ser3. -+ -+config ETRAX_SERIAL_PORT3_NO_DMA_IN -+ bool "Ser3 uses no DMA for input" -+ help -+ Do not use DMA for ser3 input. -+ -+config ETRAX_SERIAL_PORT3_DMA5_IN -+ depends on ETRAX_ARCH_V10 -+ bool "DMA 5" -+ -+config ETRAX_SERIAL_PORT3_DMA9_IN -+ bool "Ser3 uses DMA9 for input" -+ depends on ETRAXFS -+ help -+ Enables the DMA9 input channel for ser3 (ttyS3). -+ If you do not enable DMA, an interrupt for each character will be -+ used when receiving data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+config ETRAX_SERIAL_PORT3_DMA3_IN -+ bool "Ser3 uses DMA3 for input" -+ depends on CRIS_MACH_ARTPEC3 -+ help -+ Enables the DMA3 input channel for ser3 (ttyS3). -+ If you do not enable DMA, an interrupt for each character will be -+ used when receiving data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+endchoice -+ -+choice -+ prompt "Ser3 DMA out channel" -+ depends on ETRAX_SERIAL_PORT3 -+ default ETRAX_SERIAL_PORT3_NO_DMA_OUT if ETRAX_ARCH_V32 -+ default ETRAX_SERIAL_PORT3_DMA4_OUT if ETRAX_ARCH_V10 -+ -+config ETRAX_SERIAL_PORT3_NO_DMA_OUT -+ bool "Ser3 uses no DMA for output" -+ help -+ Do not use DMA for ser3 output. -+ -+config ETRAX_SERIAL_PORT3_DMA4_OUT -+ depends on ETRAX_ARCH_V10 -+ bool "DMA 4" -+ -+config ETRAX_SERIAL_PORT3_DMA8_OUT -+ bool "Ser3 uses DMA8 for output" -+ depends on ETRAXFS -+ help -+ Enables the DMA8 output channel for ser3 (ttyS3). -+ If you do not enable DMA, an interrupt for each character will be -+ used when transmitting data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+config ETRAX_SERIAL_PORT3_DMA2_OUT -+ bool "Ser3 uses DMA2 for output" -+ depends on CRIS_MACH_ARTPEC3 -+ help -+ Enables the DMA2 output channel for ser3 (ttyS3). -+ If you do not enable DMA, an interrupt for each character will be -+ used when transmitting data. -+ Normally you want to use DMA, unless you use the DMA channel for -+ something else. -+ -+endchoice -+ -+endmenu -+ -+source "drivers/base/Kconfig" -+ -+# standard linux drivers -+source "drivers/mtd/Kconfig" -+ -+source "drivers/parport/Kconfig" -+ -+source "drivers/pnp/Kconfig" -+ -+source "drivers/block/Kconfig" -+ -+source "drivers/ide/Kconfig" -+ -+source "drivers/net/Kconfig" -+ -+source "drivers/i2c/Kconfig" -+ -+source "drivers/rtc/Kconfig" -+ -+# -+# input before char - char/joystick depends on it. As does USB. -+# -+source "drivers/input/Kconfig" -+ -+source "drivers/char/Kconfig" -+ -+source "fs/Kconfig" -+ -+source "drivers/usb/Kconfig" -+ -+source "drivers/uwb/Kconfig" -+ -+source "drivers/staging/Kconfig" -+ -+source "arch/cris/Kconfig.debug" -+ -+source "security/Kconfig" -+ -+source "crypto/Kconfig" -+ -+source "lib/Kconfig" -diff -Nur linux-2.6.39.orig/arch/cris/Makefile linux-2.6.39/arch/cris/Makefile ---- linux-2.6.39.orig/arch/cris/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/Makefile 2011-07-28 16:16:36.883415879 +0200 -@@ -40,10 +40,10 @@ - - LD = $(CROSS_COMPILE)ld -mcrislinux - --OBJCOPYFLAGS := -O binary -R .note -R .comment -S -+OBJCOPYFLAGS := -O binary -R .bss -R .note -R .note.gnu.build-id -R .comment -S - - KBUILD_AFLAGS += -mlinux -march=$(arch-y) $(inc) --KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe $(inc) -+KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe -fno-peephole2 $(inc) - KBUILD_CPPFLAGS += $(inc) - - ifdef CONFIG_FRAME_POINTER -diff -Nur linux-2.6.39.orig/arch/cris/mm/init.c linux-2.6.39/arch/cris/mm/init.c ---- linux-2.6.39.orig/arch/cris/mm/init.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/mm/init.c 2011-07-28 16:16:37.013424379 +0200 -@@ -16,6 +16,7 @@ - DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); - - unsigned long empty_zero_page; -+EXPORT_SYMBOL(empty_zero_page); - - extern char _stext, _edata, _etext; /* From linkerscript */ - extern char __init_begin, __init_end; -@@ -81,3 +82,10 @@ - printk (KERN_INFO "Freeing unused kernel memory: %luk freed\n", - (unsigned long)((&__init_end - &__init_begin) >> 10)); - } -+ -+#ifdef CONFIG_BLK_DEV_INITRD -+void free_initrd_mem(unsigned long start, unsigned long end) -+{ -+ return 0; -+} -+#endif -diff -Nur linux-2.6.39.orig/drivers/net/cris/eth_v10.c linux-2.6.39/drivers/net/cris/eth_v10.c ---- linux-2.6.39.orig/drivers/net/cris/eth_v10.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/cris/eth_v10.c 2011-07-28 16:16:37.184155914 +0200 -@@ -1714,7 +1714,7 @@ - static void - e100_netpoll(struct net_device* netdev) - { -- e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL); -+ e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev); + return 0; } - #endif -diff -Nur linux-2.6.39.orig/drivers/net/cris/eth_v10.c.orig linux-2.6.39/drivers/net/cris/eth_v10.c.orig ---- linux-2.6.39.orig/drivers/net/cris/eth_v10.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/cris/eth_v10.c.orig 2011-05-19 06:06:34.000000000 +0200 -@@ -0,0 +1,1749 @@ -+/* -+ * e100net.c: A network driver for the ETRAX 100LX network controller. -+ * -+ * Copyright (c) 1998-2002 Axis Communications AB. -+ * -+ * The outline of this driver comes from skeleton.c. -+ * -+ */ -+ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include /* DMA and register descriptions */ -+#include /* CRIS_LED_* I/O functions */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+//#define ETHDEBUG -+#define D(x) -+ -+/* -+ * The name of the card. Is used for messages and in the requests for -+ * io regions, irqs and dma channels -+ */ -+ -+static const char* cardname = "ETRAX 100LX built-in ethernet controller"; -+ -+/* A default ethernet address. Highlevel SW will set the real one later */ -+ -+static struct sockaddr default_mac = { -+ 0, -+ { 0x00, 0x40, 0x8C, 0xCD, 0x00, 0x00 } -+}; -+ -+/* Information that need to be kept for each board. */ -+struct net_local { -+ struct mii_if_info mii_if; -+ -+ /* Tx control lock. This protects the transmit buffer ring -+ * state along with the "tx full" state of the driver. This -+ * means all netif_queue flow control actions are protected -+ * by this lock as well. -+ */ -+ spinlock_t lock; -+ -+ spinlock_t led_lock; /* Protect LED state */ -+ spinlock_t transceiver_lock; /* Protect transceiver state. */ -+}; -+ -+typedef struct etrax_eth_descr -+{ -+ etrax_dma_descr descr; -+ struct sk_buff* skb; -+} etrax_eth_descr; -+ -+/* Some transceivers requires special handling */ -+struct transceiver_ops -+{ -+ unsigned int oui; -+ void (*check_speed)(struct net_device* dev); -+ void (*check_duplex)(struct net_device* dev); -+}; -+ -+/* Duplex settings */ -+enum duplex -+{ -+ half, -+ full, -+ autoneg -+}; -+ -+/* Dma descriptors etc. */ -+ -+#define MAX_MEDIA_DATA_SIZE 1522 -+ -+#define MIN_PACKET_LEN 46 -+#define ETHER_HEAD_LEN 14 -+ -+/* -+** MDIO constants. -+*/ -+#define MDIO_START 0x1 -+#define MDIO_READ 0x2 -+#define MDIO_WRITE 0x1 -+#define MDIO_PREAMBLE 0xfffffffful -+ -+/* Broadcom specific */ -+#define MDIO_AUX_CTRL_STATUS_REG 0x18 -+#define MDIO_BC_FULL_DUPLEX_IND 0x1 -+#define MDIO_BC_SPEED 0x2 -+ -+/* TDK specific */ -+#define MDIO_TDK_DIAGNOSTIC_REG 18 -+#define MDIO_TDK_DIAGNOSTIC_RATE 0x400 -+#define MDIO_TDK_DIAGNOSTIC_DPLX 0x800 -+ -+/*Intel LXT972A specific*/ -+#define MDIO_INT_STATUS_REG_2 0x0011 -+#define MDIO_INT_FULL_DUPLEX_IND (1 << 9) -+#define MDIO_INT_SPEED (1 << 14) -+ -+/* Network flash constants */ -+#define NET_FLASH_TIME (HZ/50) /* 20 ms */ -+#define NET_FLASH_PAUSE (HZ/100) /* 10 ms */ -+#define NET_LINK_UP_CHECK_INTERVAL (2*HZ) /* 2 s */ -+#define NET_DUPLEX_CHECK_INTERVAL (2*HZ) /* 2 s */ -+ -+#define NO_NETWORK_ACTIVITY 0 -+#define NETWORK_ACTIVITY 1 -+ -+#define NBR_OF_RX_DESC 32 -+#define NBR_OF_TX_DESC 16 -+ -+/* Large packets are sent directly to upper layers while small packets are */ -+/* copied (to reduce memory waste). The following constant decides the breakpoint */ -+#define RX_COPYBREAK 256 -+ -+/* Due to a chip bug we need to flush the cache when descriptors are returned */ -+/* to the DMA. To decrease performance impact we return descriptors in chunks. */ -+/* The following constant determines the number of descriptors to return. */ -+#define RX_QUEUE_THRESHOLD NBR_OF_RX_DESC/2 -+ -+#define GET_BIT(bit,val) (((val) >> (bit)) & 0x01) -+ -+/* Define some macros to access ETRAX 100 registers */ -+#define SETF(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \ -+ IO_FIELD_(reg##_, field##_, val) -+#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \ -+ IO_STATE_(reg##_, field##_, _##val) -+ -+static etrax_eth_descr *myNextRxDesc; /* Points to the next descriptor to -+ to be processed */ -+static etrax_eth_descr *myLastRxDesc; /* The last processed descriptor */ -+ -+static etrax_eth_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(32))); -+ -+static etrax_eth_descr* myFirstTxDesc; /* First packet not yet sent */ -+static etrax_eth_descr* myLastTxDesc; /* End of send queue */ -+static etrax_eth_descr* myNextTxDesc; /* Next descriptor to use */ -+static etrax_eth_descr TxDescList[NBR_OF_TX_DESC] __attribute__ ((aligned(32))); -+ -+static unsigned int network_rec_config_shadow = 0; -+ -+static unsigned int network_tr_ctrl_shadow = 0; -+ -+/* Network speed indication. */ -+static DEFINE_TIMER(speed_timer, NULL, 0, 0); -+static DEFINE_TIMER(clear_led_timer, NULL, 0, 0); -+static int current_speed; /* Speed read from transceiver */ -+static int current_speed_selection; /* Speed selected by user */ -+static unsigned long led_next_time; -+static int led_active; -+static int rx_queue_len; -+ -+/* Duplex */ -+static DEFINE_TIMER(duplex_timer, NULL, 0, 0); -+static int full_duplex; -+static enum duplex current_duplex; -+ -+/* Index to functions, as function prototypes. */ -+ -+static int etrax_ethernet_init(void); -+ -+static int e100_open(struct net_device *dev); -+static int e100_set_mac_address(struct net_device *dev, void *addr); -+static int e100_send_packet(struct sk_buff *skb, struct net_device *dev); -+static irqreturn_t e100rxtx_interrupt(int irq, void *dev_id); -+static irqreturn_t e100nw_interrupt(int irq, void *dev_id); -+static void e100_rx(struct net_device *dev); -+static int e100_close(struct net_device *dev); -+static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -+static int e100_set_config(struct net_device* dev, struct ifmap* map); -+static void e100_tx_timeout(struct net_device *dev); -+static struct net_device_stats *e100_get_stats(struct net_device *dev); -+static void set_multicast_list(struct net_device *dev); -+static void e100_hardware_send_packet(struct net_local* np, char *buf, int length); -+static void update_rx_stats(struct net_device_stats *); -+static void update_tx_stats(struct net_device_stats *); -+static int e100_probe_transceiver(struct net_device* dev); -+ -+static void e100_check_speed(unsigned long priv); -+static void e100_set_speed(struct net_device* dev, unsigned long speed); -+static void e100_check_duplex(unsigned long priv); -+static void e100_set_duplex(struct net_device* dev, enum duplex); -+static void e100_negotiate(struct net_device* dev); -+ -+static int e100_get_mdio_reg(struct net_device *dev, int phy_id, int location); -+static void e100_set_mdio_reg(struct net_device *dev, int phy_id, int location, int value); -+ -+static void e100_send_mdio_cmd(unsigned short cmd, int write_cmd); -+static void e100_send_mdio_bit(unsigned char bit); -+static unsigned char e100_receive_mdio_bit(void); -+static void e100_reset_transceiver(struct net_device* net); -+ -+static void e100_clear_network_leds(unsigned long dummy); -+static void e100_set_network_leds(int active); -+ -+static const struct ethtool_ops e100_ethtool_ops; -+#if defined(CONFIG_ETRAX_NO_PHY) -+static void dummy_check_speed(struct net_device* dev); -+static void dummy_check_duplex(struct net_device* dev); -+#else -+static void broadcom_check_speed(struct net_device* dev); -+static void broadcom_check_duplex(struct net_device* dev); -+static void tdk_check_speed(struct net_device* dev); -+static void tdk_check_duplex(struct net_device* dev); -+static void intel_check_speed(struct net_device* dev); -+static void intel_check_duplex(struct net_device* dev); -+static void generic_check_speed(struct net_device* dev); -+static void generic_check_duplex(struct net_device* dev); -+#endif -+#ifdef CONFIG_NET_POLL_CONTROLLER -+static void e100_netpoll(struct net_device* dev); -+#endif -+ -+static int autoneg_normal = 1; -+ -+struct transceiver_ops transceivers[] = -+{ -+#if defined(CONFIG_ETRAX_NO_PHY) -+ {0x0000, dummy_check_speed, dummy_check_duplex} /* Dummy */ -+#else -+ {0x1018, broadcom_check_speed, broadcom_check_duplex}, /* Broadcom */ -+ {0xC039, tdk_check_speed, tdk_check_duplex}, /* TDK 2120 */ -+ {0x039C, tdk_check_speed, tdk_check_duplex}, /* TDK 2120C */ -+ {0x04de, intel_check_speed, intel_check_duplex}, /* Intel LXT972A*/ -+ {0x0000, generic_check_speed, generic_check_duplex} /* Generic, must be last */ -+#endif -+}; -+ -+struct transceiver_ops* transceiver = &transceivers[0]; -+ -+static const struct net_device_ops e100_netdev_ops = { -+ .ndo_open = e100_open, -+ .ndo_stop = e100_close, -+ .ndo_start_xmit = e100_send_packet, -+ .ndo_tx_timeout = e100_tx_timeout, -+ .ndo_get_stats = e100_get_stats, -+ .ndo_set_multicast_list = set_multicast_list, -+ .ndo_do_ioctl = e100_ioctl, -+ .ndo_set_mac_address = e100_set_mac_address, -+ .ndo_validate_addr = eth_validate_addr, -+ .ndo_change_mtu = eth_change_mtu, -+ .ndo_set_config = e100_set_config, -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ .ndo_poll_controller = e100_netpoll, -+#endif -+}; -+ -+#define tx_done(dev) (*R_DMA_CH0_CMD == 0) -+ -+/* -+ * Check for a network adaptor of this type, and return '0' if one exists. -+ * If dev->base_addr == 0, probe all likely locations. -+ * If dev->base_addr == 1, always return failure. -+ * If dev->base_addr == 2, allocate space for the device and return success -+ * (detachable devices only). -+ */ -+ -+static int __init -+etrax_ethernet_init(void) -+{ -+ struct net_device *dev; -+ struct net_local* np; -+ int i, err; -+ -+ printk(KERN_INFO -+ "ETRAX 100LX 10/100MBit ethernet v2.0 (c) 1998-2007 Axis Communications AB\n"); -+ -+ if (cris_request_io_interface(if_eth, cardname)) { -+ printk(KERN_CRIT "etrax_ethernet_init failed to get IO interface\n"); -+ return -EBUSY; -+ } -+ -+ dev = alloc_etherdev(sizeof(struct net_local)); -+ if (!dev) -+ return -ENOMEM; -+ -+ np = netdev_priv(dev); -+ -+ /* we do our own locking */ -+ dev->features |= NETIF_F_LLTX; -+ -+ dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */ -+ -+ /* now setup our etrax specific stuff */ -+ -+ dev->irq = NETWORK_DMA_RX_IRQ_NBR; /* we really use DMATX as well... */ -+ dev->dma = NETWORK_RX_DMA_NBR; -+ -+ /* fill in our handlers so the network layer can talk to us in the future */ -+ -+ dev->ethtool_ops = &e100_ethtool_ops; -+ dev->netdev_ops = &e100_netdev_ops; -+ -+ spin_lock_init(&np->lock); -+ spin_lock_init(&np->led_lock); -+ spin_lock_init(&np->transceiver_lock); -+ -+ /* Initialise the list of Etrax DMA-descriptors */ -+ -+ /* Initialise receive descriptors */ -+ -+ for (i = 0; i < NBR_OF_RX_DESC; i++) { -+ /* Allocate two extra cachelines to make sure that buffer used -+ * by DMA does not share cacheline with any other data (to -+ * avoid cache bug) -+ */ -+ RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); -+ if (!RxDescList[i].skb) -+ return -ENOMEM; -+ RxDescList[i].descr.ctrl = 0; -+ RxDescList[i].descr.sw_len = MAX_MEDIA_DATA_SIZE; -+ RxDescList[i].descr.next = virt_to_phys(&RxDescList[i + 1]); -+ RxDescList[i].descr.buf = L1_CACHE_ALIGN(virt_to_phys(RxDescList[i].skb->data)); -+ RxDescList[i].descr.status = 0; -+ RxDescList[i].descr.hw_len = 0; -+ prepare_rx_descriptor(&RxDescList[i].descr); -+ } -+ -+ RxDescList[NBR_OF_RX_DESC - 1].descr.ctrl = d_eol; -+ RxDescList[NBR_OF_RX_DESC - 1].descr.next = virt_to_phys(&RxDescList[0]); -+ rx_queue_len = 0; -+ -+ /* Initialize transmit descriptors */ -+ for (i = 0; i < NBR_OF_TX_DESC; i++) { -+ TxDescList[i].descr.ctrl = 0; -+ TxDescList[i].descr.sw_len = 0; -+ TxDescList[i].descr.next = virt_to_phys(&TxDescList[i + 1].descr); -+ TxDescList[i].descr.buf = 0; -+ TxDescList[i].descr.status = 0; -+ TxDescList[i].descr.hw_len = 0; -+ TxDescList[i].skb = 0; -+ } -+ -+ TxDescList[NBR_OF_TX_DESC - 1].descr.ctrl = d_eol; -+ TxDescList[NBR_OF_TX_DESC - 1].descr.next = virt_to_phys(&TxDescList[0].descr); -+ -+ /* Initialise initial pointers */ -+ -+ myNextRxDesc = &RxDescList[0]; -+ myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1]; -+ myFirstTxDesc = &TxDescList[0]; -+ myNextTxDesc = &TxDescList[0]; -+ myLastTxDesc = &TxDescList[NBR_OF_TX_DESC - 1]; -+ -+ /* Register device */ -+ err = register_netdev(dev); -+ if (err) { -+ free_netdev(dev); -+ return err; -+ } -+ -+ /* set the default MAC address */ -+ -+ e100_set_mac_address(dev, &default_mac); -+ -+ /* Initialize speed indicator stuff. */ -+ -+ current_speed = 10; -+ current_speed_selection = 0; /* Auto */ -+ speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; -+ speed_timer.data = (unsigned long)dev; -+ speed_timer.function = e100_check_speed; -+ -+ clear_led_timer.function = e100_clear_network_leds; -+ clear_led_timer.data = (unsigned long)dev; -+ -+ full_duplex = 0; -+ current_duplex = autoneg; -+ duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL; -+ duplex_timer.data = (unsigned long)dev; -+ duplex_timer.function = e100_check_duplex; -+ -+ /* Initialize mii interface */ -+ np->mii_if.phy_id_mask = 0x1f; -+ np->mii_if.reg_num_mask = 0x1f; -+ np->mii_if.dev = dev; -+ np->mii_if.mdio_read = e100_get_mdio_reg; -+ np->mii_if.mdio_write = e100_set_mdio_reg; -+ -+ /* Initialize group address registers to make sure that no */ -+ /* unwanted addresses are matched */ -+ *R_NETWORK_GA_0 = 0x00000000; -+ *R_NETWORK_GA_1 = 0x00000000; -+ -+ /* Initialize next time the led can flash */ -+ led_next_time = jiffies; -+ return 0; -+} -+ -+/* set MAC address of the interface. called from the core after a -+ * SIOCSIFADDR ioctl, and from the bootup above. -+ */ -+ -+static int -+e100_set_mac_address(struct net_device *dev, void *p) -+{ -+ struct net_local *np = netdev_priv(dev); -+ struct sockaddr *addr = p; -+ -+ spin_lock(&np->lock); /* preemption protection */ -+ -+ /* remember it */ -+ -+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); -+ -+ /* Write it to the hardware. -+ * Note the way the address is wrapped: -+ * *R_NETWORK_SA_0 = a0_0 | (a0_1 << 8) | (a0_2 << 16) | (a0_3 << 24); -+ * *R_NETWORK_SA_1 = a0_4 | (a0_5 << 8); -+ */ -+ -+ *R_NETWORK_SA_0 = dev->dev_addr[0] | (dev->dev_addr[1] << 8) | -+ (dev->dev_addr[2] << 16) | (dev->dev_addr[3] << 24); -+ *R_NETWORK_SA_1 = dev->dev_addr[4] | (dev->dev_addr[5] << 8); -+ *R_NETWORK_SA_2 = 0; -+ -+ /* show it in the log as well */ -+ -+ printk(KERN_INFO "%s: changed MAC to %pM\n", dev->name, dev->dev_addr); -+ -+ spin_unlock(&np->lock); -+ -+ return 0; -+} -+ -+/* -+ * Open/initialize the board. This is called (in the current kernel) -+ * sometime after booting when the 'ifconfig' program is run. -+ * -+ * This routine should set everything up anew at each open, even -+ * registers that "should" only need to be set once at boot, so that -+ * there is non-reboot way to recover if something goes wrong. -+ */ -+ -+static int -+e100_open(struct net_device *dev) -+{ -+ unsigned long flags; -+ -+ /* enable the MDIO output pin */ -+ -+ *R_NETWORK_MGM_CTRL = IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable); -+ -+ *R_IRQ_MASK0_CLR = -+ IO_STATE(R_IRQ_MASK0_CLR, overrun, clr) | -+ IO_STATE(R_IRQ_MASK0_CLR, underrun, clr) | -+ IO_STATE(R_IRQ_MASK0_CLR, excessive_col, clr); -+ -+ /* clear dma0 and 1 eop and descr irq masks */ -+ *R_IRQ_MASK2_CLR = -+ IO_STATE(R_IRQ_MASK2_CLR, dma0_descr, clr) | -+ IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) | -+ IO_STATE(R_IRQ_MASK2_CLR, dma1_descr, clr) | -+ IO_STATE(R_IRQ_MASK2_CLR, dma1_eop, clr); -+ -+ /* Reset and wait for the DMA channels */ -+ -+ RESET_DMA(NETWORK_TX_DMA_NBR); -+ RESET_DMA(NETWORK_RX_DMA_NBR); -+ WAIT_DMA(NETWORK_TX_DMA_NBR); -+ WAIT_DMA(NETWORK_RX_DMA_NBR); -+ -+ /* Initialise the etrax network controller */ -+ -+ /* allocate the irq corresponding to the receiving DMA */ -+ -+ if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt, -+ IRQF_SAMPLE_RANDOM, cardname, (void *)dev)) { -+ goto grace_exit0; -+ } -+ -+ /* allocate the irq corresponding to the transmitting DMA */ -+ -+ if (request_irq(NETWORK_DMA_TX_IRQ_NBR, e100rxtx_interrupt, 0, -+ cardname, (void *)dev)) { -+ goto grace_exit1; -+ } -+ -+ /* allocate the irq corresponding to the network errors etc */ -+ -+ if (request_irq(NETWORK_STATUS_IRQ_NBR, e100nw_interrupt, 0, -+ cardname, (void *)dev)) { -+ goto grace_exit2; -+ } -+ -+ /* -+ * Always allocate the DMA channels after the IRQ, -+ * and clean up on failure. -+ */ -+ -+ if (cris_request_dma(NETWORK_TX_DMA_NBR, -+ cardname, -+ DMA_VERBOSE_ON_ERROR, -+ dma_eth)) { -+ goto grace_exit3; -+ } -+ -+ if (cris_request_dma(NETWORK_RX_DMA_NBR, -+ cardname, -+ DMA_VERBOSE_ON_ERROR, -+ dma_eth)) { -+ goto grace_exit4; -+ } -+ -+ /* give the HW an idea of what MAC address we want */ -+ -+ *R_NETWORK_SA_0 = dev->dev_addr[0] | (dev->dev_addr[1] << 8) | -+ (dev->dev_addr[2] << 16) | (dev->dev_addr[3] << 24); -+ *R_NETWORK_SA_1 = dev->dev_addr[4] | (dev->dev_addr[5] << 8); -+ *R_NETWORK_SA_2 = 0; -+ -+#if 0 -+ /* use promiscuous mode for testing */ -+ *R_NETWORK_GA_0 = 0xffffffff; -+ *R_NETWORK_GA_1 = 0xffffffff; -+ -+ *R_NETWORK_REC_CONFIG = 0xd; /* broadcast rec, individ. rec, ma0 enabled */ -+#else -+ SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, max_size, size1522); -+ SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, broadcast, receive); -+ SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, ma0, enable); -+ SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex); -+ *R_NETWORK_REC_CONFIG = network_rec_config_shadow; -+#endif -+ -+ *R_NETWORK_GEN_CONFIG = -+ IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk) | -+ IO_STATE(R_NETWORK_GEN_CONFIG, enable, on); -+ -+ SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr); -+ SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, delay, none); -+ SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, cancel, dont); -+ SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, cd, enable); -+ SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, retry, enable); -+ SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, pad, enable); -+ SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, crc, enable); -+ *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; -+ -+ local_irq_save(flags); -+ -+ /* enable the irq's for ethernet DMA */ -+ -+ *R_IRQ_MASK2_SET = -+ IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) | -+ IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set); -+ -+ *R_IRQ_MASK0_SET = -+ IO_STATE(R_IRQ_MASK0_SET, overrun, set) | -+ IO_STATE(R_IRQ_MASK0_SET, underrun, set) | -+ IO_STATE(R_IRQ_MASK0_SET, excessive_col, set); -+ -+ /* make sure the irqs are cleared */ -+ -+ *R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do); -+ *R_DMA_CH1_CLR_INTR = IO_STATE(R_DMA_CH1_CLR_INTR, clr_eop, do); -+ -+ /* make sure the rec and transmit error counters are cleared */ -+ -+ (void)*R_REC_COUNTERS; /* dummy read */ -+ (void)*R_TR_COUNTERS; /* dummy read */ -+ -+ /* start the receiving DMA channel so we can receive packets from now on */ -+ -+ *R_DMA_CH1_FIRST = virt_to_phys(myNextRxDesc); -+ *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, start); -+ -+ /* Set up transmit DMA channel so it can be restarted later */ -+ -+ *R_DMA_CH0_FIRST = 0; -+ *R_DMA_CH0_DESCR = virt_to_phys(myLastTxDesc); -+ netif_start_queue(dev); -+ -+ local_irq_restore(flags); -+ -+ /* Probe for transceiver */ -+ if (e100_probe_transceiver(dev)) -+ goto grace_exit5; -+ -+ /* Start duplex/speed timers */ -+ add_timer(&speed_timer); -+ add_timer(&duplex_timer); -+ -+ /* We are now ready to accept transmit requeusts from -+ * the queueing layer of the networking. -+ */ -+ netif_carrier_on(dev); -+ -+ return 0; -+ -+grace_exit5: -+ cris_free_dma(NETWORK_RX_DMA_NBR, cardname); -+grace_exit4: -+ cris_free_dma(NETWORK_TX_DMA_NBR, cardname); -+grace_exit3: -+ free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev); -+grace_exit2: -+ free_irq(NETWORK_DMA_TX_IRQ_NBR, (void *)dev); -+grace_exit1: -+ free_irq(NETWORK_DMA_RX_IRQ_NBR, (void *)dev); -+grace_exit0: -+ return -EAGAIN; -+} -+ -+#if defined(CONFIG_ETRAX_NO_PHY) -+static void -+dummy_check_speed(struct net_device* dev) -+{ -+ current_speed = 100; -+} -+#else -+static void -+generic_check_speed(struct net_device* dev) -+{ -+ unsigned long data; -+ struct net_local *np = netdev_priv(dev); -+ -+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE); -+ if ((data & ADVERTISE_100FULL) || -+ (data & ADVERTISE_100HALF)) -+ current_speed = 100; -+ else -+ current_speed = 10; -+} -+ -+static void -+tdk_check_speed(struct net_device* dev) -+{ -+ unsigned long data; -+ struct net_local *np = netdev_priv(dev); -+ -+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, -+ MDIO_TDK_DIAGNOSTIC_REG); -+ current_speed = (data & MDIO_TDK_DIAGNOSTIC_RATE ? 100 : 10); -+} -+ -+static void -+broadcom_check_speed(struct net_device* dev) -+{ -+ unsigned long data; -+ struct net_local *np = netdev_priv(dev); -+ -+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, -+ MDIO_AUX_CTRL_STATUS_REG); -+ current_speed = (data & MDIO_BC_SPEED ? 100 : 10); -+} -+ -+static void -+intel_check_speed(struct net_device* dev) -+{ -+ unsigned long data; -+ struct net_local *np = netdev_priv(dev); -+ -+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, -+ MDIO_INT_STATUS_REG_2); -+ current_speed = (data & MDIO_INT_SPEED ? 100 : 10); -+} -+#endif -+static void -+e100_check_speed(unsigned long priv) -+{ -+ struct net_device* dev = (struct net_device*)priv; -+ struct net_local *np = netdev_priv(dev); -+ static int led_initiated = 0; -+ unsigned long data; -+ int old_speed = current_speed; -+ -+ spin_lock(&np->transceiver_lock); -+ -+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMSR); -+ if (!(data & BMSR_LSTATUS)) { -+ current_speed = 0; -+ } else { -+ transceiver->check_speed(dev); -+ } -+ -+ spin_lock(&np->led_lock); -+ if ((old_speed != current_speed) || !led_initiated) { -+ led_initiated = 1; -+ e100_set_network_leds(NO_NETWORK_ACTIVITY); -+ if (current_speed) -+ netif_carrier_on(dev); -+ else -+ netif_carrier_off(dev); -+ } -+ spin_unlock(&np->led_lock); -+ -+ /* Reinitialize the timer. */ -+ speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; -+ add_timer(&speed_timer); -+ -+ spin_unlock(&np->transceiver_lock); -+} -+ -+static void -+e100_negotiate(struct net_device* dev) -+{ -+ struct net_local *np = netdev_priv(dev); -+ unsigned short data = e100_get_mdio_reg(dev, np->mii_if.phy_id, -+ MII_ADVERTISE); -+ -+ /* Discard old speed and duplex settings */ -+ data &= ~(ADVERTISE_100HALF | ADVERTISE_100FULL | -+ ADVERTISE_10HALF | ADVERTISE_10FULL); -+ -+ switch (current_speed_selection) { -+ case 10: -+ if (current_duplex == full) -+ data |= ADVERTISE_10FULL; -+ else if (current_duplex == half) -+ data |= ADVERTISE_10HALF; -+ else -+ data |= ADVERTISE_10HALF | ADVERTISE_10FULL; -+ break; -+ -+ case 100: -+ if (current_duplex == full) -+ data |= ADVERTISE_100FULL; -+ else if (current_duplex == half) -+ data |= ADVERTISE_100HALF; -+ else -+ data |= ADVERTISE_100HALF | ADVERTISE_100FULL; -+ break; -+ -+ case 0: /* Auto */ -+ if (current_duplex == full) -+ data |= ADVERTISE_100FULL | ADVERTISE_10FULL; -+ else if (current_duplex == half) -+ data |= ADVERTISE_100HALF | ADVERTISE_10HALF; -+ else -+ data |= ADVERTISE_10HALF | ADVERTISE_10FULL | -+ ADVERTISE_100HALF | ADVERTISE_100FULL; -+ break; -+ -+ default: /* assume autoneg speed and duplex */ -+ data |= ADVERTISE_10HALF | ADVERTISE_10FULL | -+ ADVERTISE_100HALF | ADVERTISE_100FULL; -+ break; -+ } -+ -+ e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE, data); -+ -+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR); -+ if (autoneg_normal) { -+ /* Renegotiate with link partner */ -+ data |= BMCR_ANENABLE | BMCR_ANRESTART; -+ } else { -+ /* Don't negotiate speed or duplex */ -+ data &= ~(BMCR_ANENABLE | BMCR_ANRESTART); -+ -+ /* Set speed and duplex static */ -+ if (current_speed_selection == 10) -+ data &= ~BMCR_SPEED100; -+ else -+ data |= BMCR_SPEED100; -+ -+ if (current_duplex != full) -+ data &= ~BMCR_FULLDPLX; -+ else -+ data |= BMCR_FULLDPLX; -+ } -+ e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR, data); -+} -+ -+static void -+e100_set_speed(struct net_device* dev, unsigned long speed) -+{ -+ struct net_local *np = netdev_priv(dev); -+ -+ spin_lock(&np->transceiver_lock); -+ if (speed != current_speed_selection) { -+ current_speed_selection = speed; -+ e100_negotiate(dev); -+ } -+ spin_unlock(&np->transceiver_lock); -+} -+ -+static void -+e100_check_duplex(unsigned long priv) -+{ -+ struct net_device *dev = (struct net_device *)priv; -+ struct net_local *np = netdev_priv(dev); -+ int old_duplex; -+ -+ spin_lock(&np->transceiver_lock); -+ old_duplex = full_duplex; -+ transceiver->check_duplex(dev); -+ if (old_duplex != full_duplex) { -+ /* Duplex changed */ -+ SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex); -+ *R_NETWORK_REC_CONFIG = network_rec_config_shadow; -+ } -+ -+ /* Reinitialize the timer. */ -+ duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL; -+ add_timer(&duplex_timer); -+ np->mii_if.full_duplex = full_duplex; -+ spin_unlock(&np->transceiver_lock); -+} -+#if defined(CONFIG_ETRAX_NO_PHY) -+static void -+dummy_check_duplex(struct net_device* dev) -+{ -+ full_duplex = 1; -+} -+#else -+static void -+generic_check_duplex(struct net_device* dev) -+{ -+ unsigned long data; -+ struct net_local *np = netdev_priv(dev); -+ -+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE); -+ if ((data & ADVERTISE_10FULL) || -+ (data & ADVERTISE_100FULL)) -+ full_duplex = 1; -+ else -+ full_duplex = 0; -+} -+ -+static void -+tdk_check_duplex(struct net_device* dev) -+{ -+ unsigned long data; -+ struct net_local *np = netdev_priv(dev); -+ -+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, -+ MDIO_TDK_DIAGNOSTIC_REG); -+ full_duplex = (data & MDIO_TDK_DIAGNOSTIC_DPLX) ? 1 : 0; -+} -+ -+static void -+broadcom_check_duplex(struct net_device* dev) -+{ -+ unsigned long data; -+ struct net_local *np = netdev_priv(dev); -+ -+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, -+ MDIO_AUX_CTRL_STATUS_REG); -+ full_duplex = (data & MDIO_BC_FULL_DUPLEX_IND) ? 1 : 0; -+} -+ -+static void -+intel_check_duplex(struct net_device* dev) -+{ -+ unsigned long data; -+ struct net_local *np = netdev_priv(dev); -+ -+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, -+ MDIO_INT_STATUS_REG_2); -+ full_duplex = (data & MDIO_INT_FULL_DUPLEX_IND) ? 1 : 0; -+} -+#endif -+static void -+e100_set_duplex(struct net_device* dev, enum duplex new_duplex) -+{ -+ struct net_local *np = netdev_priv(dev); -+ -+ spin_lock(&np->transceiver_lock); -+ if (new_duplex != current_duplex) { -+ current_duplex = new_duplex; -+ e100_negotiate(dev); -+ } -+ spin_unlock(&np->transceiver_lock); -+} -+ -+static int -+e100_probe_transceiver(struct net_device* dev) -+{ -+ int ret = 0; -+ -+#if !defined(CONFIG_ETRAX_NO_PHY) -+ unsigned int phyid_high; -+ unsigned int phyid_low; -+ unsigned int oui; -+ struct transceiver_ops* ops = NULL; -+ struct net_local *np = netdev_priv(dev); -+ -+ spin_lock(&np->transceiver_lock); -+ -+ /* Probe MDIO physical address */ -+ for (np->mii_if.phy_id = 0; np->mii_if.phy_id <= 31; -+ np->mii_if.phy_id++) { -+ if (e100_get_mdio_reg(dev, -+ np->mii_if.phy_id, MII_BMSR) != 0xffff) -+ break; -+ } -+ if (np->mii_if.phy_id == 32) { -+ ret = -ENODEV; -+ goto out; -+ } -+ -+ /* Get manufacturer */ -+ phyid_high = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_PHYSID1); -+ phyid_low = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_PHYSID2); -+ oui = (phyid_high << 6) | (phyid_low >> 10); -+ -+ for (ops = &transceivers[0]; ops->oui; ops++) { -+ if (ops->oui == oui) -+ break; -+ } -+ transceiver = ops; -+out: -+ spin_unlock(&np->transceiver_lock); -+#endif -+ return ret; -+} -+ -+static int -+e100_get_mdio_reg(struct net_device *dev, int phy_id, int location) -+{ -+ unsigned short cmd; /* Data to be sent on MDIO port */ -+ int data; /* Data read from MDIO */ -+ int bitCounter; -+ -+ /* Start of frame, OP Code, Physical Address, Register Address */ -+ cmd = (MDIO_START << 14) | (MDIO_READ << 12) | (phy_id << 7) | -+ (location << 2); -+ -+ e100_send_mdio_cmd(cmd, 0); -+ -+ data = 0; -+ -+ /* Data... */ -+ for (bitCounter=15; bitCounter>=0 ; bitCounter--) { -+ data |= (e100_receive_mdio_bit() << bitCounter); -+ } -+ -+ return data; -+} -+ -+static void -+e100_set_mdio_reg(struct net_device *dev, int phy_id, int location, int value) -+{ -+ int bitCounter; -+ unsigned short cmd; -+ -+ cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (phy_id << 7) | -+ (location << 2); -+ -+ e100_send_mdio_cmd(cmd, 1); -+ -+ /* Data... */ -+ for (bitCounter=15; bitCounter>=0 ; bitCounter--) { -+ e100_send_mdio_bit(GET_BIT(bitCounter, value)); -+ } -+ -+} -+ -+static void -+e100_send_mdio_cmd(unsigned short cmd, int write_cmd) -+{ -+ int bitCounter; -+ unsigned char data = 0x2; -+ -+ /* Preamble */ -+ for (bitCounter = 31; bitCounter>= 0; bitCounter--) -+ e100_send_mdio_bit(GET_BIT(bitCounter, MDIO_PREAMBLE)); -+ -+ for (bitCounter = 15; bitCounter >= 2; bitCounter--) -+ e100_send_mdio_bit(GET_BIT(bitCounter, cmd)); -+ -+ /* Turnaround */ -+ for (bitCounter = 1; bitCounter >= 0 ; bitCounter--) -+ if (write_cmd) -+ e100_send_mdio_bit(GET_BIT(bitCounter, data)); -+ else -+ e100_receive_mdio_bit(); -+} -+ -+static void -+e100_send_mdio_bit(unsigned char bit) -+{ -+ *R_NETWORK_MGM_CTRL = -+ IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable) | -+ IO_FIELD(R_NETWORK_MGM_CTRL, mdio, bit); -+ udelay(1); -+ *R_NETWORK_MGM_CTRL = -+ IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable) | -+ IO_MASK(R_NETWORK_MGM_CTRL, mdck) | -+ IO_FIELD(R_NETWORK_MGM_CTRL, mdio, bit); -+ udelay(1); -+} -+ -+static unsigned char -+e100_receive_mdio_bit() -+{ -+ unsigned char bit; -+ *R_NETWORK_MGM_CTRL = 0; -+ bit = IO_EXTRACT(R_NETWORK_STAT, mdio, *R_NETWORK_STAT); -+ udelay(1); -+ *R_NETWORK_MGM_CTRL = IO_MASK(R_NETWORK_MGM_CTRL, mdck); -+ udelay(1); -+ return bit; -+} -+ -+static void -+e100_reset_transceiver(struct net_device* dev) -+{ -+ struct net_local *np = netdev_priv(dev); -+ unsigned short cmd; -+ unsigned short data; -+ int bitCounter; -+ -+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR); -+ -+ cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (np->mii_if.phy_id << 7) | (MII_BMCR << 2); -+ -+ e100_send_mdio_cmd(cmd, 1); -+ -+ data |= 0x8000; -+ -+ for (bitCounter = 15; bitCounter >= 0 ; bitCounter--) { -+ e100_send_mdio_bit(GET_BIT(bitCounter, data)); -+ } -+} -+ -+/* Called by upper layers if they decide it took too long to complete -+ * sending a packet - we need to reset and stuff. -+ */ -+ -+static void -+e100_tx_timeout(struct net_device *dev) -+{ -+ struct net_local *np = netdev_priv(dev); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&np->lock, flags); -+ -+ printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, -+ tx_done(dev) ? "IRQ problem" : "network cable problem"); -+ -+ /* remember we got an error */ -+ -+ dev->stats.tx_errors++; -+ -+ /* reset the TX DMA in case it has hung on something */ -+ -+ RESET_DMA(NETWORK_TX_DMA_NBR); -+ WAIT_DMA(NETWORK_TX_DMA_NBR); -+ -+ /* Reset the transceiver. */ -+ -+ e100_reset_transceiver(dev); -+ -+ /* and get rid of the packets that never got an interrupt */ -+ while (myFirstTxDesc != myNextTxDesc) { -+ dev_kfree_skb(myFirstTxDesc->skb); -+ myFirstTxDesc->skb = 0; -+ myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next); -+ } -+ -+ /* Set up transmit DMA channel so it can be restarted later */ -+ *R_DMA_CH0_FIRST = 0; -+ *R_DMA_CH0_DESCR = virt_to_phys(myLastTxDesc); -+ -+ /* tell the upper layers we're ok again */ -+ -+ netif_wake_queue(dev); -+ spin_unlock_irqrestore(&np->lock, flags); -+} -+ -+ -+/* This will only be invoked if the driver is _not_ in XOFF state. -+ * What this means is that we need not check it, and that this -+ * invariant will hold if we make sure that the netif_*_queue() -+ * calls are done at the proper times. -+ */ -+ -+static int -+e100_send_packet(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct net_local *np = netdev_priv(dev); -+ unsigned char *buf = skb->data; -+ unsigned long flags; -+ -+#ifdef ETHDEBUG -+ printk("send packet len %d\n", length); -+#endif -+ spin_lock_irqsave(&np->lock, flags); /* protect from tx_interrupt and ourself */ -+ -+ myNextTxDesc->skb = skb; -+ -+ dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ -+ -+ e100_hardware_send_packet(np, buf, skb->len); -+ -+ myNextTxDesc = phys_to_virt(myNextTxDesc->descr.next); -+ -+ /* Stop queue if full */ -+ if (myNextTxDesc == myFirstTxDesc) { -+ netif_stop_queue(dev); -+ } -+ -+ spin_unlock_irqrestore(&np->lock, flags); -+ -+ return NETDEV_TX_OK; -+} -+ -+/* -+ * The typical workload of the driver: -+ * Handle the network interface interrupts. -+ */ -+ -+static irqreturn_t -+e100rxtx_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *dev = (struct net_device *)dev_id; -+ struct net_local *np = netdev_priv(dev); -+ unsigned long irqbits; -+ -+ /* -+ * Note that both rx and tx interrupts are blocked at this point, -+ * regardless of which got us here. -+ */ -+ -+ irqbits = *R_IRQ_MASK2_RD; -+ -+ /* Handle received packets */ -+ if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma1_eop, active)) { -+ /* acknowledge the eop interrupt */ -+ -+ *R_DMA_CH1_CLR_INTR = IO_STATE(R_DMA_CH1_CLR_INTR, clr_eop, do); -+ -+ /* check if one or more complete packets were indeed received */ -+ -+ while ((*R_DMA_CH1_FIRST != virt_to_phys(myNextRxDesc)) && -+ (myNextRxDesc != myLastRxDesc)) { -+ /* Take out the buffer and give it to the OS, then -+ * allocate a new buffer to put a packet in. -+ */ -+ e100_rx(dev); -+ dev->stats.rx_packets++; -+ /* restart/continue on the channel, for safety */ -+ *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, restart); -+ /* clear dma channel 1 eop/descr irq bits */ -+ *R_DMA_CH1_CLR_INTR = -+ IO_STATE(R_DMA_CH1_CLR_INTR, clr_eop, do) | -+ IO_STATE(R_DMA_CH1_CLR_INTR, clr_descr, do); -+ -+ /* now, we might have gotten another packet -+ so we have to loop back and check if so */ -+ } -+ } -+ -+ /* Report any packets that have been sent */ -+ while (virt_to_phys(myFirstTxDesc) != *R_DMA_CH0_FIRST && -+ (netif_queue_stopped(dev) || myFirstTxDesc != myNextTxDesc)) { -+ dev->stats.tx_bytes += myFirstTxDesc->skb->len; -+ dev->stats.tx_packets++; -+ -+ /* dma is ready with the transmission of the data in tx_skb, so now -+ we can release the skb memory */ -+ dev_kfree_skb_irq(myFirstTxDesc->skb); -+ myFirstTxDesc->skb = 0; -+ myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next); -+ /* Wake up queue. */ -+ netif_wake_queue(dev); -+ } -+ -+ if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, active)) { -+ /* acknowledge the eop interrupt. */ -+ *R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t -+e100nw_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *dev = (struct net_device *)dev_id; -+ unsigned long irqbits = *R_IRQ_MASK0_RD; -+ -+ /* check for underrun irq */ -+ if (irqbits & IO_STATE(R_IRQ_MASK0_RD, underrun, active)) { -+ SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr); -+ *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; -+ SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop); -+ dev->stats.tx_errors++; -+ D(printk("ethernet receiver underrun!\n")); -+ } -+ -+ /* check for overrun irq */ -+ if (irqbits & IO_STATE(R_IRQ_MASK0_RD, overrun, active)) { -+ update_rx_stats(&dev->stats); /* this will ack the irq */ -+ D(printk("ethernet receiver overrun!\n")); -+ } -+ /* check for excessive collision irq */ -+ if (irqbits & IO_STATE(R_IRQ_MASK0_RD, excessive_col, active)) { -+ SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr); -+ *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; -+ SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop); -+ dev->stats.tx_errors++; -+ D(printk("ethernet excessive collisions!\n")); -+ } -+ return IRQ_HANDLED; -+} -+ -+/* We have a good packet(s), get it/them out of the buffers. */ -+static void -+e100_rx(struct net_device *dev) -+{ -+ struct sk_buff *skb; -+ int length = 0; -+ struct net_local *np = netdev_priv(dev); -+ unsigned char *skb_data_ptr; -+#ifdef ETHDEBUG -+ int i; -+#endif -+ etrax_eth_descr *prevRxDesc; /* The descriptor right before myNextRxDesc */ -+ spin_lock(&np->led_lock); -+ if (!led_active && time_after(jiffies, led_next_time)) { -+ /* light the network leds depending on the current speed. */ -+ e100_set_network_leds(NETWORK_ACTIVITY); -+ -+ /* Set the earliest time we may clear the LED */ -+ led_next_time = jiffies + NET_FLASH_TIME; -+ led_active = 1; -+ mod_timer(&clear_led_timer, jiffies + HZ/10); -+ } -+ spin_unlock(&np->led_lock); -+ -+ length = myNextRxDesc->descr.hw_len - 4; -+ dev->stats.rx_bytes += length; -+ -+#ifdef ETHDEBUG -+ printk("Got a packet of length %d:\n", length); -+ /* dump the first bytes in the packet */ -+ skb_data_ptr = (unsigned char *)phys_to_virt(myNextRxDesc->descr.buf); -+ for (i = 0; i < 8; i++) { -+ printk("%d: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", i * 8, -+ skb_data_ptr[0],skb_data_ptr[1],skb_data_ptr[2],skb_data_ptr[3], -+ skb_data_ptr[4],skb_data_ptr[5],skb_data_ptr[6],skb_data_ptr[7]); -+ skb_data_ptr += 8; -+ } -+#endif -+ -+ if (length < RX_COPYBREAK) { -+ /* Small packet, copy data */ -+ skb = dev_alloc_skb(length - ETHER_HEAD_LEN); -+ if (!skb) { -+ dev->stats.rx_errors++; -+ printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); -+ goto update_nextrxdesc; -+ } -+ -+ skb_put(skb, length - ETHER_HEAD_LEN); /* allocate room for the packet body */ -+ skb_data_ptr = skb_push(skb, ETHER_HEAD_LEN); /* allocate room for the header */ -+ -+#ifdef ETHDEBUG -+ printk("head = 0x%x, data = 0x%x, tail = 0x%x, end = 0x%x\n", -+ skb->head, skb->data, skb_tail_pointer(skb), -+ skb_end_pointer(skb)); -+ printk("copying packet to 0x%x.\n", skb_data_ptr); -+#endif -+ -+ memcpy(skb_data_ptr, phys_to_virt(myNextRxDesc->descr.buf), length); -+ } -+ else { -+ /* Large packet, send directly to upper layers and allocate new -+ * memory (aligned to cache line boundary to avoid bug). -+ * Before sending the skb to upper layers we must make sure -+ * that skb->data points to the aligned start of the packet. -+ */ -+ int align; -+ struct sk_buff *new_skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); -+ if (!new_skb) { -+ dev->stats.rx_errors++; -+ printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); -+ goto update_nextrxdesc; -+ } -+ skb = myNextRxDesc->skb; -+ align = (int)phys_to_virt(myNextRxDesc->descr.buf) - (int)skb->data; -+ skb_put(skb, length + align); -+ skb_pull(skb, align); /* Remove alignment bytes */ -+ myNextRxDesc->skb = new_skb; -+ myNextRxDesc->descr.buf = L1_CACHE_ALIGN(virt_to_phys(myNextRxDesc->skb->data)); -+ } -+ -+ skb->protocol = eth_type_trans(skb, dev); -+ -+ /* Send the packet to the upper layers */ -+ netif_rx(skb); -+ -+ update_nextrxdesc: -+ /* Prepare for next packet */ -+ myNextRxDesc->descr.status = 0; -+ prevRxDesc = myNextRxDesc; -+ myNextRxDesc = phys_to_virt(myNextRxDesc->descr.next); -+ -+ rx_queue_len++; -+ -+ /* Check if descriptors should be returned */ -+ if (rx_queue_len == RX_QUEUE_THRESHOLD) { -+ flush_etrax_cache(); -+ prevRxDesc->descr.ctrl |= d_eol; -+ myLastRxDesc->descr.ctrl &= ~d_eol; -+ myLastRxDesc = prevRxDesc; -+ rx_queue_len = 0; -+ } -+} -+ -+/* The inverse routine to net_open(). */ -+static int -+e100_close(struct net_device *dev) -+{ -+ printk(KERN_INFO "Closing %s.\n", dev->name); -+ -+ netif_stop_queue(dev); -+ -+ *R_IRQ_MASK0_CLR = -+ IO_STATE(R_IRQ_MASK0_CLR, overrun, clr) | -+ IO_STATE(R_IRQ_MASK0_CLR, underrun, clr) | -+ IO_STATE(R_IRQ_MASK0_CLR, excessive_col, clr); -+ -+ *R_IRQ_MASK2_CLR = -+ IO_STATE(R_IRQ_MASK2_CLR, dma0_descr, clr) | -+ IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) | -+ IO_STATE(R_IRQ_MASK2_CLR, dma1_descr, clr) | -+ IO_STATE(R_IRQ_MASK2_CLR, dma1_eop, clr); -+ -+ /* Stop the receiver and the transmitter */ -+ -+ RESET_DMA(NETWORK_TX_DMA_NBR); -+ RESET_DMA(NETWORK_RX_DMA_NBR); -+ -+ /* Flush the Tx and disable Rx here. */ -+ -+ free_irq(NETWORK_DMA_RX_IRQ_NBR, (void *)dev); -+ free_irq(NETWORK_DMA_TX_IRQ_NBR, (void *)dev); -+ free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev); -+ -+ cris_free_dma(NETWORK_TX_DMA_NBR, cardname); -+ cris_free_dma(NETWORK_RX_DMA_NBR, cardname); -+ -+ /* Update the statistics here. */ -+ -+ update_rx_stats(&dev->stats); -+ update_tx_stats(&dev->stats); -+ -+ /* Stop speed/duplex timers */ -+ del_timer(&speed_timer); -+ del_timer(&duplex_timer); -+ -+ return 0; -+} -+ -+static int -+e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ struct mii_ioctl_data *data = if_mii(ifr); -+ struct net_local *np = netdev_priv(dev); -+ int rc = 0; -+ int old_autoneg; -+ -+ spin_lock(&np->lock); /* Preempt protection */ -+ switch (cmd) { -+ /* The ioctls below should be considered obsolete but are */ -+ /* still present for compatibility with old scripts/apps */ -+ case SET_ETH_SPEED_10: /* 10 Mbps */ -+ e100_set_speed(dev, 10); -+ break; -+ case SET_ETH_SPEED_100: /* 100 Mbps */ -+ e100_set_speed(dev, 100); -+ break; -+ case SET_ETH_SPEED_AUTO: /* Auto-negotiate speed */ -+ e100_set_speed(dev, 0); -+ break; -+ case SET_ETH_DUPLEX_HALF: /* Half duplex */ -+ e100_set_duplex(dev, half); -+ break; -+ case SET_ETH_DUPLEX_FULL: /* Full duplex */ -+ e100_set_duplex(dev, full); -+ break; -+ case SET_ETH_DUPLEX_AUTO: /* Auto-negotiate duplex */ -+ e100_set_duplex(dev, autoneg); -+ break; -+ case SET_ETH_AUTONEG: -+ old_autoneg = autoneg_normal; -+ autoneg_normal = *(int*)data; -+ if (autoneg_normal != old_autoneg) -+ e100_negotiate(dev); -+ break; -+ default: -+ rc = generic_mii_ioctl(&np->mii_if, if_mii(ifr), -+ cmd, NULL); -+ break; -+ } -+ spin_unlock(&np->lock); -+ return rc; -+} -+ -+static int e100_get_settings(struct net_device *dev, -+ struct ethtool_cmd *cmd) -+{ -+ struct net_local *np = netdev_priv(dev); -+ int err; -+ -+ spin_lock_irq(&np->lock); -+ err = mii_ethtool_gset(&np->mii_if, cmd); -+ spin_unlock_irq(&np->lock); -+ -+ /* The PHY may support 1000baseT, but the Etrax100 does not. */ -+ cmd->supported &= ~(SUPPORTED_1000baseT_Half -+ | SUPPORTED_1000baseT_Full); -+ return err; -+} -+ -+static int e100_set_settings(struct net_device *dev, -+ struct ethtool_cmd *ecmd) -+{ -+ if (ecmd->autoneg == AUTONEG_ENABLE) { -+ e100_set_duplex(dev, autoneg); -+ e100_set_speed(dev, 0); -+ } else { -+ e100_set_duplex(dev, ecmd->duplex == DUPLEX_HALF ? half : full); -+ e100_set_speed(dev, ecmd->speed == SPEED_10 ? 10: 100); -+ } -+ -+ return 0; -+} -+ -+static void e100_get_drvinfo(struct net_device *dev, -+ struct ethtool_drvinfo *info) -+{ -+ strncpy(info->driver, "ETRAX 100LX", sizeof(info->driver) - 1); -+ strncpy(info->version, "$Revision: 1.31 $", sizeof(info->version) - 1); -+ strncpy(info->fw_version, "N/A", sizeof(info->fw_version) - 1); -+ strncpy(info->bus_info, "N/A", sizeof(info->bus_info) - 1); -+} -+ -+static int e100_nway_reset(struct net_device *dev) -+{ -+ if (current_duplex == autoneg && current_speed_selection == 0) -+ e100_negotiate(dev); -+ return 0; -+} -+ -+static const struct ethtool_ops e100_ethtool_ops = { -+ .get_settings = e100_get_settings, -+ .set_settings = e100_set_settings, -+ .get_drvinfo = e100_get_drvinfo, -+ .nway_reset = e100_nway_reset, -+ .get_link = ethtool_op_get_link, -+}; -+ -+static int -+e100_set_config(struct net_device *dev, struct ifmap *map) -+{ -+ struct net_local *np = netdev_priv(dev); -+ -+ spin_lock(&np->lock); /* Preempt protection */ -+ -+ switch(map->port) { -+ case IF_PORT_UNKNOWN: -+ /* Use autoneg */ -+ e100_set_speed(dev, 0); -+ e100_set_duplex(dev, autoneg); -+ break; -+ case IF_PORT_10BASET: -+ e100_set_speed(dev, 10); -+ e100_set_duplex(dev, autoneg); -+ break; -+ case IF_PORT_100BASET: -+ case IF_PORT_100BASETX: -+ e100_set_speed(dev, 100); -+ e100_set_duplex(dev, autoneg); -+ break; -+ case IF_PORT_100BASEFX: -+ case IF_PORT_10BASE2: -+ case IF_PORT_AUI: -+ spin_unlock(&np->lock); -+ return -EOPNOTSUPP; -+ break; -+ default: -+ printk(KERN_ERR "%s: Invalid media selected", dev->name); -+ spin_unlock(&np->lock); -+ return -EINVAL; -+ } -+ spin_unlock(&np->lock); -+ return 0; -+} -+ -+static void -+update_rx_stats(struct net_device_stats *es) -+{ -+ unsigned long r = *R_REC_COUNTERS; -+ /* update stats relevant to reception errors */ -+ es->rx_fifo_errors += IO_EXTRACT(R_REC_COUNTERS, congestion, r); -+ es->rx_crc_errors += IO_EXTRACT(R_REC_COUNTERS, crc_error, r); -+ es->rx_frame_errors += IO_EXTRACT(R_REC_COUNTERS, alignment_error, r); -+ es->rx_length_errors += IO_EXTRACT(R_REC_COUNTERS, oversize, r); -+} -+ -+static void -+update_tx_stats(struct net_device_stats *es) -+{ -+ unsigned long r = *R_TR_COUNTERS; -+ /* update stats relevant to transmission errors */ -+ es->collisions += -+ IO_EXTRACT(R_TR_COUNTERS, single_col, r) + -+ IO_EXTRACT(R_TR_COUNTERS, multiple_col, r); -+} -+ -+/* -+ * Get the current statistics. -+ * This may be called with the card open or closed. -+ */ -+static struct net_device_stats * -+e100_get_stats(struct net_device *dev) -+{ -+ struct net_local *lp = netdev_priv(dev); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&lp->lock, flags); -+ -+ update_rx_stats(&dev->stats); -+ update_tx_stats(&dev->stats); -+ -+ spin_unlock_irqrestore(&lp->lock, flags); -+ return &dev->stats; -+} -+ -+/* -+ * Set or clear the multicast filter for this adaptor. -+ * num_addrs == -1 Promiscuous mode, receive all packets -+ * num_addrs == 0 Normal mode, clear multicast list -+ * num_addrs > 0 Multicast mode, receive normal and MC packets, -+ * and do best-effort filtering. -+ */ -+static void -+set_multicast_list(struct net_device *dev) -+{ -+ struct net_local *lp = netdev_priv(dev); -+ int num_addr = netdev_mc_count(dev); -+ unsigned long int lo_bits; -+ unsigned long int hi_bits; -+ -+ spin_lock(&lp->lock); -+ if (dev->flags & IFF_PROMISC) { -+ /* promiscuous mode */ -+ lo_bits = 0xfffffffful; -+ hi_bits = 0xfffffffful; -+ -+ /* Enable individual receive */ -+ SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, individual, receive); -+ *R_NETWORK_REC_CONFIG = network_rec_config_shadow; -+ } else if (dev->flags & IFF_ALLMULTI) { -+ /* enable all multicasts */ -+ lo_bits = 0xfffffffful; -+ hi_bits = 0xfffffffful; -+ -+ /* Disable individual receive */ -+ SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, individual, discard); -+ *R_NETWORK_REC_CONFIG = network_rec_config_shadow; -+ } else if (num_addr == 0) { -+ /* Normal, clear the mc list */ -+ lo_bits = 0x00000000ul; -+ hi_bits = 0x00000000ul; -+ -+ /* Disable individual receive */ -+ SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, individual, discard); -+ *R_NETWORK_REC_CONFIG = network_rec_config_shadow; -+ } else { -+ /* MC mode, receive normal and MC packets */ -+ char hash_ix; -+ struct netdev_hw_addr *ha; -+ char *baddr; -+ -+ lo_bits = 0x00000000ul; -+ hi_bits = 0x00000000ul; -+ netdev_for_each_mc_addr(ha, dev) { -+ /* Calculate the hash index for the GA registers */ -+ -+ hash_ix = 0; -+ baddr = ha->addr; -+ hash_ix ^= (*baddr) & 0x3f; -+ hash_ix ^= ((*baddr) >> 6) & 0x03; -+ ++baddr; -+ hash_ix ^= ((*baddr) << 2) & 0x03c; -+ hash_ix ^= ((*baddr) >> 4) & 0xf; -+ ++baddr; -+ hash_ix ^= ((*baddr) << 4) & 0x30; -+ hash_ix ^= ((*baddr) >> 2) & 0x3f; -+ ++baddr; -+ hash_ix ^= (*baddr) & 0x3f; -+ hash_ix ^= ((*baddr) >> 6) & 0x03; -+ ++baddr; -+ hash_ix ^= ((*baddr) << 2) & 0x03c; -+ hash_ix ^= ((*baddr) >> 4) & 0xf; -+ ++baddr; -+ hash_ix ^= ((*baddr) << 4) & 0x30; -+ hash_ix ^= ((*baddr) >> 2) & 0x3f; -+ -+ hash_ix &= 0x3f; -+ -+ if (hash_ix >= 32) { -+ hi_bits |= (1 << (hash_ix-32)); -+ } else { -+ lo_bits |= (1 << hash_ix); -+ } -+ } -+ /* Disable individual receive */ -+ SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, individual, discard); -+ *R_NETWORK_REC_CONFIG = network_rec_config_shadow; -+ } -+ *R_NETWORK_GA_0 = lo_bits; -+ *R_NETWORK_GA_1 = hi_bits; -+ spin_unlock(&lp->lock); -+} -+ -+void -+e100_hardware_send_packet(struct net_local *np, char *buf, int length) -+{ -+ D(printk("e100 send pack, buf 0x%x len %d\n", buf, length)); -+ -+ spin_lock(&np->led_lock); -+ if (!led_active && time_after(jiffies, led_next_time)) { -+ /* light the network leds depending on the current speed. */ -+ e100_set_network_leds(NETWORK_ACTIVITY); -+ -+ /* Set the earliest time we may clear the LED */ -+ led_next_time = jiffies + NET_FLASH_TIME; -+ led_active = 1; -+ mod_timer(&clear_led_timer, jiffies + HZ/10); -+ } -+ spin_unlock(&np->led_lock); -+ -+ /* configure the tx dma descriptor */ -+ myNextTxDesc->descr.sw_len = length; -+ myNextTxDesc->descr.ctrl = d_eop | d_eol | d_wait; -+ myNextTxDesc->descr.buf = virt_to_phys(buf); -+ -+ /* Move end of list */ -+ myLastTxDesc->descr.ctrl &= ~d_eol; -+ myLastTxDesc = myNextTxDesc; -+ -+ /* Restart DMA channel */ -+ *R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, restart); -+} -+ -+static void -+e100_clear_network_leds(unsigned long dummy) -+{ -+ struct net_device *dev = (struct net_device *)dummy; -+ struct net_local *np = netdev_priv(dev); -+ -+ spin_lock(&np->led_lock); -+ -+ if (led_active && time_after(jiffies, led_next_time)) { -+ e100_set_network_leds(NO_NETWORK_ACTIVITY); -+ -+ /* Set the earliest time we may set the LED */ -+ led_next_time = jiffies + NET_FLASH_PAUSE; -+ led_active = 0; -+ } -+ -+ spin_unlock(&np->led_lock); -+} -+ -+static void -+e100_set_network_leds(int active) -+{ -+#if defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK) -+ int light_leds = (active == NO_NETWORK_ACTIVITY); -+#elif defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY) -+ int light_leds = (active == NETWORK_ACTIVITY); -+#else -+#error "Define either CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK or CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY" -+#endif -+ -+ if (!current_speed) { -+ /* Make LED red, link is down */ -+ CRIS_LED_NETWORK_SET(CRIS_LED_OFF); -+ } else if (light_leds) { -+ if (current_speed == 10) { -+ CRIS_LED_NETWORK_SET(CRIS_LED_ORANGE); -+ } else { -+ CRIS_LED_NETWORK_SET(CRIS_LED_GREEN); -+ } -+ } else { -+ CRIS_LED_NETWORK_SET(CRIS_LED_OFF); -+ } -+} -+ -+#ifdef CONFIG_NET_POLL_CONTROLLER -+static void -+e100_netpoll(struct net_device* netdev) -+{ -+ e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL); -+} -+#endif -+ -+static int -+etrax_init_module(void) -+{ -+ return etrax_ethernet_init(); -+} -+ -+static int __init -+e100_boot_setup(char* str) -+{ -+ struct sockaddr sa = {0}; -+ int i; -+ -+ /* Parse the colon separated Ethernet station address */ -+ for (i = 0; i < ETH_ALEN; i++) { -+ unsigned int tmp; -+ if (sscanf(str + 3*i, "%2x", &tmp) != 1) { -+ printk(KERN_WARNING "Malformed station address"); -+ return 0; -+ } -+ sa.sa_data[i] = (char)tmp; -+ } -+ -+ default_mac = sa; -+ return 1; -+} -+ -+__setup("etrax100_eth=", e100_boot_setup); -+ -+module_init(etrax_init_module); -diff -Nur linux-2.6.39.orig/drivers/tty/serial/crisv10.c linux-2.6.39/drivers/tty/serial/crisv10.c ---- linux-2.6.39.orig/drivers/tty/serial/crisv10.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/tty/serial/crisv10.c 2011-07-28 16:27:57.623883501 +0200 -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -4430,6 +4431,7 @@ - #endif - }; - -+static struct class *rs_class; - static int __init rs_init(void) - { - int i; -@@ -4564,6 +4566,24 @@ - #endif - #endif /* CONFIG_SVINTO_SIM */ - -+ rs_class = class_create(THIS_MODULE, "rs_tty"); -+#ifdef CONFIG_ETRAX_SERIAL_PORT0 -+ device_create(rs_class, NULL, -+ MKDEV(TTY_MAJOR, 64), NULL, "ttyS0"); -+#endif -+#ifdef CONFIG_ETRAX_SERIAL_PORT1 -+ device_create(rs_class, NULL, -+ MKDEV(TTY_MAJOR, 65), NULL, "ttyS1"); -+#endif -+#ifdef CONFIG_ETRAX_SERIAL_PORT2 -+ device_create(rs_class, NULL, -+ MKDEV(TTY_MAJOR, 66), NULL, "ttyS2"); -+#endif -+#ifdef CONFIG_ETRAX_SERIAL_PORT3 -+ device_create(rs_class, NULL, -+ MKDEV(TTY_MAJOR, 67), NULL, "ttyS3"); -+#endif -+ - return 0; - } - -diff -Nur linux-2.6.39.orig/drivers/tty/serial/crisv10.c.orig linux-2.6.39/drivers/tty/serial/crisv10.c.orig ---- linux-2.6.39.orig/drivers/tty/serial/crisv10.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/tty/serial/crisv10.c.orig 2011-05-19 06:06:34.000000000 +0200 -@@ -0,0 +1,4572 @@ -+/* -+ * Serial port driver for the ETRAX 100LX chip -+ * -+ * Copyright (C) 1998-2007 Axis Communications AB -+ * -+ * Many, many authors. Based once upon a time on serial.c for 16x50. -+ * -+ */ -+ -+static char *serial_version = "$Revision: 1.25 $"; -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+/* non-arch dependent serial structures are in linux/serial.h */ -+#include -+/* while we keep our own stuff (struct e100_serial) in a local .h file */ -+#include "crisv10.h" -+#include -+#include -+ -+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER -+#ifndef CONFIG_ETRAX_FAST_TIMER -+#error "Enable FAST_TIMER to use SERIAL_FAST_TIMER" -+#endif -+#endif -+ -+#if defined(CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS) && \ -+ (CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS == 0) -+#error "RX_TIMEOUT_TICKS == 0 not allowed, use 1" -+#endif -+ -+#if defined(CONFIG_ETRAX_RS485_ON_PA) && defined(CONFIG_ETRAX_RS485_ON_PORT_G) -+#error "Disable either CONFIG_ETRAX_RS485_ON_PA or CONFIG_ETRAX_RS485_ON_PORT_G" -+#endif -+ -+/* -+ * All of the compatibilty code so we can compile serial.c against -+ * older kernels is hidden in serial_compat.h -+ */ -+#if defined(LOCAL_HEADERS) -+#include "serial_compat.h" -+#endif -+ -+struct tty_driver *serial_driver; -+ -+/* number of characters left in xmit buffer before we ask for more */ -+#define WAKEUP_CHARS 256 -+ -+//#define SERIAL_DEBUG_INTR -+//#define SERIAL_DEBUG_OPEN -+//#define SERIAL_DEBUG_FLOW -+//#define SERIAL_DEBUG_DATA -+//#define SERIAL_DEBUG_THROTTLE -+//#define SERIAL_DEBUG_IO /* Debug for Extra control and status pins */ -+//#define SERIAL_DEBUG_LINE 0 /* What serport we want to debug */ -+ -+/* Enable this to use serial interrupts to handle when you -+ expect the first received event on the serial port to -+ be an error, break or similar. Used to be able to flash IRMA -+ from eLinux */ -+#define SERIAL_HANDLE_EARLY_ERRORS -+ -+/* Currently 16 descriptors x 128 bytes = 2048 bytes */ -+#define SERIAL_DESCR_BUF_SIZE 256 -+ -+#define SERIAL_PRESCALE_BASE 3125000 /* 3.125MHz */ -+#define DEF_BAUD_BASE SERIAL_PRESCALE_BASE -+ -+/* We don't want to load the system with massive fast timer interrupt -+ * on high baudrates so limit it to 250 us (4kHz) */ -+#define MIN_FLUSH_TIME_USEC 250 -+ -+/* Add an x here to log a lot of timer stuff */ -+#define TIMERD(x) -+/* Debug details of interrupt handling */ -+#define DINTR1(x) /* irq on/off, errors */ -+#define DINTR2(x) /* tx and rx */ -+/* Debug flip buffer stuff */ -+#define DFLIP(x) -+/* Debug flow control and overview of data flow */ -+#define DFLOW(x) -+#define DBAUD(x) -+#define DLOG_INT_TRIG(x) -+ -+//#define DEBUG_LOG_INCLUDED -+#ifndef DEBUG_LOG_INCLUDED -+#define DEBUG_LOG(line, string, value) -+#else -+struct debug_log_info -+{ -+ unsigned long time; -+ unsigned long timer_data; -+// int line; -+ const char *string; -+ int value; -+}; -+#define DEBUG_LOG_SIZE 4096 -+ -+struct debug_log_info debug_log[DEBUG_LOG_SIZE]; -+int debug_log_pos = 0; -+ -+#define DEBUG_LOG(_line, _string, _value) do { \ -+ if ((_line) == SERIAL_DEBUG_LINE) {\ -+ debug_log_func(_line, _string, _value); \ -+ }\ -+}while(0) -+ -+void debug_log_func(int line, const char *string, int value) -+{ -+ if (debug_log_pos < DEBUG_LOG_SIZE) { -+ debug_log[debug_log_pos].time = jiffies; -+ debug_log[debug_log_pos].timer_data = *R_TIMER_DATA; -+// debug_log[debug_log_pos].line = line; -+ debug_log[debug_log_pos].string = string; -+ debug_log[debug_log_pos].value = value; -+ debug_log_pos++; -+ } -+ /*printk(string, value);*/ -+} -+#endif -+ -+#ifndef CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS -+/* Default number of timer ticks before flushing rx fifo -+ * When using "little data, low latency applications: use 0 -+ * When using "much data applications (PPP)" use ~5 -+ */ -+#define CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS 5 -+#endif -+ -+unsigned long timer_data_to_ns(unsigned long timer_data); -+ -+static void change_speed(struct e100_serial *info); -+static void rs_throttle(struct tty_struct * tty); -+static void rs_wait_until_sent(struct tty_struct *tty, int timeout); -+static int rs_write(struct tty_struct *tty, -+ const unsigned char *buf, int count); -+#ifdef CONFIG_ETRAX_RS485 -+static int e100_write_rs485(struct tty_struct *tty, -+ const unsigned char *buf, int count); -+#endif -+static int get_lsr_info(struct e100_serial *info, unsigned int *value); -+ -+ -+#define DEF_BAUD 115200 /* 115.2 kbit/s */ -+#define STD_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -+#define DEF_RX 0x20 /* or SERIAL_CTRL_W >> 8 */ -+/* Default value of tx_ctrl register: has txd(bit 7)=1 (idle) as default */ -+#define DEF_TX 0x80 /* or SERIAL_CTRL_B */ -+ -+/* offsets from R_SERIALx_CTRL */ -+ -+#define REG_DATA 0 -+#define REG_DATA_STATUS32 0 /* this is the 32 bit register R_SERIALx_READ */ -+#define REG_TR_DATA 0 -+#define REG_STATUS 1 -+#define REG_TR_CTRL 1 -+#define REG_REC_CTRL 2 -+#define REG_BAUD 3 -+#define REG_XOFF 4 /* this is a 32 bit register */ -+ -+/* The bitfields are the same for all serial ports */ -+#define SER_RXD_MASK IO_MASK(R_SERIAL0_STATUS, rxd) -+#define SER_DATA_AVAIL_MASK IO_MASK(R_SERIAL0_STATUS, data_avail) -+#define SER_FRAMING_ERR_MASK IO_MASK(R_SERIAL0_STATUS, framing_err) -+#define SER_PAR_ERR_MASK IO_MASK(R_SERIAL0_STATUS, par_err) -+#define SER_OVERRUN_MASK IO_MASK(R_SERIAL0_STATUS, overrun) -+ -+#define SER_ERROR_MASK (SER_OVERRUN_MASK | SER_PAR_ERR_MASK | SER_FRAMING_ERR_MASK) -+ -+/* Values for info->errorcode */ -+#define ERRCODE_SET_BREAK (TTY_BREAK) -+#define ERRCODE_INSERT 0x100 -+#define ERRCODE_INSERT_BREAK (ERRCODE_INSERT | TTY_BREAK) -+ -+#define FORCE_EOP(info) *R_SET_EOP = 1U << info->iseteop; -+ -+/* -+ * General note regarding the use of IO_* macros in this file: -+ * -+ * We will use the bits defined for DMA channel 6 when using various -+ * IO_* macros (e.g. IO_STATE, IO_MASK, IO_EXTRACT) and _assume_ they are -+ * the same for all channels (which of course they are). -+ * -+ * We will also use the bits defined for serial port 0 when writing commands -+ * to the different ports, as these bits too are the same for all ports. -+ */ -+ -+ -+/* Mask for the irqs possibly enabled in R_IRQ_MASK1_RD etc. */ -+static const unsigned long e100_ser_int_mask = 0 -+#ifdef CONFIG_ETRAX_SERIAL_PORT0 -+| IO_MASK(R_IRQ_MASK1_RD, ser0_data) | IO_MASK(R_IRQ_MASK1_RD, ser0_ready) -+#endif -+#ifdef CONFIG_ETRAX_SERIAL_PORT1 -+| IO_MASK(R_IRQ_MASK1_RD, ser1_data) | IO_MASK(R_IRQ_MASK1_RD, ser1_ready) -+#endif -+#ifdef CONFIG_ETRAX_SERIAL_PORT2 -+| IO_MASK(R_IRQ_MASK1_RD, ser2_data) | IO_MASK(R_IRQ_MASK1_RD, ser2_ready) -+#endif -+#ifdef CONFIG_ETRAX_SERIAL_PORT3 -+| IO_MASK(R_IRQ_MASK1_RD, ser3_data) | IO_MASK(R_IRQ_MASK1_RD, ser3_ready) -+#endif -+; -+unsigned long r_alt_ser_baudrate_shadow = 0; -+ -+/* this is the data for the four serial ports in the etrax100 */ -+/* DMA2(ser2), DMA4(ser3), DMA6(ser0) or DMA8(ser1) */ -+/* R_DMA_CHx_CLR_INTR, R_DMA_CHx_FIRST, R_DMA_CHx_CMD */ -+ -+static struct e100_serial rs_table[] = { -+ { .baud = DEF_BAUD, -+ .ioport = (unsigned char *)R_SERIAL0_CTRL, -+ .irq = 1U << 12, /* uses DMA 6 and 7 */ -+ .oclrintradr = R_DMA_CH6_CLR_INTR, -+ .ofirstadr = R_DMA_CH6_FIRST, -+ .ocmdadr = R_DMA_CH6_CMD, -+ .ostatusadr = R_DMA_CH6_STATUS, -+ .iclrintradr = R_DMA_CH7_CLR_INTR, -+ .ifirstadr = R_DMA_CH7_FIRST, -+ .icmdadr = R_DMA_CH7_CMD, -+ .idescradr = R_DMA_CH7_DESCR, -+ .flags = STD_FLAGS, -+ .rx_ctrl = DEF_RX, -+ .tx_ctrl = DEF_TX, -+ .iseteop = 2, -+ .dma_owner = dma_ser0, -+ .io_if = if_serial_0, -+#ifdef CONFIG_ETRAX_SERIAL_PORT0 -+ .enabled = 1, -+#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT -+ .dma_out_enabled = 1, -+ .dma_out_nbr = SER0_TX_DMA_NBR, -+ .dma_out_irq_nbr = SER0_DMA_TX_IRQ_NBR, -+ .dma_out_irq_flags = IRQF_DISABLED, -+ .dma_out_irq_description = "serial 0 dma tr", -+#else -+ .dma_out_enabled = 0, -+ .dma_out_nbr = UINT_MAX, -+ .dma_out_irq_nbr = 0, -+ .dma_out_irq_flags = 0, -+ .dma_out_irq_description = NULL, -+#endif -+#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN -+ .dma_in_enabled = 1, -+ .dma_in_nbr = SER0_RX_DMA_NBR, -+ .dma_in_irq_nbr = SER0_DMA_RX_IRQ_NBR, -+ .dma_in_irq_flags = IRQF_DISABLED, -+ .dma_in_irq_description = "serial 0 dma rec", -+#else -+ .dma_in_enabled = 0, -+ .dma_in_nbr = UINT_MAX, -+ .dma_in_irq_nbr = 0, -+ .dma_in_irq_flags = 0, -+ .dma_in_irq_description = NULL, -+#endif -+#else -+ .enabled = 0, -+ .io_if_description = NULL, -+ .dma_out_enabled = 0, -+ .dma_in_enabled = 0 -+#endif -+ -+}, /* ttyS0 */ -+#ifndef CONFIG_SVINTO_SIM -+ { .baud = DEF_BAUD, -+ .ioport = (unsigned char *)R_SERIAL1_CTRL, -+ .irq = 1U << 16, /* uses DMA 8 and 9 */ -+ .oclrintradr = R_DMA_CH8_CLR_INTR, -+ .ofirstadr = R_DMA_CH8_FIRST, -+ .ocmdadr = R_DMA_CH8_CMD, -+ .ostatusadr = R_DMA_CH8_STATUS, -+ .iclrintradr = R_DMA_CH9_CLR_INTR, -+ .ifirstadr = R_DMA_CH9_FIRST, -+ .icmdadr = R_DMA_CH9_CMD, -+ .idescradr = R_DMA_CH9_DESCR, -+ .flags = STD_FLAGS, -+ .rx_ctrl = DEF_RX, -+ .tx_ctrl = DEF_TX, -+ .iseteop = 3, -+ .dma_owner = dma_ser1, -+ .io_if = if_serial_1, -+#ifdef CONFIG_ETRAX_SERIAL_PORT1 -+ .enabled = 1, -+ .io_if_description = "ser1", -+#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT -+ .dma_out_enabled = 1, -+ .dma_out_nbr = SER1_TX_DMA_NBR, -+ .dma_out_irq_nbr = SER1_DMA_TX_IRQ_NBR, -+ .dma_out_irq_flags = IRQF_DISABLED, -+ .dma_out_irq_description = "serial 1 dma tr", -+#else -+ .dma_out_enabled = 0, -+ .dma_out_nbr = UINT_MAX, -+ .dma_out_irq_nbr = 0, -+ .dma_out_irq_flags = 0, -+ .dma_out_irq_description = NULL, -+#endif -+#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN -+ .dma_in_enabled = 1, -+ .dma_in_nbr = SER1_RX_DMA_NBR, -+ .dma_in_irq_nbr = SER1_DMA_RX_IRQ_NBR, -+ .dma_in_irq_flags = IRQF_DISABLED, -+ .dma_in_irq_description = "serial 1 dma rec", -+#else -+ .dma_in_enabled = 0, -+ .dma_in_enabled = 0, -+ .dma_in_nbr = UINT_MAX, -+ .dma_in_irq_nbr = 0, -+ .dma_in_irq_flags = 0, -+ .dma_in_irq_description = NULL, -+#endif -+#else -+ .enabled = 0, -+ .io_if_description = NULL, -+ .dma_in_irq_nbr = 0, -+ .dma_out_enabled = 0, -+ .dma_in_enabled = 0 -+#endif -+}, /* ttyS1 */ -+ -+ { .baud = DEF_BAUD, -+ .ioport = (unsigned char *)R_SERIAL2_CTRL, -+ .irq = 1U << 4, /* uses DMA 2 and 3 */ -+ .oclrintradr = R_DMA_CH2_CLR_INTR, -+ .ofirstadr = R_DMA_CH2_FIRST, -+ .ocmdadr = R_DMA_CH2_CMD, -+ .ostatusadr = R_DMA_CH2_STATUS, -+ .iclrintradr = R_DMA_CH3_CLR_INTR, -+ .ifirstadr = R_DMA_CH3_FIRST, -+ .icmdadr = R_DMA_CH3_CMD, -+ .idescradr = R_DMA_CH3_DESCR, -+ .flags = STD_FLAGS, -+ .rx_ctrl = DEF_RX, -+ .tx_ctrl = DEF_TX, -+ .iseteop = 0, -+ .dma_owner = dma_ser2, -+ .io_if = if_serial_2, -+#ifdef CONFIG_ETRAX_SERIAL_PORT2 -+ .enabled = 1, -+ .io_if_description = "ser2", -+#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT -+ .dma_out_enabled = 1, -+ .dma_out_nbr = SER2_TX_DMA_NBR, -+ .dma_out_irq_nbr = SER2_DMA_TX_IRQ_NBR, -+ .dma_out_irq_flags = IRQF_DISABLED, -+ .dma_out_irq_description = "serial 2 dma tr", -+#else -+ .dma_out_enabled = 0, -+ .dma_out_nbr = UINT_MAX, -+ .dma_out_irq_nbr = 0, -+ .dma_out_irq_flags = 0, -+ .dma_out_irq_description = NULL, -+#endif -+#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN -+ .dma_in_enabled = 1, -+ .dma_in_nbr = SER2_RX_DMA_NBR, -+ .dma_in_irq_nbr = SER2_DMA_RX_IRQ_NBR, -+ .dma_in_irq_flags = IRQF_DISABLED, -+ .dma_in_irq_description = "serial 2 dma rec", -+#else -+ .dma_in_enabled = 0, -+ .dma_in_nbr = UINT_MAX, -+ .dma_in_irq_nbr = 0, -+ .dma_in_irq_flags = 0, -+ .dma_in_irq_description = NULL, -+#endif -+#else -+ .enabled = 0, -+ .io_if_description = NULL, -+ .dma_out_enabled = 0, -+ .dma_in_enabled = 0 -+#endif -+ }, /* ttyS2 */ -+ -+ { .baud = DEF_BAUD, -+ .ioport = (unsigned char *)R_SERIAL3_CTRL, -+ .irq = 1U << 8, /* uses DMA 4 and 5 */ -+ .oclrintradr = R_DMA_CH4_CLR_INTR, -+ .ofirstadr = R_DMA_CH4_FIRST, -+ .ocmdadr = R_DMA_CH4_CMD, -+ .ostatusadr = R_DMA_CH4_STATUS, -+ .iclrintradr = R_DMA_CH5_CLR_INTR, -+ .ifirstadr = R_DMA_CH5_FIRST, -+ .icmdadr = R_DMA_CH5_CMD, -+ .idescradr = R_DMA_CH5_DESCR, -+ .flags = STD_FLAGS, -+ .rx_ctrl = DEF_RX, -+ .tx_ctrl = DEF_TX, -+ .iseteop = 1, -+ .dma_owner = dma_ser3, -+ .io_if = if_serial_3, -+#ifdef CONFIG_ETRAX_SERIAL_PORT3 -+ .enabled = 1, -+ .io_if_description = "ser3", -+#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT -+ .dma_out_enabled = 1, -+ .dma_out_nbr = SER3_TX_DMA_NBR, -+ .dma_out_irq_nbr = SER3_DMA_TX_IRQ_NBR, -+ .dma_out_irq_flags = IRQF_DISABLED, -+ .dma_out_irq_description = "serial 3 dma tr", -+#else -+ .dma_out_enabled = 0, -+ .dma_out_nbr = UINT_MAX, -+ .dma_out_irq_nbr = 0, -+ .dma_out_irq_flags = 0, -+ .dma_out_irq_description = NULL, -+#endif -+#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN -+ .dma_in_enabled = 1, -+ .dma_in_nbr = SER3_RX_DMA_NBR, -+ .dma_in_irq_nbr = SER3_DMA_RX_IRQ_NBR, -+ .dma_in_irq_flags = IRQF_DISABLED, -+ .dma_in_irq_description = "serial 3 dma rec", -+#else -+ .dma_in_enabled = 0, -+ .dma_in_nbr = UINT_MAX, -+ .dma_in_irq_nbr = 0, -+ .dma_in_irq_flags = 0, -+ .dma_in_irq_description = NULL -+#endif -+#else -+ .enabled = 0, -+ .io_if_description = NULL, -+ .dma_out_enabled = 0, -+ .dma_in_enabled = 0 -+#endif -+ } /* ttyS3 */ -+#endif -+}; -+ -+ -+#define NR_PORTS (sizeof(rs_table)/sizeof(struct e100_serial)) -+ -+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER -+static struct fast_timer fast_timers[NR_PORTS]; -+#endif -+ -+#ifdef CONFIG_ETRAX_SERIAL_PROC_ENTRY -+#define PROCSTAT(x) x -+struct ser_statistics_type { -+ int overrun_cnt; -+ int early_errors_cnt; -+ int ser_ints_ok_cnt; -+ int errors_cnt; -+ unsigned long int processing_flip; -+ unsigned long processing_flip_still_room; -+ unsigned long int timeout_flush_cnt; -+ int rx_dma_ints; -+ int tx_dma_ints; -+ int rx_tot; -+ int tx_tot; -+}; -+ -+static struct ser_statistics_type ser_stat[NR_PORTS]; -+ -+#else -+ -+#define PROCSTAT(x) -+ -+#endif /* CONFIG_ETRAX_SERIAL_PROC_ENTRY */ -+ -+/* RS-485 */ -+#if defined(CONFIG_ETRAX_RS485) -+#ifdef CONFIG_ETRAX_FAST_TIMER -+static struct fast_timer fast_timers_rs485[NR_PORTS]; -+#endif -+#if defined(CONFIG_ETRAX_RS485_ON_PA) -+static int rs485_pa_bit = CONFIG_ETRAX_RS485_ON_PA_BIT; -+#endif -+#if defined(CONFIG_ETRAX_RS485_ON_PORT_G) -+static int rs485_port_g_bit = CONFIG_ETRAX_RS485_ON_PORT_G_BIT; -+#endif -+#endif -+ -+/* Info and macros needed for each ports extra control/status signals. */ -+#define E100_STRUCT_PORT(line, pinname) \ -+ ((CONFIG_ETRAX_SER##line##_##pinname##_ON_PA_BIT >= 0)? \ -+ (R_PORT_PA_DATA): ( \ -+ (CONFIG_ETRAX_SER##line##_##pinname##_ON_PB_BIT >= 0)? \ -+ (R_PORT_PB_DATA):&dummy_ser[line])) -+ -+#define E100_STRUCT_SHADOW(line, pinname) \ -+ ((CONFIG_ETRAX_SER##line##_##pinname##_ON_PA_BIT >= 0)? \ -+ (&port_pa_data_shadow): ( \ -+ (CONFIG_ETRAX_SER##line##_##pinname##_ON_PB_BIT >= 0)? \ -+ (&port_pb_data_shadow):&dummy_ser[line])) -+#define E100_STRUCT_MASK(line, pinname) \ -+ ((CONFIG_ETRAX_SER##line##_##pinname##_ON_PA_BIT >= 0)? \ -+ (1<= 0)? \ -+ (1< 3.3V to RS-232 driver -> -12V on RS-232 level -+ * inactive = 1 -> 0V to RS-232 driver -> +12V on RS-232 level -+ * -+ * These macros returns the pin value: 0=0V, >=1 = 3.3V on ETRAX chip -+ */ -+ -+/* Output */ -+#define E100_RTS_GET(info) ((info)->rx_ctrl & E100_RTS_MASK) -+/* Input */ -+#define E100_CTS_GET(info) ((info)->ioport[REG_STATUS] & E100_CTS_MASK) -+ -+/* These are typically PA or PB and 0 means 0V, 1 means 3.3V */ -+/* Is an output */ -+#define E100_DTR_GET(info) ((*e100_modem_pins[(info)->line].dtr_shadow) & e100_modem_pins[(info)->line].dtr_mask) -+ -+/* Normally inputs */ -+#define E100_RI_GET(info) ((*e100_modem_pins[(info)->line].ri_port) & e100_modem_pins[(info)->line].ri_mask) -+#define E100_CD_GET(info) ((*e100_modem_pins[(info)->line].cd_port) & e100_modem_pins[(info)->line].cd_mask) -+ -+/* Input */ -+#define E100_DSR_GET(info) ((*e100_modem_pins[(info)->line].dsr_port) & e100_modem_pins[(info)->line].dsr_mask) -+ -+ -+/* -+ * tmp_buf is used as a temporary buffer by serial_write. We need to -+ * lock it in case the memcpy_fromfs blocks while swapping in a page, -+ * and some other program tries to do a serial write at the same time. -+ * Since the lock will only come under contention when the system is -+ * swapping and available memory is low, it makes sense to share one -+ * buffer across all the serial ports, since it significantly saves -+ * memory if large numbers of serial ports are open. -+ */ -+static unsigned char *tmp_buf; -+static DEFINE_MUTEX(tmp_buf_mutex); -+ -+/* Calculate the chartime depending on baudrate, numbor of bits etc. */ -+static void update_char_time(struct e100_serial * info) -+{ -+ tcflag_t cflags = info->port.tty->termios->c_cflag; -+ int bits; -+ -+ /* calc. number of bits / data byte */ -+ /* databits + startbit and 1 stopbit */ -+ if ((cflags & CSIZE) == CS7) -+ bits = 9; -+ else -+ bits = 10; -+ -+ if (cflags & CSTOPB) /* 2 stopbits ? */ -+ bits++; -+ -+ if (cflags & PARENB) /* parity bit ? */ -+ bits++; -+ -+ /* calc timeout */ -+ info->char_time_usec = ((bits * 1000000) / info->baud) + 1; -+ info->flush_time_usec = 4*info->char_time_usec; -+ if (info->flush_time_usec < MIN_FLUSH_TIME_USEC) -+ info->flush_time_usec = MIN_FLUSH_TIME_USEC; -+ -+} -+ -+/* -+ * This function maps from the Bxxxx defines in asm/termbits.h into real -+ * baud rates. -+ */ -+ -+static int -+cflag_to_baud(unsigned int cflag) -+{ -+ static int baud_table[] = { -+ 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, -+ 4800, 9600, 19200, 38400 }; -+ -+ static int ext_baud_table[] = { -+ 0, 57600, 115200, 230400, 460800, 921600, 1843200, 6250000, -+ 0, 0, 0, 0, 0, 0, 0, 0 }; -+ -+ if (cflag & CBAUDEX) -+ return ext_baud_table[(cflag & CBAUD) & ~CBAUDEX]; -+ else -+ return baud_table[cflag & CBAUD]; -+} -+ -+/* and this maps to an etrax100 hardware baud constant */ -+ -+static unsigned char -+cflag_to_etrax_baud(unsigned int cflag) -+{ -+ char retval; -+ -+ static char baud_table[] = { -+ -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, 3, 4, 5, 6, 7 }; -+ -+ static char ext_baud_table[] = { -+ -1, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1 }; -+ -+ if (cflag & CBAUDEX) -+ retval = ext_baud_table[(cflag & CBAUD) & ~CBAUDEX]; -+ else -+ retval = baud_table[cflag & CBAUD]; -+ -+ if (retval < 0) { -+ printk(KERN_WARNING "serdriver tried setting invalid baud rate, flags %x.\n", cflag); -+ retval = 5; /* choose default 9600 instead */ -+ } -+ -+ return retval | (retval << 4); /* choose same for both TX and RX */ -+} -+ -+ -+/* Various static support functions */ -+ -+/* Functions to set or clear DTR/RTS on the requested line */ -+/* It is complicated by the fact that RTS is a serial port register, while -+ * DTR might not be implemented in the HW at all, and if it is, it can be on -+ * any general port. -+ */ -+ -+ -+static inline void -+e100_dtr(struct e100_serial *info, int set) -+{ -+#ifndef CONFIG_SVINTO_SIM -+ unsigned char mask = e100_modem_pins[info->line].dtr_mask; -+ -+#ifdef SERIAL_DEBUG_IO -+ printk("ser%i dtr %i mask: 0x%02X\n", info->line, set, mask); -+ printk("ser%i shadow before 0x%02X get: %i\n", -+ info->line, *e100_modem_pins[info->line].dtr_shadow, -+ E100_DTR_GET(info)); -+#endif -+ /* DTR is active low */ -+ { -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ *e100_modem_pins[info->line].dtr_shadow &= ~mask; -+ *e100_modem_pins[info->line].dtr_shadow |= (set ? 0 : mask); -+ *e100_modem_pins[info->line].dtr_port = *e100_modem_pins[info->line].dtr_shadow; -+ local_irq_restore(flags); -+ } -+ -+#ifdef SERIAL_DEBUG_IO -+ printk("ser%i shadow after 0x%02X get: %i\n", -+ info->line, *e100_modem_pins[info->line].dtr_shadow, -+ E100_DTR_GET(info)); -+#endif -+#endif -+} -+ -+/* set = 0 means 3.3V on the pin, bitvalue: 0=active, 1=inactive -+ * 0=0V , 1=3.3V -+ */ -+static inline void -+e100_rts(struct e100_serial *info, int set) -+{ -+#ifndef CONFIG_SVINTO_SIM -+ unsigned long flags; -+ local_irq_save(flags); -+ info->rx_ctrl &= ~E100_RTS_MASK; -+ info->rx_ctrl |= (set ? 0 : E100_RTS_MASK); /* RTS is active low */ -+ info->ioport[REG_REC_CTRL] = info->rx_ctrl; -+ local_irq_restore(flags); -+#ifdef SERIAL_DEBUG_IO -+ printk("ser%i rts %i\n", info->line, set); -+#endif -+#endif -+} -+ -+ -+/* If this behaves as a modem, RI and CD is an output */ -+static inline void -+e100_ri_out(struct e100_serial *info, int set) -+{ -+#ifndef CONFIG_SVINTO_SIM -+ /* RI is active low */ -+ { -+ unsigned char mask = e100_modem_pins[info->line].ri_mask; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ *e100_modem_pins[info->line].ri_shadow &= ~mask; -+ *e100_modem_pins[info->line].ri_shadow |= (set ? 0 : mask); -+ *e100_modem_pins[info->line].ri_port = *e100_modem_pins[info->line].ri_shadow; -+ local_irq_restore(flags); -+ } -+#endif -+} -+static inline void -+e100_cd_out(struct e100_serial *info, int set) -+{ -+#ifndef CONFIG_SVINTO_SIM -+ /* CD is active low */ -+ { -+ unsigned char mask = e100_modem_pins[info->line].cd_mask; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ *e100_modem_pins[info->line].cd_shadow &= ~mask; -+ *e100_modem_pins[info->line].cd_shadow |= (set ? 0 : mask); -+ *e100_modem_pins[info->line].cd_port = *e100_modem_pins[info->line].cd_shadow; -+ local_irq_restore(flags); -+ } -+#endif -+} -+ -+static inline void -+e100_disable_rx(struct e100_serial *info) -+{ -+#ifndef CONFIG_SVINTO_SIM -+ /* disable the receiver */ -+ info->ioport[REG_REC_CTRL] = -+ (info->rx_ctrl &= ~IO_MASK(R_SERIAL0_REC_CTRL, rec_enable)); -+#endif -+} -+ -+static inline void -+e100_enable_rx(struct e100_serial *info) -+{ -+#ifndef CONFIG_SVINTO_SIM -+ /* enable the receiver */ -+ info->ioport[REG_REC_CTRL] = -+ (info->rx_ctrl |= IO_MASK(R_SERIAL0_REC_CTRL, rec_enable)); -+#endif -+} -+ -+/* the rx DMA uses both the dma_descr and the dma_eop interrupts */ -+ -+static inline void -+e100_disable_rxdma_irq(struct e100_serial *info) -+{ -+#ifdef SERIAL_DEBUG_INTR -+ printk("rxdma_irq(%d): 0\n",info->line); -+#endif -+ DINTR1(DEBUG_LOG(info->line,"IRQ disable_rxdma_irq %i\n", info->line)); -+ *R_IRQ_MASK2_CLR = (info->irq << 2) | (info->irq << 3); -+} -+ -+static inline void -+e100_enable_rxdma_irq(struct e100_serial *info) -+{ -+#ifdef SERIAL_DEBUG_INTR -+ printk("rxdma_irq(%d): 1\n",info->line); -+#endif -+ DINTR1(DEBUG_LOG(info->line,"IRQ enable_rxdma_irq %i\n", info->line)); -+ *R_IRQ_MASK2_SET = (info->irq << 2) | (info->irq << 3); -+} -+ -+/* the tx DMA uses only dma_descr interrupt */ -+ -+static void e100_disable_txdma_irq(struct e100_serial *info) -+{ -+#ifdef SERIAL_DEBUG_INTR -+ printk("txdma_irq(%d): 0\n",info->line); -+#endif -+ DINTR1(DEBUG_LOG(info->line,"IRQ disable_txdma_irq %i\n", info->line)); -+ *R_IRQ_MASK2_CLR = info->irq; -+} -+ -+static void e100_enable_txdma_irq(struct e100_serial *info) -+{ -+#ifdef SERIAL_DEBUG_INTR -+ printk("txdma_irq(%d): 1\n",info->line); -+#endif -+ DINTR1(DEBUG_LOG(info->line,"IRQ enable_txdma_irq %i\n", info->line)); -+ *R_IRQ_MASK2_SET = info->irq; -+} -+ -+static void e100_disable_txdma_channel(struct e100_serial *info) -+{ -+ unsigned long flags; -+ -+ /* Disable output DMA channel for the serial port in question -+ * ( set to something other than serialX) -+ */ -+ local_irq_save(flags); -+ DFLOW(DEBUG_LOG(info->line, "disable_txdma_channel %i\n", info->line)); -+ if (info->line == 0) { -+ if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma6)) == -+ IO_STATE(R_GEN_CONFIG, dma6, serial0)) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused); -+ } -+ } else if (info->line == 1) { -+ if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma8)) == -+ IO_STATE(R_GEN_CONFIG, dma8, serial1)) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb); -+ } -+ } else if (info->line == 2) { -+ if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma2)) == -+ IO_STATE(R_GEN_CONFIG, dma2, serial2)) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0); -+ } -+ } else if (info->line == 3) { -+ if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma4)) == -+ IO_STATE(R_GEN_CONFIG, dma4, serial3)) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1); -+ } -+ } -+ *R_GEN_CONFIG = genconfig_shadow; -+ local_irq_restore(flags); -+} -+ -+ -+static void e100_enable_txdma_channel(struct e100_serial *info) -+{ -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ DFLOW(DEBUG_LOG(info->line, "enable_txdma_channel %i\n", info->line)); -+ /* Enable output DMA channel for the serial port in question */ -+ if (info->line == 0) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, serial0); -+ } else if (info->line == 1) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, serial1); -+ } else if (info->line == 2) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, serial2); -+ } else if (info->line == 3) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, serial3); -+ } -+ *R_GEN_CONFIG = genconfig_shadow; -+ local_irq_restore(flags); -+} -+ -+static void e100_disable_rxdma_channel(struct e100_serial *info) -+{ -+ unsigned long flags; -+ -+ /* Disable input DMA channel for the serial port in question -+ * ( set to something other than serialX) -+ */ -+ local_irq_save(flags); -+ if (info->line == 0) { -+ if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma7)) == -+ IO_STATE(R_GEN_CONFIG, dma7, serial0)) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma7); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma7, unused); -+ } -+ } else if (info->line == 1) { -+ if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma9)) == -+ IO_STATE(R_GEN_CONFIG, dma9, serial1)) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma9); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma9, usb); -+ } -+ } else if (info->line == 2) { -+ if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma3)) == -+ IO_STATE(R_GEN_CONFIG, dma3, serial2)) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, par0); -+ } -+ } else if (info->line == 3) { -+ if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma5)) == -+ IO_STATE(R_GEN_CONFIG, dma5, serial3)) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, par1); -+ } -+ } -+ *R_GEN_CONFIG = genconfig_shadow; -+ local_irq_restore(flags); -+} -+ -+ -+static void e100_enable_rxdma_channel(struct e100_serial *info) -+{ -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ /* Enable input DMA channel for the serial port in question */ -+ if (info->line == 0) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma7); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma7, serial0); -+ } else if (info->line == 1) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma9); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma9, serial1); -+ } else if (info->line == 2) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, serial2); -+ } else if (info->line == 3) { -+ genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5); -+ genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, serial3); -+ } -+ *R_GEN_CONFIG = genconfig_shadow; -+ local_irq_restore(flags); -+} -+ -+#ifdef SERIAL_HANDLE_EARLY_ERRORS -+/* in order to detect and fix errors on the first byte -+ we have to use the serial interrupts as well. */ -+ -+static inline void -+e100_disable_serial_data_irq(struct e100_serial *info) -+{ -+#ifdef SERIAL_DEBUG_INTR -+ printk("ser_irq(%d): 0\n",info->line); -+#endif -+ DINTR1(DEBUG_LOG(info->line,"IRQ disable data_irq %i\n", info->line)); -+ *R_IRQ_MASK1_CLR = (1U << (8+2*info->line)); -+} -+ -+static inline void -+e100_enable_serial_data_irq(struct e100_serial *info) -+{ -+#ifdef SERIAL_DEBUG_INTR -+ printk("ser_irq(%d): 1\n",info->line); -+ printk("**** %d = %d\n", -+ (8+2*info->line), -+ (1U << (8+2*info->line))); -+#endif -+ DINTR1(DEBUG_LOG(info->line,"IRQ enable data_irq %i\n", info->line)); -+ *R_IRQ_MASK1_SET = (1U << (8+2*info->line)); -+} -+#endif -+ -+static inline void -+e100_disable_serial_tx_ready_irq(struct e100_serial *info) -+{ -+#ifdef SERIAL_DEBUG_INTR -+ printk("ser_tx_irq(%d): 0\n",info->line); -+#endif -+ DINTR1(DEBUG_LOG(info->line,"IRQ disable ready_irq %i\n", info->line)); -+ *R_IRQ_MASK1_CLR = (1U << (8+1+2*info->line)); -+} -+ -+static inline void -+e100_enable_serial_tx_ready_irq(struct e100_serial *info) -+{ -+#ifdef SERIAL_DEBUG_INTR -+ printk("ser_tx_irq(%d): 1\n",info->line); -+ printk("**** %d = %d\n", -+ (8+1+2*info->line), -+ (1U << (8+1+2*info->line))); -+#endif -+ DINTR2(DEBUG_LOG(info->line,"IRQ enable ready_irq %i\n", info->line)); -+ *R_IRQ_MASK1_SET = (1U << (8+1+2*info->line)); -+} -+ -+static inline void e100_enable_rx_irq(struct e100_serial *info) -+{ -+ if (info->uses_dma_in) -+ e100_enable_rxdma_irq(info); -+ else -+ e100_enable_serial_data_irq(info); -+} -+static inline void e100_disable_rx_irq(struct e100_serial *info) -+{ -+ if (info->uses_dma_in) -+ e100_disable_rxdma_irq(info); -+ else -+ e100_disable_serial_data_irq(info); -+} -+ -+#if defined(CONFIG_ETRAX_RS485) -+/* Enable RS-485 mode on selected port. This is UGLY. */ -+static int -+e100_enable_rs485(struct tty_struct *tty, struct serial_rs485 *r) -+{ -+ struct e100_serial * info = (struct e100_serial *)tty->driver_data; -+ -+#if defined(CONFIG_ETRAX_RS485_ON_PA) -+ *R_PORT_PA_DATA = port_pa_data_shadow |= (1 << rs485_pa_bit); -+#endif -+#if defined(CONFIG_ETRAX_RS485_ON_PORT_G) -+ REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, -+ rs485_port_g_bit, 1); -+#endif -+#if defined(CONFIG_ETRAX_RS485_LTC1387) -+ REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, -+ CONFIG_ETRAX_RS485_LTC1387_DXEN_PORT_G_BIT, 1); -+ REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, -+ CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 1); -+#endif -+ -+ info->rs485 = *r; -+ -+ /* Maximum delay before RTS equal to 1000 */ -+ if (info->rs485.delay_rts_before_send >= 1000) -+ info->rs485.delay_rts_before_send = 1000; -+ -+/* printk("rts: on send = %i, after = %i, enabled = %i", -+ info->rs485.rts_on_send, -+ info->rs485.rts_after_sent, -+ info->rs485.enabled -+ ); -+*/ -+ return 0; -+} -+ -+static int -+e100_write_rs485(struct tty_struct *tty, -+ const unsigned char *buf, int count) -+{ -+ struct e100_serial * info = (struct e100_serial *)tty->driver_data; -+ int old_value = (info->rs485.flags) & SER_RS485_ENABLED; -+ -+ /* rs485 is always implicitly enabled if we're using the ioctl() -+ * but it doesn't have to be set in the serial_rs485 -+ * (to be backward compatible with old apps) -+ * So we store, set and restore it. -+ */ -+ info->rs485.flags |= SER_RS485_ENABLED; -+ /* rs_write now deals with RS485 if enabled */ -+ count = rs_write(tty, buf, count); -+ if (!old_value) -+ info->rs485.flags &= ~(SER_RS485_ENABLED); -+ return count; -+} -+ -+#ifdef CONFIG_ETRAX_FAST_TIMER -+/* Timer function to toggle RTS when using FAST_TIMER */ -+static void rs485_toggle_rts_timer_function(unsigned long data) -+{ -+ struct e100_serial *info = (struct e100_serial *)data; -+ -+ fast_timers_rs485[info->line].function = NULL; -+ e100_rts(info, (info->rs485.flags & SER_RS485_RTS_AFTER_SEND)); -+#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) -+ e100_enable_rx(info); -+ e100_enable_rx_irq(info); -+#endif -+} -+#endif -+#endif /* CONFIG_ETRAX_RS485 */ -+ -+/* -+ * ------------------------------------------------------------ -+ * rs_stop() and rs_start() -+ * -+ * This routines are called before setting or resetting tty->stopped. -+ * They enable or disable transmitter using the XOFF registers, as necessary. -+ * ------------------------------------------------------------ -+ */ -+ -+static void -+rs_stop(struct tty_struct *tty) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ if (info) { -+ unsigned long flags; -+ unsigned long xoff; -+ -+ local_irq_save(flags); -+ DFLOW(DEBUG_LOG(info->line, "XOFF rs_stop xmit %i\n", -+ CIRC_CNT(info->xmit.head, -+ info->xmit.tail,SERIAL_XMIT_SIZE))); -+ -+ xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, -+ STOP_CHAR(info->port.tty)); -+ xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop); -+ if (tty->termios->c_iflag & IXON ) { -+ xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); -+ } -+ -+ *((unsigned long *)&info->ioport[REG_XOFF]) = xoff; -+ local_irq_restore(flags); -+ } -+} -+ -+static void -+rs_start(struct tty_struct *tty) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ if (info) { -+ unsigned long flags; -+ unsigned long xoff; -+ -+ local_irq_save(flags); -+ DFLOW(DEBUG_LOG(info->line, "XOFF rs_start xmit %i\n", -+ CIRC_CNT(info->xmit.head, -+ info->xmit.tail,SERIAL_XMIT_SIZE))); -+ xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty)); -+ xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); -+ if (tty->termios->c_iflag & IXON ) { -+ xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); -+ } -+ -+ *((unsigned long *)&info->ioport[REG_XOFF]) = xoff; -+ if (!info->uses_dma_out && -+ info->xmit.head != info->xmit.tail && info->xmit.buf) -+ e100_enable_serial_tx_ready_irq(info); -+ -+ local_irq_restore(flags); -+ } -+} -+ -+/* -+ * ---------------------------------------------------------------------- -+ * -+ * Here starts the interrupt handling routines. All of the following -+ * subroutines are declared as inline and are folded into -+ * rs_interrupt(). They were separated out for readability's sake. -+ * -+ * Note: rs_interrupt() is a "fast" interrupt, which means that it -+ * runs with interrupts turned off. People who may want to modify -+ * rs_interrupt() should try to keep the interrupt handler as fast as -+ * possible. After you are done making modifications, it is not a bad -+ * idea to do: -+ * -+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c -+ * -+ * and look at the resulting assemble code in serial.s. -+ * -+ * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 -+ * ----------------------------------------------------------------------- -+ */ -+ -+/* -+ * This routine is used by the interrupt handler to schedule -+ * processing in the software interrupt portion of the driver. -+ */ -+static void rs_sched_event(struct e100_serial *info, int event) -+{ -+ if (info->event & (1 << event)) -+ return; -+ info->event |= 1 << event; -+ schedule_work(&info->work); -+} -+ -+/* The output DMA channel is free - use it to send as many chars as possible -+ * NOTES: -+ * We don't pay attention to info->x_char, which means if the TTY wants to -+ * use XON/XOFF it will set info->x_char but we won't send any X char! -+ * -+ * To implement this, we'd just start a DMA send of 1 byte pointing at a -+ * buffer containing the X char, and skip updating xmit. We'd also have to -+ * check if the last sent char was the X char when we enter this function -+ * the next time, to avoid updating xmit with the sent X value. -+ */ -+ -+static void -+transmit_chars_dma(struct e100_serial *info) -+{ -+ unsigned int c, sentl; -+ struct etrax_dma_descr *descr; -+ -+#ifdef CONFIG_SVINTO_SIM -+ /* This will output too little if tail is not 0 always since -+ * we don't reloop to send the other part. Anyway this SHOULD be a -+ * no-op - transmit_chars_dma would never really be called during sim -+ * since rs_write does not write into the xmit buffer then. -+ */ -+ if (info->xmit.tail) -+ printk("Error in serial.c:transmit_chars-dma(), tail!=0\n"); -+ if (info->xmit.head != info->xmit.tail) { -+ SIMCOUT(info->xmit.buf + info->xmit.tail, -+ CIRC_CNT(info->xmit.head, -+ info->xmit.tail, -+ SERIAL_XMIT_SIZE)); -+ info->xmit.head = info->xmit.tail; /* move back head */ -+ info->tr_running = 0; -+ } -+ return; -+#endif -+ /* acknowledge both dma_descr and dma_eop irq in R_DMA_CHx_CLR_INTR */ -+ *info->oclrintradr = -+ IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | -+ IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); -+ -+#ifdef SERIAL_DEBUG_INTR -+ if (info->line == SERIAL_DEBUG_LINE) -+ printk("tc\n"); -+#endif -+ if (!info->tr_running) { -+ /* weirdo... we shouldn't get here! */ -+ printk(KERN_WARNING "Achtung: transmit_chars_dma with !tr_running\n"); -+ return; -+ } -+ -+ descr = &info->tr_descr; -+ -+ /* first get the amount of bytes sent during the last DMA transfer, -+ and update xmit accordingly */ -+ -+ /* if the stop bit was not set, all data has been sent */ -+ if (!(descr->status & d_stop)) { -+ sentl = descr->sw_len; -+ } else -+ /* otherwise we find the amount of data sent here */ -+ sentl = descr->hw_len; -+ -+ DFLOW(DEBUG_LOG(info->line, "TX %i done\n", sentl)); -+ -+ /* update stats */ -+ info->icount.tx += sentl; -+ -+ /* update xmit buffer */ -+ info->xmit.tail = (info->xmit.tail + sentl) & (SERIAL_XMIT_SIZE - 1); -+ -+ /* if there is only a few chars left in the buf, wake up the blocked -+ write if any */ -+ if (CIRC_CNT(info->xmit.head, -+ info->xmit.tail, -+ SERIAL_XMIT_SIZE) < WAKEUP_CHARS) -+ rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); -+ -+ /* find out the largest amount of consecutive bytes we want to send now */ -+ -+ c = CIRC_CNT_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -+ -+ /* Don't send all in one DMA transfer - divide it so we wake up -+ * application before all is sent -+ */ -+ -+ if (c >= 4*WAKEUP_CHARS) -+ c = c/2; -+ -+ if (c <= 0) { -+ /* our job here is done, don't schedule any new DMA transfer */ -+ info->tr_running = 0; -+ -+#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER) -+ if (info->rs485.flags & SER_RS485_ENABLED) { -+ /* Set a short timer to toggle RTS */ -+ start_one_shot_timer(&fast_timers_rs485[info->line], -+ rs485_toggle_rts_timer_function, -+ (unsigned long)info, -+ info->char_time_usec*2, -+ "RS-485"); -+ } -+#endif /* RS485 */ -+ return; -+ } -+ -+ /* ok we can schedule a dma send of c chars starting at info->xmit.tail */ -+ /* set up the descriptor correctly for output */ -+ DFLOW(DEBUG_LOG(info->line, "TX %i\n", c)); -+ descr->ctrl = d_int | d_eol | d_wait; /* Wait needed for tty_wait_until_sent() */ -+ descr->sw_len = c; -+ descr->buf = virt_to_phys(info->xmit.buf + info->xmit.tail); -+ descr->status = 0; -+ -+ *info->ofirstadr = virt_to_phys(descr); /* write to R_DMAx_FIRST */ -+ *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, start); -+ -+ /* DMA is now running (hopefully) */ -+} /* transmit_chars_dma */ -+ -+static void -+start_transmit(struct e100_serial *info) -+{ -+#if 0 -+ if (info->line == SERIAL_DEBUG_LINE) -+ printk("x\n"); -+#endif -+ -+ info->tr_descr.sw_len = 0; -+ info->tr_descr.hw_len = 0; -+ info->tr_descr.status = 0; -+ info->tr_running = 1; -+ if (info->uses_dma_out) -+ transmit_chars_dma(info); -+ else -+ e100_enable_serial_tx_ready_irq(info); -+} /* start_transmit */ -+ -+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER -+static int serial_fast_timer_started = 0; -+static int serial_fast_timer_expired = 0; -+static void flush_timeout_function(unsigned long data); -+#define START_FLUSH_FAST_TIMER_TIME(info, string, usec) {\ -+ unsigned long timer_flags; \ -+ local_irq_save(timer_flags); \ -+ if (fast_timers[info->line].function == NULL) { \ -+ serial_fast_timer_started++; \ -+ TIMERD(DEBUG_LOG(info->line, "start_timer %i ", info->line)); \ -+ TIMERD(DEBUG_LOG(info->line, "num started: %i\n", serial_fast_timer_started)); \ -+ start_one_shot_timer(&fast_timers[info->line], \ -+ flush_timeout_function, \ -+ (unsigned long)info, \ -+ (usec), \ -+ string); \ -+ } \ -+ else { \ -+ TIMERD(DEBUG_LOG(info->line, "timer %i already running\n", info->line)); \ -+ } \ -+ local_irq_restore(timer_flags); \ -+} -+#define START_FLUSH_FAST_TIMER(info, string) START_FLUSH_FAST_TIMER_TIME(info, string, info->flush_time_usec) -+ -+#else -+#define START_FLUSH_FAST_TIMER_TIME(info, string, usec) -+#define START_FLUSH_FAST_TIMER(info, string) -+#endif -+ -+static struct etrax_recv_buffer * -+alloc_recv_buffer(unsigned int size) -+{ -+ struct etrax_recv_buffer *buffer; -+ -+ if (!(buffer = kmalloc(sizeof *buffer + size, GFP_ATOMIC))) -+ return NULL; -+ -+ buffer->next = NULL; -+ buffer->length = 0; -+ buffer->error = TTY_NORMAL; -+ -+ return buffer; -+} -+ -+static void -+append_recv_buffer(struct e100_serial *info, struct etrax_recv_buffer *buffer) -+{ -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ -+ if (!info->first_recv_buffer) -+ info->first_recv_buffer = buffer; -+ else -+ info->last_recv_buffer->next = buffer; -+ -+ info->last_recv_buffer = buffer; -+ -+ info->recv_cnt += buffer->length; -+ if (info->recv_cnt > info->max_recv_cnt) -+ info->max_recv_cnt = info->recv_cnt; -+ -+ local_irq_restore(flags); -+} -+ -+static int -+add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char flag) -+{ -+ struct etrax_recv_buffer *buffer; -+ if (info->uses_dma_in) { -+ if (!(buffer = alloc_recv_buffer(4))) -+ return 0; -+ -+ buffer->length = 1; -+ buffer->error = flag; -+ buffer->buffer[0] = data; -+ -+ append_recv_buffer(info, buffer); -+ -+ info->icount.rx++; -+ } else { -+ struct tty_struct *tty = info->port.tty; -+ tty_insert_flip_char(tty, data, flag); -+ info->icount.rx++; -+ } -+ -+ return 1; -+} -+ -+static unsigned int handle_descr_data(struct e100_serial *info, -+ struct etrax_dma_descr *descr, -+ unsigned int recvl) -+{ -+ struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer; -+ -+ if (info->recv_cnt + recvl > 65536) { -+ printk(KERN_CRIT -+ "%s: Too much pending incoming serial data! Dropping %u bytes.\n", __func__, recvl); -+ return 0; -+ } -+ -+ buffer->length = recvl; -+ -+ if (info->errorcode == ERRCODE_SET_BREAK) -+ buffer->error = TTY_BREAK; -+ info->errorcode = 0; -+ -+ append_recv_buffer(info, buffer); -+ -+ if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE))) -+ panic("%s: Failed to allocate memory for receive buffer!\n", __func__); -+ -+ descr->buf = virt_to_phys(buffer->buffer); -+ -+ return recvl; -+} -+ -+static unsigned int handle_all_descr_data(struct e100_serial *info) -+{ -+ struct etrax_dma_descr *descr; -+ unsigned int recvl; -+ unsigned int ret = 0; -+ -+ while (1) -+ { -+ descr = &info->rec_descr[info->cur_rec_descr]; -+ -+ if (descr == phys_to_virt(*info->idescradr)) -+ break; -+ -+ if (++info->cur_rec_descr == SERIAL_RECV_DESCRIPTORS) -+ info->cur_rec_descr = 0; -+ -+ /* find out how many bytes were read */ -+ -+ /* if the eop bit was not set, all data has been received */ -+ if (!(descr->status & d_eop)) { -+ recvl = descr->sw_len; -+ } else { -+ /* otherwise we find the amount of data received here */ -+ recvl = descr->hw_len; -+ } -+ -+ /* Reset the status information */ -+ descr->status = 0; -+ -+ DFLOW( DEBUG_LOG(info->line, "RX %lu\n", recvl); -+ if (info->port.tty->stopped) { -+ unsigned char *buf = phys_to_virt(descr->buf); -+ DEBUG_LOG(info->line, "rx 0x%02X\n", buf[0]); -+ DEBUG_LOG(info->line, "rx 0x%02X\n", buf[1]); -+ DEBUG_LOG(info->line, "rx 0x%02X\n", buf[2]); -+ } -+ ); -+ -+ /* update stats */ -+ info->icount.rx += recvl; -+ -+ ret += handle_descr_data(info, descr, recvl); -+ } -+ -+ return ret; -+} -+ -+static void receive_chars_dma(struct e100_serial *info) -+{ -+ struct tty_struct *tty; -+ unsigned char rstat; -+ -+#ifdef CONFIG_SVINTO_SIM -+ /* No receive in the simulator. Will probably be when the rest of -+ * the serial interface works, and this piece will just be removed. -+ */ -+ return; -+#endif -+ -+ /* Acknowledge both dma_descr and dma_eop irq in R_DMA_CHx_CLR_INTR */ -+ *info->iclrintradr = -+ IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | -+ IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); -+ -+ tty = info->port.tty; -+ if (!tty) /* Something wrong... */ -+ return; -+ -+#ifdef SERIAL_HANDLE_EARLY_ERRORS -+ if (info->uses_dma_in) -+ e100_enable_serial_data_irq(info); -+#endif -+ -+ if (info->errorcode == ERRCODE_INSERT_BREAK) -+ add_char_and_flag(info, '\0', TTY_BREAK); -+ -+ handle_all_descr_data(info); -+ -+ /* Read the status register to detect errors */ -+ rstat = info->ioport[REG_STATUS]; -+ if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) { -+ DFLOW(DEBUG_LOG(info->line, "XOFF detect stat %x\n", rstat)); -+ } -+ -+ if (rstat & SER_ERROR_MASK) { -+ /* If we got an error, we must reset it by reading the -+ * data_in field -+ */ -+ unsigned char data = info->ioport[REG_DATA]; -+ -+ PROCSTAT(ser_stat[info->line].errors_cnt++); -+ DEBUG_LOG(info->line, "#dERR: s d 0x%04X\n", -+ ((rstat & SER_ERROR_MASK) << 8) | data); -+ -+ if (rstat & SER_PAR_ERR_MASK) -+ add_char_and_flag(info, data, TTY_PARITY); -+ else if (rstat & SER_OVERRUN_MASK) -+ add_char_and_flag(info, data, TTY_OVERRUN); -+ else if (rstat & SER_FRAMING_ERR_MASK) -+ add_char_and_flag(info, data, TTY_FRAME); -+ } -+ -+ START_FLUSH_FAST_TIMER(info, "receive_chars"); -+ -+ /* Restart the receiving DMA */ -+ *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); -+} -+ -+static int start_recv_dma(struct e100_serial *info) -+{ -+ struct etrax_dma_descr *descr = info->rec_descr; -+ struct etrax_recv_buffer *buffer; -+ int i; -+ -+ /* Set up the receiving descriptors */ -+ for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++) { -+ if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE))) -+ panic("%s: Failed to allocate memory for receive buffer!\n", __func__); -+ -+ descr[i].ctrl = d_int; -+ descr[i].buf = virt_to_phys(buffer->buffer); -+ descr[i].sw_len = SERIAL_DESCR_BUF_SIZE; -+ descr[i].hw_len = 0; -+ descr[i].status = 0; -+ descr[i].next = virt_to_phys(&descr[i+1]); -+ } -+ -+ /* Link the last descriptor to the first */ -+ descr[i-1].next = virt_to_phys(&descr[0]); -+ -+ /* Start with the first descriptor in the list */ -+ info->cur_rec_descr = 0; -+ -+ /* Start the DMA */ -+ *info->ifirstadr = virt_to_phys(&descr[info->cur_rec_descr]); -+ *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, start); -+ -+ /* Input DMA should be running now */ -+ return 1; -+} -+ -+static void -+start_receive(struct e100_serial *info) -+{ -+#ifdef CONFIG_SVINTO_SIM -+ /* No receive in the simulator. Will probably be when the rest of -+ * the serial interface works, and this piece will just be removed. -+ */ -+ return; -+#endif -+ if (info->uses_dma_in) { -+ /* reset the input dma channel to be sure it works */ -+ -+ *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); -+ while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) == -+ IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); -+ -+ start_recv_dma(info); -+ } -+} -+ -+ -+/* the bits in the MASK2 register are laid out like this: -+ DMAI_EOP DMAI_DESCR DMAO_EOP DMAO_DESCR -+ where I is the input channel and O is the output channel for the port. -+ info->irq is the bit number for the DMAO_DESCR so to check the others we -+ shift info->irq to the left. -+*/ -+ -+/* dma output channel interrupt handler -+ this interrupt is called from DMA2(ser2), DMA4(ser3), DMA6(ser0) or -+ DMA8(ser1) when they have finished a descriptor with the intr flag set. -+*/ -+ -+static irqreturn_t -+tr_interrupt(int irq, void *dev_id) -+{ -+ struct e100_serial *info; -+ unsigned long ireg; -+ int i; -+ int handled = 0; -+ -+#ifdef CONFIG_SVINTO_SIM -+ /* No receive in the simulator. Will probably be when the rest of -+ * the serial interface works, and this piece will just be removed. -+ */ -+ { -+ const char *s = "What? tr_interrupt in simulator??\n"; -+ SIMCOUT(s,strlen(s)); -+ } -+ return IRQ_HANDLED; -+#endif -+ -+ /* find out the line that caused this irq and get it from rs_table */ -+ -+ ireg = *R_IRQ_MASK2_RD; /* get the active irq bits for the dma channels */ -+ -+ for (i = 0; i < NR_PORTS; i++) { -+ info = rs_table + i; -+ if (!info->enabled || !info->uses_dma_out) -+ continue; -+ /* check for dma_descr (don't need to check for dma_eop in output dma for serial */ -+ if (ireg & info->irq) { -+ handled = 1; -+ /* we can send a new dma bunch. make it so. */ -+ DINTR2(DEBUG_LOG(info->line, "tr_interrupt %i\n", i)); -+ /* Read jiffies_usec first, -+ * we want this time to be as late as possible -+ */ -+ PROCSTAT(ser_stat[info->line].tx_dma_ints++); -+ info->last_tx_active_usec = GET_JIFFIES_USEC(); -+ info->last_tx_active = jiffies; -+ transmit_chars_dma(info); -+ } -+ -+ /* FIXME: here we should really check for a change in the -+ status lines and if so call status_handle(info) */ -+ } -+ return IRQ_RETVAL(handled); -+} /* tr_interrupt */ -+ -+/* dma input channel interrupt handler */ -+ -+static irqreturn_t -+rec_interrupt(int irq, void *dev_id) -+{ -+ struct e100_serial *info; -+ unsigned long ireg; -+ int i; -+ int handled = 0; -+ -+#ifdef CONFIG_SVINTO_SIM -+ /* No receive in the simulator. Will probably be when the rest of -+ * the serial interface works, and this piece will just be removed. -+ */ -+ { -+ const char *s = "What? rec_interrupt in simulator??\n"; -+ SIMCOUT(s,strlen(s)); -+ } -+ return IRQ_HANDLED; -+#endif -+ -+ /* find out the line that caused this irq and get it from rs_table */ -+ -+ ireg = *R_IRQ_MASK2_RD; /* get the active irq bits for the dma channels */ -+ -+ for (i = 0; i < NR_PORTS; i++) { -+ info = rs_table + i; -+ if (!info->enabled || !info->uses_dma_in) -+ continue; -+ /* check for both dma_eop and dma_descr for the input dma channel */ -+ if (ireg & ((info->irq << 2) | (info->irq << 3))) { -+ handled = 1; -+ /* we have received something */ -+ receive_chars_dma(info); -+ } -+ -+ /* FIXME: here we should really check for a change in the -+ status lines and if so call status_handle(info) */ -+ } -+ return IRQ_RETVAL(handled); -+} /* rec_interrupt */ -+ -+static int force_eop_if_needed(struct e100_serial *info) -+{ -+ /* We check data_avail bit to determine if data has -+ * arrived since last time -+ */ -+ unsigned char rstat = info->ioport[REG_STATUS]; -+ -+ /* error or datavail? */ -+ if (rstat & SER_ERROR_MASK) { -+ /* Some error has occurred. If there has been valid data, an -+ * EOP interrupt will be made automatically. If no data, the -+ * normal ser_interrupt should be enabled and handle it. -+ * So do nothing! -+ */ -+ DEBUG_LOG(info->line, "timeout err: rstat 0x%03X\n", -+ rstat | (info->line << 8)); -+ return 0; -+ } -+ -+ if (rstat & SER_DATA_AVAIL_MASK) { -+ /* Ok data, no error, count it */ -+ TIMERD(DEBUG_LOG(info->line, "timeout: rstat 0x%03X\n", -+ rstat | (info->line << 8))); -+ /* Read data to clear status flags */ -+ (void)info->ioport[REG_DATA]; -+ -+ info->forced_eop = 0; -+ START_FLUSH_FAST_TIMER(info, "magic"); -+ return 0; -+ } -+ -+ /* hit the timeout, force an EOP for the input -+ * dma channel if we haven't already -+ */ -+ if (!info->forced_eop) { -+ info->forced_eop = 1; -+ PROCSTAT(ser_stat[info->line].timeout_flush_cnt++); -+ TIMERD(DEBUG_LOG(info->line, "timeout EOP %i\n", info->line)); -+ FORCE_EOP(info); -+ } -+ -+ return 1; -+} -+ -+static void flush_to_flip_buffer(struct e100_serial *info) -+{ -+ struct tty_struct *tty; -+ struct etrax_recv_buffer *buffer; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ tty = info->port.tty; -+ -+ if (!tty) { -+ local_irq_restore(flags); -+ return; -+ } -+ -+ while ((buffer = info->first_recv_buffer) != NULL) { -+ unsigned int count = buffer->length; -+ -+ tty_insert_flip_string(tty, buffer->buffer, count); -+ info->recv_cnt -= count; -+ -+ if (count == buffer->length) { -+ info->first_recv_buffer = buffer->next; -+ kfree(buffer); -+ } else { -+ buffer->length -= count; -+ memmove(buffer->buffer, buffer->buffer + count, buffer->length); -+ buffer->error = TTY_NORMAL; -+ } -+ } -+ -+ if (!info->first_recv_buffer) -+ info->last_recv_buffer = NULL; -+ -+ local_irq_restore(flags); -+ -+ /* This includes a check for low-latency */ -+ tty_flip_buffer_push(tty); -+} -+ -+static void check_flush_timeout(struct e100_serial *info) -+{ -+ /* Flip what we've got (if we can) */ -+ flush_to_flip_buffer(info); -+ -+ /* We might need to flip later, but not to fast -+ * since the system is busy processing input... */ -+ if (info->first_recv_buffer) -+ START_FLUSH_FAST_TIMER_TIME(info, "flip", 2000); -+ -+ /* Force eop last, since data might have come while we're processing -+ * and if we started the slow timer above, we won't start a fast -+ * below. -+ */ -+ force_eop_if_needed(info); -+} -+ -+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER -+static void flush_timeout_function(unsigned long data) -+{ -+ struct e100_serial *info = (struct e100_serial *)data; -+ -+ fast_timers[info->line].function = NULL; -+ serial_fast_timer_expired++; -+ TIMERD(DEBUG_LOG(info->line, "flush_timout %i ", info->line)); -+ TIMERD(DEBUG_LOG(info->line, "num expired: %i\n", serial_fast_timer_expired)); -+ check_flush_timeout(info); -+} -+ -+#else -+ -+/* dma fifo/buffer timeout handler -+ forces an end-of-packet for the dma input channel if no chars -+ have been received for CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS/100 s. -+*/ -+ -+static struct timer_list flush_timer; -+ -+static void -+timed_flush_handler(unsigned long ptr) -+{ -+ struct e100_serial *info; -+ int i; -+ -+#ifdef CONFIG_SVINTO_SIM -+ return; -+#endif -+ -+ for (i = 0; i < NR_PORTS; i++) { -+ info = rs_table + i; -+ if (info->uses_dma_in) -+ check_flush_timeout(info); -+ } -+ -+ /* restart flush timer */ -+ mod_timer(&flush_timer, jiffies + CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS); -+} -+#endif -+ -+#ifdef SERIAL_HANDLE_EARLY_ERRORS -+ -+/* If there is an error (ie break) when the DMA is running and -+ * there are no bytes in the fifo the DMA is stopped and we get no -+ * eop interrupt. Thus we have to monitor the first bytes on a DMA -+ * transfer, and if it is without error we can turn the serial -+ * interrupts off. -+ */ -+ -+/* -+BREAK handling on ETRAX 100: -+ETRAX will generate interrupt although there is no stop bit between the -+characters. -+ -+Depending on how long the break sequence is, the end of the breaksequence -+will look differently: -+| indicates start/end of a character. -+ -+B= Break character (0x00) with framing error. -+E= Error byte with parity error received after B characters. -+F= "Faked" valid byte received immediately after B characters. -+V= Valid byte -+ -+1. -+ B BL ___________________________ V -+.._|__________|__________| |valid data | -+ -+Multiple frame errors with data == 0x00 (B), -+the timing matches up "perfectly" so no extra ending char is detected. -+The RXD pin is 1 in the last interrupt, in that case -+we set info->errorcode = ERRCODE_INSERT_BREAK, but we can't really -+know if another byte will come and this really is case 2. below -+(e.g F=0xFF or 0xFE) -+If RXD pin is 0 we can expect another character (see 2. below). -+ -+ -+2. -+ -+ B B E or F__________________..__ V -+.._|__________|__________|______ | |valid data -+ "valid" or -+ parity error -+ -+Multiple frame errors with data == 0x00 (B), -+but the part of the break trigs is interpreted as a start bit (and possibly -+some 0 bits followed by a number of 1 bits and a stop bit). -+Depending on parity settings etc. this last character can be either -+a fake "valid" char (F) or have a parity error (E). -+ -+If the character is valid it will be put in the buffer, -+we set info->errorcode = ERRCODE_SET_BREAK so the receive interrupt -+will set the flags so the tty will handle it, -+if it's an error byte it will not be put in the buffer -+and we set info->errorcode = ERRCODE_INSERT_BREAK. -+ -+To distinguish a V byte in 1. from an F byte in 2. we keep a timestamp -+of the last faulty char (B) and compares it with the current time: -+If the time elapsed time is less then 2*char_time_usec we will assume -+it's a faked F char and not a Valid char and set -+info->errorcode = ERRCODE_SET_BREAK. -+ -+Flaws in the above solution: -+~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+We use the timer to distinguish a F character from a V character, -+if a V character is to close after the break we might make the wrong decision. -+ -+TODO: The break will be delayed until an F or V character is received. -+ -+*/ -+ -+static -+struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) -+{ -+ unsigned long data_read; -+ struct tty_struct *tty = info->port.tty; -+ -+ if (!tty) { -+ printk("!NO TTY!\n"); -+ return info; -+ } -+ -+ /* Read data and status at the same time */ -+ data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]); -+more_data: -+ if (data_read & IO_MASK(R_SERIAL0_READ, xoff_detect) ) { -+ DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0)); -+ } -+ DINTR2(DEBUG_LOG(info->line, "ser_rx %c\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read))); -+ -+ if (data_read & ( IO_MASK(R_SERIAL0_READ, framing_err) | -+ IO_MASK(R_SERIAL0_READ, par_err) | -+ IO_MASK(R_SERIAL0_READ, overrun) )) { -+ /* An error */ -+ info->last_rx_active_usec = GET_JIFFIES_USEC(); -+ info->last_rx_active = jiffies; -+ DINTR1(DEBUG_LOG(info->line, "ser_rx err stat_data %04X\n", data_read)); -+ DLOG_INT_TRIG( -+ if (!log_int_trig1_pos) { -+ log_int_trig1_pos = log_int_pos; -+ log_int(rdpc(), 0, 0); -+ } -+ ); -+ -+ -+ if ( ((data_read & IO_MASK(R_SERIAL0_READ, data_in)) == 0) && -+ (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) ) { -+ /* Most likely a break, but we get interrupts over and -+ * over again. -+ */ -+ -+ if (!info->break_detected_cnt) { -+ DEBUG_LOG(info->line, "#BRK start\n", 0); -+ } -+ if (data_read & IO_MASK(R_SERIAL0_READ, rxd)) { -+ /* The RX pin is high now, so the break -+ * must be over, but.... -+ * we can't really know if we will get another -+ * last byte ending the break or not. -+ * And we don't know if the byte (if any) will -+ * have an error or look valid. -+ */ -+ DEBUG_LOG(info->line, "# BL BRK\n", 0); -+ info->errorcode = ERRCODE_INSERT_BREAK; -+ } -+ info->break_detected_cnt++; -+ } else { -+ /* The error does not look like a break, but could be -+ * the end of one -+ */ -+ if (info->break_detected_cnt) { -+ DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt); -+ info->errorcode = ERRCODE_INSERT_BREAK; -+ } else { -+ unsigned char data = IO_EXTRACT(R_SERIAL0_READ, -+ data_in, data_read); -+ char flag = TTY_NORMAL; -+ if (info->errorcode == ERRCODE_INSERT_BREAK) { -+ struct tty_struct *tty = info->port.tty; -+ tty_insert_flip_char(tty, 0, flag); -+ info->icount.rx++; -+ } -+ -+ if (data_read & IO_MASK(R_SERIAL0_READ, par_err)) { -+ info->icount.parity++; -+ flag = TTY_PARITY; -+ } else if (data_read & IO_MASK(R_SERIAL0_READ, overrun)) { -+ info->icount.overrun++; -+ flag = TTY_OVERRUN; -+ } else if (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) { -+ info->icount.frame++; -+ flag = TTY_FRAME; -+ } -+ tty_insert_flip_char(tty, data, flag); -+ info->errorcode = 0; -+ } -+ info->break_detected_cnt = 0; -+ } -+ } else if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) { -+ /* No error */ -+ DLOG_INT_TRIG( -+ if (!log_int_trig1_pos) { -+ if (log_int_pos >= log_int_size) { -+ log_int_pos = 0; -+ } -+ log_int_trig0_pos = log_int_pos; -+ log_int(rdpc(), 0, 0); -+ } -+ ); -+ tty_insert_flip_char(tty, -+ IO_EXTRACT(R_SERIAL0_READ, data_in, data_read), -+ TTY_NORMAL); -+ } else { -+ DEBUG_LOG(info->line, "ser_rx int but no data_avail %08lX\n", data_read); -+ } -+ -+ -+ info->icount.rx++; -+ data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]); -+ if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) { -+ DEBUG_LOG(info->line, "ser_rx %c in loop\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read)); -+ goto more_data; -+ } -+ -+ tty_flip_buffer_push(info->port.tty); -+ return info; -+} -+ -+static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) -+{ -+ unsigned char rstat; -+ -+#ifdef SERIAL_DEBUG_INTR -+ printk("Interrupt from serport %d\n", i); -+#endif -+/* DEBUG_LOG(info->line, "ser_interrupt stat %03X\n", rstat | (i << 8)); */ -+ if (!info->uses_dma_in) { -+ return handle_ser_rx_interrupt_no_dma(info); -+ } -+ /* DMA is used */ -+ rstat = info->ioport[REG_STATUS]; -+ if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) { -+ DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0)); -+ } -+ -+ if (rstat & SER_ERROR_MASK) { -+ unsigned char data; -+ -+ info->last_rx_active_usec = GET_JIFFIES_USEC(); -+ info->last_rx_active = jiffies; -+ /* If we got an error, we must reset it by reading the -+ * data_in field -+ */ -+ data = info->ioport[REG_DATA]; -+ DINTR1(DEBUG_LOG(info->line, "ser_rx! %c\n", data)); -+ DINTR1(DEBUG_LOG(info->line, "ser_rx err stat %02X\n", rstat)); -+ if (!data && (rstat & SER_FRAMING_ERR_MASK)) { -+ /* Most likely a break, but we get interrupts over and -+ * over again. -+ */ -+ -+ if (!info->break_detected_cnt) { -+ DEBUG_LOG(info->line, "#BRK start\n", 0); -+ } -+ if (rstat & SER_RXD_MASK) { -+ /* The RX pin is high now, so the break -+ * must be over, but.... -+ * we can't really know if we will get another -+ * last byte ending the break or not. -+ * And we don't know if the byte (if any) will -+ * have an error or look valid. -+ */ -+ DEBUG_LOG(info->line, "# BL BRK\n", 0); -+ info->errorcode = ERRCODE_INSERT_BREAK; -+ } -+ info->break_detected_cnt++; -+ } else { -+ /* The error does not look like a break, but could be -+ * the end of one -+ */ -+ if (info->break_detected_cnt) { -+ DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt); -+ info->errorcode = ERRCODE_INSERT_BREAK; -+ } else { -+ if (info->errorcode == ERRCODE_INSERT_BREAK) { -+ info->icount.brk++; -+ add_char_and_flag(info, '\0', TTY_BREAK); -+ } -+ -+ if (rstat & SER_PAR_ERR_MASK) { -+ info->icount.parity++; -+ add_char_and_flag(info, data, TTY_PARITY); -+ } else if (rstat & SER_OVERRUN_MASK) { -+ info->icount.overrun++; -+ add_char_and_flag(info, data, TTY_OVERRUN); -+ } else if (rstat & SER_FRAMING_ERR_MASK) { -+ info->icount.frame++; -+ add_char_and_flag(info, data, TTY_FRAME); -+ } -+ -+ info->errorcode = 0; -+ } -+ info->break_detected_cnt = 0; -+ DEBUG_LOG(info->line, "#iERR s d %04X\n", -+ ((rstat & SER_ERROR_MASK) << 8) | data); -+ } -+ PROCSTAT(ser_stat[info->line].early_errors_cnt++); -+ } else { /* It was a valid byte, now let the DMA do the rest */ -+ unsigned long curr_time_u = GET_JIFFIES_USEC(); -+ unsigned long curr_time = jiffies; -+ -+ if (info->break_detected_cnt) { -+ /* Detect if this character is a new valid char or the -+ * last char in a break sequence: If LSBits are 0 and -+ * MSBits are high AND the time is close to the -+ * previous interrupt we should discard it. -+ */ -+ long elapsed_usec = -+ (curr_time - info->last_rx_active) * (1000000/HZ) + -+ curr_time_u - info->last_rx_active_usec; -+ if (elapsed_usec < 2*info->char_time_usec) { -+ DEBUG_LOG(info->line, "FBRK %i\n", info->line); -+ /* Report as BREAK (error) and let -+ * receive_chars_dma() handle it -+ */ -+ info->errorcode = ERRCODE_SET_BREAK; -+ } else { -+ DEBUG_LOG(info->line, "Not end of BRK (V)%i\n", info->line); -+ } -+ DEBUG_LOG(info->line, "num brk %i\n", info->break_detected_cnt); -+ } -+ -+#ifdef SERIAL_DEBUG_INTR -+ printk("** OK, disabling ser_interrupts\n"); -+#endif -+ e100_disable_serial_data_irq(info); -+ DINTR2(DEBUG_LOG(info->line, "ser_rx OK %d\n", info->line)); -+ info->break_detected_cnt = 0; -+ -+ PROCSTAT(ser_stat[info->line].ser_ints_ok_cnt++); -+ } -+ /* Restarting the DMA never hurts */ -+ *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); -+ START_FLUSH_FAST_TIMER(info, "ser_int"); -+ return info; -+} /* handle_ser_rx_interrupt */ -+ -+static void handle_ser_tx_interrupt(struct e100_serial *info) -+{ -+ unsigned long flags; -+ -+ if (info->x_char) { -+ unsigned char rstat; -+ DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char)); -+ local_irq_save(flags); -+ rstat = info->ioport[REG_STATUS]; -+ DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); -+ -+ info->ioport[REG_TR_DATA] = info->x_char; -+ info->icount.tx++; -+ info->x_char = 0; -+ /* We must enable since it is disabled in ser_interrupt */ -+ e100_enable_serial_tx_ready_irq(info); -+ local_irq_restore(flags); -+ return; -+ } -+ if (info->uses_dma_out) { -+ unsigned char rstat; -+ int i; -+ /* We only use normal tx interrupt when sending x_char */ -+ DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0)); -+ local_irq_save(flags); -+ rstat = info->ioport[REG_STATUS]; -+ DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); -+ e100_disable_serial_tx_ready_irq(info); -+ if (info->port.tty->stopped) -+ rs_stop(info->port.tty); -+ /* Enable the DMA channel and tell it to continue */ -+ e100_enable_txdma_channel(info); -+ /* Wait 12 cycles before doing the DMA command */ -+ for(i = 6; i > 0; i--) -+ nop(); -+ -+ *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, continue); -+ local_irq_restore(flags); -+ return; -+ } -+ /* Normal char-by-char interrupt */ -+ if (info->xmit.head == info->xmit.tail -+ || info->port.tty->stopped -+ || info->port.tty->hw_stopped) { -+ DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n", -+ info->port.tty->stopped)); -+ e100_disable_serial_tx_ready_irq(info); -+ info->tr_running = 0; -+ return; -+ } -+ DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail])); -+ /* Send a byte, rs485 timing is critical so turn of ints */ -+ local_irq_save(flags); -+ info->ioport[REG_TR_DATA] = info->xmit.buf[info->xmit.tail]; -+ info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); -+ info->icount.tx++; -+ if (info->xmit.head == info->xmit.tail) { -+#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER) -+ if (info->rs485.flags & SER_RS485_ENABLED) { -+ /* Set a short timer to toggle RTS */ -+ start_one_shot_timer(&fast_timers_rs485[info->line], -+ rs485_toggle_rts_timer_function, -+ (unsigned long)info, -+ info->char_time_usec*2, -+ "RS-485"); -+ } -+#endif /* RS485 */ -+ info->last_tx_active_usec = GET_JIFFIES_USEC(); -+ info->last_tx_active = jiffies; -+ e100_disable_serial_tx_ready_irq(info); -+ info->tr_running = 0; -+ DFLOW(DEBUG_LOG(info->line, "tx_int: stop2\n", 0)); -+ } else { -+ /* We must enable since it is disabled in ser_interrupt */ -+ e100_enable_serial_tx_ready_irq(info); -+ } -+ local_irq_restore(flags); -+ -+ if (CIRC_CNT(info->xmit.head, -+ info->xmit.tail, -+ SERIAL_XMIT_SIZE) < WAKEUP_CHARS) -+ rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); -+ -+} /* handle_ser_tx_interrupt */ -+ -+/* result of time measurements: -+ * RX duration 54-60 us when doing something, otherwise 6-9 us -+ * ser_int duration: just sending: 8-15 us normally, up to 73 us -+ */ -+static irqreturn_t -+ser_interrupt(int irq, void *dev_id) -+{ -+ static volatile int tx_started = 0; -+ struct e100_serial *info; -+ int i; -+ unsigned long flags; -+ unsigned long irq_mask1_rd; -+ unsigned long data_mask = (1 << (8+2*0)); /* ser0 data_avail */ -+ int handled = 0; -+ static volatile unsigned long reentered_ready_mask = 0; -+ -+ local_irq_save(flags); -+ irq_mask1_rd = *R_IRQ_MASK1_RD; -+ /* First handle all rx interrupts with ints disabled */ -+ info = rs_table; -+ irq_mask1_rd &= e100_ser_int_mask; -+ for (i = 0; i < NR_PORTS; i++) { -+ /* Which line caused the data irq? */ -+ if (irq_mask1_rd & data_mask) { -+ handled = 1; -+ handle_ser_rx_interrupt(info); -+ } -+ info += 1; -+ data_mask <<= 2; -+ } -+ /* Handle tx interrupts with interrupts enabled so we -+ * can take care of new data interrupts while transmitting -+ * We protect the tx part with the tx_started flag. -+ * We disable the tr_ready interrupts we are about to handle and -+ * unblock the serial interrupt so new serial interrupts may come. -+ * -+ * If we get a new interrupt: -+ * - it migth be due to synchronous serial ports. -+ * - serial irq will be blocked by general irq handler. -+ * - async data will be handled above (sync will be ignored). -+ * - tx_started flag will prevent us from trying to send again and -+ * we will exit fast - no need to unblock serial irq. -+ * - Next (sync) serial interrupt handler will be runned with -+ * disabled interrupt due to restore_flags() at end of function, -+ * so sync handler will not be preempted or reentered. -+ */ -+ if (!tx_started) { -+ unsigned long ready_mask; -+ unsigned long -+ tx_started = 1; -+ /* Only the tr_ready interrupts left */ -+ irq_mask1_rd &= (IO_MASK(R_IRQ_MASK1_RD, ser0_ready) | -+ IO_MASK(R_IRQ_MASK1_RD, ser1_ready) | -+ IO_MASK(R_IRQ_MASK1_RD, ser2_ready) | -+ IO_MASK(R_IRQ_MASK1_RD, ser3_ready)); -+ while (irq_mask1_rd) { -+ /* Disable those we are about to handle */ -+ *R_IRQ_MASK1_CLR = irq_mask1_rd; -+ /* Unblock the serial interrupt */ -+ *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set); -+ -+ local_irq_enable(); -+ ready_mask = (1 << (8+1+2*0)); /* ser0 tr_ready */ -+ info = rs_table; -+ for (i = 0; i < NR_PORTS; i++) { -+ /* Which line caused the ready irq? */ -+ if (irq_mask1_rd & ready_mask) { -+ handled = 1; -+ handle_ser_tx_interrupt(info); -+ } -+ info += 1; -+ ready_mask <<= 2; -+ } -+ /* handle_ser_tx_interrupt enables tr_ready interrupts */ -+ local_irq_disable(); -+ /* Handle reentered TX interrupt */ -+ irq_mask1_rd = reentered_ready_mask; -+ } -+ local_irq_disable(); -+ tx_started = 0; -+ } else { -+ unsigned long ready_mask; -+ ready_mask = irq_mask1_rd & (IO_MASK(R_IRQ_MASK1_RD, ser0_ready) | -+ IO_MASK(R_IRQ_MASK1_RD, ser1_ready) | -+ IO_MASK(R_IRQ_MASK1_RD, ser2_ready) | -+ IO_MASK(R_IRQ_MASK1_RD, ser3_ready)); -+ if (ready_mask) { -+ reentered_ready_mask |= ready_mask; -+ /* Disable those we are about to handle */ -+ *R_IRQ_MASK1_CLR = ready_mask; -+ DFLOW(DEBUG_LOG(SERIAL_DEBUG_LINE, "ser_int reentered with TX %X\n", ready_mask)); -+ } -+ } -+ -+ local_irq_restore(flags); -+ return IRQ_RETVAL(handled); -+} /* ser_interrupt */ -+#endif -+ -+/* -+ * ------------------------------------------------------------------- -+ * Here ends the serial interrupt routines. -+ * ------------------------------------------------------------------- -+ */ -+ -+/* -+ * This routine is used to handle the "bottom half" processing for the -+ * serial driver, known also the "software interrupt" processing. -+ * This processing is done at the kernel interrupt level, after the -+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This -+ * is where time-consuming activities which can not be done in the -+ * interrupt driver proper are done; the interrupt driver schedules -+ * them using rs_sched_event(), and they get done here. -+ */ -+static void -+do_softint(struct work_struct *work) -+{ -+ struct e100_serial *info; -+ struct tty_struct *tty; -+ -+ info = container_of(work, struct e100_serial, work); -+ -+ tty = info->port.tty; -+ if (!tty) -+ return; -+ -+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) -+ tty_wakeup(tty); -+} -+ -+static int -+startup(struct e100_serial * info) -+{ -+ unsigned long flags; -+ unsigned long xmit_page; -+ int i; -+ -+ xmit_page = get_zeroed_page(GFP_KERNEL); -+ if (!xmit_page) -+ return -ENOMEM; -+ -+ local_irq_save(flags); -+ -+ /* if it was already initialized, skip this */ -+ -+ if (info->flags & ASYNC_INITIALIZED) { -+ local_irq_restore(flags); -+ free_page(xmit_page); -+ return 0; -+ } -+ -+ if (info->xmit.buf) -+ free_page(xmit_page); -+ else -+ info->xmit.buf = (unsigned char *) xmit_page; -+ -+#ifdef SERIAL_DEBUG_OPEN -+ printk("starting up ttyS%d (xmit_buf 0x%p)...\n", info->line, info->xmit.buf); -+#endif -+ -+#ifdef CONFIG_SVINTO_SIM -+ /* Bits and pieces collected from below. Better to have them -+ in one ifdef:ed clause than to mix in a lot of ifdefs, -+ right? */ -+ if (info->port.tty) -+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags); -+ -+ info->xmit.head = info->xmit.tail = 0; -+ info->first_recv_buffer = info->last_recv_buffer = NULL; -+ info->recv_cnt = info->max_recv_cnt = 0; -+ -+ for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++) -+ info->rec_descr[i].buf = NULL; -+ -+ /* No real action in the simulator, but may set info important -+ to ioctl. */ -+ change_speed(info); -+#else -+ -+ /* -+ * Clear the FIFO buffers and disable them -+ * (they will be reenabled in change_speed()) -+ */ -+ -+ /* -+ * Reset the DMA channels and make sure their interrupts are cleared -+ */ -+ -+ if (info->dma_in_enabled) { -+ info->uses_dma_in = 1; -+ e100_enable_rxdma_channel(info); -+ -+ *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); -+ -+ /* Wait until reset cycle is complete */ -+ while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) == -+ IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); -+ -+ /* Make sure the irqs are cleared */ -+ *info->iclrintradr = -+ IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | -+ IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); -+ } else { -+ e100_disable_rxdma_channel(info); -+ } -+ -+ if (info->dma_out_enabled) { -+ info->uses_dma_out = 1; -+ e100_enable_txdma_channel(info); -+ *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); -+ -+ while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) == -+ IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); -+ -+ /* Make sure the irqs are cleared */ -+ *info->oclrintradr = -+ IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | -+ IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); -+ } else { -+ e100_disable_txdma_channel(info); -+ } -+ -+ if (info->port.tty) -+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags); -+ -+ info->xmit.head = info->xmit.tail = 0; -+ info->first_recv_buffer = info->last_recv_buffer = NULL; -+ info->recv_cnt = info->max_recv_cnt = 0; -+ -+ for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++) -+ info->rec_descr[i].buf = 0; -+ -+ /* -+ * and set the speed and other flags of the serial port -+ * this will start the rx/tx as well -+ */ -+#ifdef SERIAL_HANDLE_EARLY_ERRORS -+ e100_enable_serial_data_irq(info); -+#endif -+ change_speed(info); -+ -+ /* dummy read to reset any serial errors */ -+ -+ (void)info->ioport[REG_DATA]; -+ -+ /* enable the interrupts */ -+ if (info->uses_dma_out) -+ e100_enable_txdma_irq(info); -+ -+ e100_enable_rx_irq(info); -+ -+ info->tr_running = 0; /* to be sure we don't lock up the transmitter */ -+ -+ /* setup the dma input descriptor and start dma */ -+ -+ start_receive(info); -+ -+ /* for safety, make sure the descriptors last result is 0 bytes written */ -+ -+ info->tr_descr.sw_len = 0; -+ info->tr_descr.hw_len = 0; -+ info->tr_descr.status = 0; -+ -+ /* enable RTS/DTR last */ -+ -+ e100_rts(info, 1); -+ e100_dtr(info, 1); -+ -+#endif /* CONFIG_SVINTO_SIM */ -+ -+ info->flags |= ASYNC_INITIALIZED; -+ -+ local_irq_restore(flags); -+ return 0; -+} -+ -+/* -+ * This routine will shutdown a serial port; interrupts are disabled, and -+ * DTR is dropped if the hangup on close termio flag is on. -+ */ -+static void -+shutdown(struct e100_serial * info) -+{ -+ unsigned long flags; -+ struct etrax_dma_descr *descr = info->rec_descr; -+ struct etrax_recv_buffer *buffer; -+ int i; -+ -+#ifndef CONFIG_SVINTO_SIM -+ /* shut down the transmitter and receiver */ -+ DFLOW(DEBUG_LOG(info->line, "shutdown %i\n", info->line)); -+ e100_disable_rx(info); -+ info->ioport[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40); -+ -+ /* disable interrupts, reset dma channels */ -+ if (info->uses_dma_in) { -+ e100_disable_rxdma_irq(info); -+ *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); -+ info->uses_dma_in = 0; -+ } else { -+ e100_disable_serial_data_irq(info); -+ } -+ -+ if (info->uses_dma_out) { -+ e100_disable_txdma_irq(info); -+ info->tr_running = 0; -+ *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); -+ info->uses_dma_out = 0; -+ } else { -+ e100_disable_serial_tx_ready_irq(info); -+ info->tr_running = 0; -+ } -+ -+#endif /* CONFIG_SVINTO_SIM */ -+ -+ if (!(info->flags & ASYNC_INITIALIZED)) -+ return; -+ -+#ifdef SERIAL_DEBUG_OPEN -+ printk("Shutting down serial port %d (irq %d)....\n", info->line, -+ info->irq); -+#endif -+ -+ local_irq_save(flags); -+ -+ if (info->xmit.buf) { -+ free_page((unsigned long)info->xmit.buf); -+ info->xmit.buf = NULL; -+ } -+ -+ for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++) -+ if (descr[i].buf) { -+ buffer = phys_to_virt(descr[i].buf) - sizeof *buffer; -+ kfree(buffer); -+ descr[i].buf = 0; -+ } -+ -+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) { -+ /* hang up DTR and RTS if HUPCL is enabled */ -+ e100_dtr(info, 0); -+ e100_rts(info, 0); /* could check CRTSCTS before doing this */ -+ } -+ -+ if (info->port.tty) -+ set_bit(TTY_IO_ERROR, &info->port.tty->flags); -+ -+ info->flags &= ~ASYNC_INITIALIZED; -+ local_irq_restore(flags); -+} -+ -+ -+/* change baud rate and other assorted parameters */ -+ -+static void -+change_speed(struct e100_serial *info) -+{ -+ unsigned int cflag; -+ unsigned long xoff; -+ unsigned long flags; -+ /* first some safety checks */ -+ -+ if (!info->port.tty || !info->port.tty->termios) -+ return; -+ if (!info->ioport) -+ return; -+ -+ cflag = info->port.tty->termios->c_cflag; -+ -+ /* possibly, the tx/rx should be disabled first to do this safely */ -+ -+ /* change baud-rate and write it to the hardware */ -+ if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) { -+ /* Special baudrate */ -+ u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */ -+ unsigned long alt_source = -+ IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, normal) | -+ IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, normal); -+ /* R_ALT_SER_BAUDRATE selects the source */ -+ DBAUD(printk("Custom baudrate: baud_base/divisor %lu/%i\n", -+ (unsigned long)info->baud_base, info->custom_divisor)); -+ if (info->baud_base == SERIAL_PRESCALE_BASE) { -+ /* 0, 2-65535 (0=65536) */ -+ u16 divisor = info->custom_divisor; -+ /* R_SERIAL_PRESCALE (upper 16 bits of R_CLOCK_PRESCALE) */ -+ /* baudrate is 3.125MHz/custom_divisor */ -+ alt_source = -+ IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, prescale) | -+ IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, prescale); -+ alt_source = 0x11; -+ DBAUD(printk("Writing SERIAL_PRESCALE: divisor %i\n", divisor)); -+ *R_SERIAL_PRESCALE = divisor; -+ info->baud = SERIAL_PRESCALE_BASE/divisor; -+ } -+#ifdef CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED -+ else if ((info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8 && -+ info->custom_divisor == 1) || -+ (info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ && -+ info->custom_divisor == 8)) { -+ /* ext_clk selected */ -+ alt_source = -+ IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, extern) | -+ IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, extern); -+ DBAUD(printk("using external baudrate: %lu\n", CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8)); -+ info->baud = CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8; -+ } -+#endif -+ else -+ { -+ /* Bad baudbase, we don't support using timer0 -+ * for baudrate. -+ */ -+ printk(KERN_WARNING "Bad baud_base/custom_divisor: %lu/%i\n", -+ (unsigned long)info->baud_base, info->custom_divisor); -+ } -+ r_alt_ser_baudrate_shadow &= ~mask; -+ r_alt_ser_baudrate_shadow |= (alt_source << (info->line*8)); -+ *R_ALT_SER_BAUDRATE = r_alt_ser_baudrate_shadow; -+ } else { -+ /* Normal baudrate */ -+ /* Make sure we use normal baudrate */ -+ u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */ -+ unsigned long alt_source = -+ IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, normal) | -+ IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, normal); -+ r_alt_ser_baudrate_shadow &= ~mask; -+ r_alt_ser_baudrate_shadow |= (alt_source << (info->line*8)); -+#ifndef CONFIG_SVINTO_SIM -+ *R_ALT_SER_BAUDRATE = r_alt_ser_baudrate_shadow; -+#endif /* CONFIG_SVINTO_SIM */ -+ -+ info->baud = cflag_to_baud(cflag); -+#ifndef CONFIG_SVINTO_SIM -+ info->ioport[REG_BAUD] = cflag_to_etrax_baud(cflag); -+#endif /* CONFIG_SVINTO_SIM */ -+ } -+ -+#ifndef CONFIG_SVINTO_SIM -+ /* start with default settings and then fill in changes */ -+ local_irq_save(flags); -+ /* 8 bit, no/even parity */ -+ info->rx_ctrl &= ~(IO_MASK(R_SERIAL0_REC_CTRL, rec_bitnr) | -+ IO_MASK(R_SERIAL0_REC_CTRL, rec_par_en) | -+ IO_MASK(R_SERIAL0_REC_CTRL, rec_par)); -+ -+ /* 8 bit, no/even parity, 1 stop bit, no cts */ -+ info->tx_ctrl &= ~(IO_MASK(R_SERIAL0_TR_CTRL, tr_bitnr) | -+ IO_MASK(R_SERIAL0_TR_CTRL, tr_par_en) | -+ IO_MASK(R_SERIAL0_TR_CTRL, tr_par) | -+ IO_MASK(R_SERIAL0_TR_CTRL, stop_bits) | -+ IO_MASK(R_SERIAL0_TR_CTRL, auto_cts)); -+ -+ if ((cflag & CSIZE) == CS7) { -+ /* set 7 bit mode */ -+ info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit); -+ info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit); -+ } -+ -+ if (cflag & CSTOPB) { -+ /* set 2 stop bit mode */ -+ info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, stop_bits, two_bits); -+ } -+ -+ if (cflag & PARENB) { -+ /* enable parity */ -+ info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable); -+ info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable); -+ } -+ -+ if (cflag & CMSPAR) { -+ /* enable stick parity, PARODD mean Mark which matches ETRAX */ -+ info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_stick_par, stick); -+ info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, stick); -+ } -+ if (cflag & PARODD) { -+ /* set odd parity (or Mark if CMSPAR) */ -+ info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); -+ info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); -+ } -+ -+ if (cflag & CRTSCTS) { -+ /* enable automatic CTS handling */ -+ DFLOW(DEBUG_LOG(info->line, "FLOW auto_cts enabled\n", 0)); -+ info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, active); -+ } -+ -+ /* make sure the tx and rx are enabled */ -+ -+ info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable); -+ info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable); -+ -+ /* actually write the control regs to the hardware */ -+ -+ info->ioport[REG_TR_CTRL] = info->tx_ctrl; -+ info->ioport[REG_REC_CTRL] = info->rx_ctrl; -+ xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty)); -+ xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); -+ if (info->port.tty->termios->c_iflag & IXON ) { -+ DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n", -+ STOP_CHAR(info->port.tty))); -+ xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); -+ } -+ -+ *((unsigned long *)&info->ioport[REG_XOFF]) = xoff; -+ local_irq_restore(flags); -+#endif /* !CONFIG_SVINTO_SIM */ -+ -+ update_char_time(info); -+ -+} /* change_speed */ -+ -+/* start transmitting chars NOW */ -+ -+static void -+rs_flush_chars(struct tty_struct *tty) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ unsigned long flags; -+ -+ if (info->tr_running || -+ info->xmit.head == info->xmit.tail || -+ tty->stopped || -+ tty->hw_stopped || -+ !info->xmit.buf) -+ return; -+ -+#ifdef SERIAL_DEBUG_FLOW -+ printk("rs_flush_chars\n"); -+#endif -+ -+ /* this protection might not exactly be necessary here */ -+ -+ local_irq_save(flags); -+ start_transmit(info); -+ local_irq_restore(flags); -+} -+ -+static int rs_raw_write(struct tty_struct *tty, -+ const unsigned char *buf, int count) -+{ -+ int c, ret = 0; -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ unsigned long flags; -+ -+ /* first some sanity checks */ -+ -+ if (!tty || !info->xmit.buf || !tmp_buf) -+ return 0; -+ -+#ifdef SERIAL_DEBUG_DATA -+ if (info->line == SERIAL_DEBUG_LINE) -+ printk("rs_raw_write (%d), status %d\n", -+ count, info->ioport[REG_STATUS]); -+#endif -+ -+#ifdef CONFIG_SVINTO_SIM -+ /* Really simple. The output is here and now. */ -+ SIMCOUT(buf, count); -+ return count; -+#endif -+ local_save_flags(flags); -+ DFLOW(DEBUG_LOG(info->line, "write count %i ", count)); -+ DFLOW(DEBUG_LOG(info->line, "ldisc %i\n", tty->ldisc.chars_in_buffer(tty))); -+ -+ -+ /* The local_irq_disable/restore_flags pairs below are needed -+ * because the DMA interrupt handler moves the info->xmit values. -+ * the memcpy needs to be in the critical region unfortunately, -+ * because we need to read xmit values, memcpy, write xmit values -+ * in one atomic operation... this could perhaps be avoided by -+ * more clever design. -+ */ -+ local_irq_disable(); -+ while (count) { -+ c = CIRC_SPACE_TO_END(info->xmit.head, -+ info->xmit.tail, -+ SERIAL_XMIT_SIZE); -+ -+ if (count < c) -+ c = count; -+ if (c <= 0) -+ break; -+ -+ memcpy(info->xmit.buf + info->xmit.head, buf, c); -+ info->xmit.head = (info->xmit.head + c) & -+ (SERIAL_XMIT_SIZE-1); -+ buf += c; -+ count -= c; -+ ret += c; -+ } -+ local_irq_restore(flags); -+ -+ /* enable transmitter if not running, unless the tty is stopped -+ * this does not need IRQ protection since if tr_running == 0 -+ * the IRQ's are not running anyway for this port. -+ */ -+ DFLOW(DEBUG_LOG(info->line, "write ret %i\n", ret)); -+ -+ if (info->xmit.head != info->xmit.tail && -+ !tty->stopped && -+ !tty->hw_stopped && -+ !info->tr_running) { -+ start_transmit(info); -+ } -+ -+ return ret; -+} /* raw_raw_write() */ -+ -+static int -+rs_write(struct tty_struct *tty, -+ const unsigned char *buf, int count) -+{ -+#if defined(CONFIG_ETRAX_RS485) -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ -+ if (info->rs485.flags & SER_RS485_ENABLED) -+ { -+ /* If we are in RS-485 mode, we need to toggle RTS and disable -+ * the receiver before initiating a DMA transfer -+ */ -+#ifdef CONFIG_ETRAX_FAST_TIMER -+ /* Abort any started timer */ -+ fast_timers_rs485[info->line].function = NULL; -+ del_fast_timer(&fast_timers_rs485[info->line]); -+#endif -+ e100_rts(info, (info->rs485.flags & SER_RS485_RTS_ON_SEND)); -+#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) -+ e100_disable_rx(info); -+ e100_enable_rx_irq(info); -+#endif -+ if ((info->rs485.flags & SER_RS485_RTS_BEFORE_SEND) && -+ (info->rs485.delay_rts_before_send > 0)) -+ msleep(info->rs485.delay_rts_before_send); -+ } -+#endif /* CONFIG_ETRAX_RS485 */ -+ -+ count = rs_raw_write(tty, buf, count); -+ -+#if defined(CONFIG_ETRAX_RS485) -+ if (info->rs485.flags & SER_RS485_ENABLED) -+ { -+ unsigned int val; -+ /* If we are in RS-485 mode the following has to be done: -+ * wait until DMA is ready -+ * wait on transmit shift register -+ * toggle RTS -+ * enable the receiver -+ */ -+ -+ /* Sleep until all sent */ -+ tty_wait_until_sent(tty, 0); -+#ifdef CONFIG_ETRAX_FAST_TIMER -+ /* Now sleep a little more so that shift register is empty */ -+ schedule_usleep(info->char_time_usec * 2); -+#endif -+ /* wait on transmit shift register */ -+ do{ -+ get_lsr_info(info, &val); -+ }while (!(val & TIOCSER_TEMT)); -+ -+ e100_rts(info, (info->rs485.flags & SER_RS485_RTS_AFTER_SEND)); -+ -+#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) -+ e100_enable_rx(info); -+ e100_enable_rxdma_irq(info); -+#endif -+ } -+#endif /* CONFIG_ETRAX_RS485 */ -+ -+ return count; -+} /* rs_write */ -+ -+ -+/* how much space is available in the xmit buffer? */ -+ -+static int -+rs_write_room(struct tty_struct *tty) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ -+ return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -+} -+ -+/* How many chars are in the xmit buffer? -+ * This does not include any chars in the transmitter FIFO. -+ * Use wait_until_sent for waiting for FIFO drain. -+ */ -+ -+static int -+rs_chars_in_buffer(struct tty_struct *tty) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ -+ return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -+} -+ -+/* discard everything in the xmit buffer */ -+ -+static void -+rs_flush_buffer(struct tty_struct *tty) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ info->xmit.head = info->xmit.tail = 0; -+ local_irq_restore(flags); -+ -+ tty_wakeup(tty); -+} -+ -+/* -+ * This function is used to send a high-priority XON/XOFF character to -+ * the device -+ * -+ * Since we use DMA we don't check for info->x_char in transmit_chars_dma(), -+ * but we do it in handle_ser_tx_interrupt(). -+ * We disable DMA channel and enable tx ready interrupt and write the -+ * character when possible. -+ */ -+static void rs_send_xchar(struct tty_struct *tty, char ch) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ unsigned long flags; -+ local_irq_save(flags); -+ if (info->uses_dma_out) { -+ /* Put the DMA on hold and disable the channel */ -+ *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, hold); -+ while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) != -+ IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, hold)); -+ e100_disable_txdma_channel(info); -+ } -+ -+ /* Must make sure transmitter is not stopped before we can transmit */ -+ if (tty->stopped) -+ rs_start(tty); -+ -+ /* Enable manual transmit interrupt and send from there */ -+ DFLOW(DEBUG_LOG(info->line, "rs_send_xchar 0x%02X\n", ch)); -+ info->x_char = ch; -+ e100_enable_serial_tx_ready_irq(info); -+ local_irq_restore(flags); -+} -+ -+/* -+ * ------------------------------------------------------------ -+ * rs_throttle() -+ * -+ * This routine is called by the upper-layer tty layer to signal that -+ * incoming characters should be throttled. -+ * ------------------------------------------------------------ -+ */ -+static void -+rs_throttle(struct tty_struct * tty) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+#ifdef SERIAL_DEBUG_THROTTLE -+ char buf[64]; -+ -+ printk("throttle %s: %lu....\n", tty_name(tty, buf), -+ (unsigned long)tty->ldisc.chars_in_buffer(tty)); -+#endif -+ DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty))); -+ -+ /* Do RTS before XOFF since XOFF might take some time */ -+ if (tty->termios->c_cflag & CRTSCTS) { -+ /* Turn off RTS line */ -+ e100_rts(info, 0); -+ } -+ if (I_IXOFF(tty)) -+ rs_send_xchar(tty, STOP_CHAR(tty)); -+ -+} -+ -+static void -+rs_unthrottle(struct tty_struct * tty) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+#ifdef SERIAL_DEBUG_THROTTLE -+ char buf[64]; -+ -+ printk("unthrottle %s: %lu....\n", tty_name(tty, buf), -+ (unsigned long)tty->ldisc.chars_in_buffer(tty)); -+#endif -+ DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty))); -+ DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count)); -+ /* Do RTS before XOFF since XOFF might take some time */ -+ if (tty->termios->c_cflag & CRTSCTS) { -+ /* Assert RTS line */ -+ e100_rts(info, 1); -+ } -+ -+ if (I_IXOFF(tty)) { -+ if (info->x_char) -+ info->x_char = 0; -+ else -+ rs_send_xchar(tty, START_CHAR(tty)); -+ } -+ -+} -+ -+/* -+ * ------------------------------------------------------------ -+ * rs_ioctl() and friends -+ * ------------------------------------------------------------ -+ */ -+ -+static int -+get_serial_info(struct e100_serial * info, -+ struct serial_struct * retinfo) -+{ -+ struct serial_struct tmp; -+ -+ /* this is all probably wrong, there are a lot of fields -+ * here that we don't have in e100_serial and maybe we -+ * should set them to something else than 0. -+ */ -+ -+ if (!retinfo) -+ return -EFAULT; -+ memset(&tmp, 0, sizeof(tmp)); -+ tmp.type = info->type; -+ tmp.line = info->line; -+ tmp.port = (int)info->ioport; -+ tmp.irq = info->irq; -+ tmp.flags = info->flags; -+ tmp.baud_base = info->baud_base; -+ tmp.close_delay = info->close_delay; -+ tmp.closing_wait = info->closing_wait; -+ tmp.custom_divisor = info->custom_divisor; -+ if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) -+ return -EFAULT; -+ return 0; -+} -+ -+static int -+set_serial_info(struct e100_serial *info, -+ struct serial_struct *new_info) -+{ -+ struct serial_struct new_serial; -+ struct e100_serial old_info; -+ int retval = 0; -+ -+ if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) -+ return -EFAULT; -+ -+ old_info = *info; -+ -+ if (!capable(CAP_SYS_ADMIN)) { -+ if ((new_serial.type != info->type) || -+ (new_serial.close_delay != info->close_delay) || -+ ((new_serial.flags & ~ASYNC_USR_MASK) != -+ (info->flags & ~ASYNC_USR_MASK))) -+ return -EPERM; -+ info->flags = ((info->flags & ~ASYNC_USR_MASK) | -+ (new_serial.flags & ASYNC_USR_MASK)); -+ goto check_and_exit; -+ } -+ -+ if (info->count > 1) -+ return -EBUSY; -+ -+ /* -+ * OK, past this point, all the error checking has been done. -+ * At this point, we start making changes..... -+ */ -+ -+ info->baud_base = new_serial.baud_base; -+ info->flags = ((info->flags & ~ASYNC_FLAGS) | -+ (new_serial.flags & ASYNC_FLAGS)); -+ info->custom_divisor = new_serial.custom_divisor; -+ info->type = new_serial.type; -+ info->close_delay = new_serial.close_delay; -+ info->closing_wait = new_serial.closing_wait; -+ info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; -+ -+ check_and_exit: -+ if (info->flags & ASYNC_INITIALIZED) { -+ change_speed(info); -+ } else -+ retval = startup(info); -+ return retval; -+} -+ -+/* -+ * get_lsr_info - get line status register info -+ * -+ * Purpose: Let user call ioctl() to get info when the UART physically -+ * is emptied. On bus types like RS485, the transmitter must -+ * release the bus after transmitting. This must be done when -+ * the transmit shift register is empty, not be done when the -+ * transmit holding register is empty. This functionality -+ * allows an RS485 driver to be written in user space. -+ */ -+static int -+get_lsr_info(struct e100_serial * info, unsigned int *value) -+{ -+ unsigned int result = TIOCSER_TEMT; -+#ifndef CONFIG_SVINTO_SIM -+ unsigned long curr_time = jiffies; -+ unsigned long curr_time_usec = GET_JIFFIES_USEC(); -+ unsigned long elapsed_usec = -+ (curr_time - info->last_tx_active) * 1000000/HZ + -+ curr_time_usec - info->last_tx_active_usec; -+ -+ if (info->xmit.head != info->xmit.tail || -+ elapsed_usec < 2*info->char_time_usec) { -+ result = 0; -+ } -+#endif -+ -+ if (copy_to_user(value, &result, sizeof(int))) -+ return -EFAULT; -+ return 0; -+} -+ -+#ifdef SERIAL_DEBUG_IO -+struct state_str -+{ -+ int state; -+ const char *str; -+}; -+ -+const struct state_str control_state_str[] = { -+ {TIOCM_DTR, "DTR" }, -+ {TIOCM_RTS, "RTS"}, -+ {TIOCM_ST, "ST?" }, -+ {TIOCM_SR, "SR?" }, -+ {TIOCM_CTS, "CTS" }, -+ {TIOCM_CD, "CD" }, -+ {TIOCM_RI, "RI" }, -+ {TIOCM_DSR, "DSR" }, -+ {0, NULL } -+}; -+ -+char *get_control_state_str(int MLines, char *s) -+{ -+ int i = 0; -+ -+ s[0]='\0'; -+ while (control_state_str[i].str != NULL) { -+ if (MLines & control_state_str[i].state) { -+ if (s[0] != '\0') { -+ strcat(s, ", "); -+ } -+ strcat(s, control_state_str[i].str); -+ } -+ i++; -+ } -+ return s; -+} -+#endif -+ -+static int -+rs_break(struct tty_struct *tty, int break_state) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ unsigned long flags; -+ -+ if (!info->ioport) -+ return -EIO; -+ -+ local_irq_save(flags); -+ if (break_state == -1) { -+ /* Go to manual mode and set the txd pin to 0 */ -+ /* Clear bit 7 (txd) and 6 (tr_enable) */ -+ info->tx_ctrl &= 0x3F; -+ } else { -+ /* Set bit 7 (txd) and 6 (tr_enable) */ -+ info->tx_ctrl |= (0x80 | 0x40); -+ } -+ info->ioport[REG_TR_CTRL] = info->tx_ctrl; -+ local_irq_restore(flags); -+ return 0; -+} -+ -+static int -+rs_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ -+ if (clear & TIOCM_RTS) -+ e100_rts(info, 0); -+ if (clear & TIOCM_DTR) -+ e100_dtr(info, 0); -+ /* Handle FEMALE behaviour */ -+ if (clear & TIOCM_RI) -+ e100_ri_out(info, 0); -+ if (clear & TIOCM_CD) -+ e100_cd_out(info, 0); -+ -+ if (set & TIOCM_RTS) -+ e100_rts(info, 1); -+ if (set & TIOCM_DTR) -+ e100_dtr(info, 1); -+ /* Handle FEMALE behaviour */ -+ if (set & TIOCM_RI) -+ e100_ri_out(info, 1); -+ if (set & TIOCM_CD) -+ e100_cd_out(info, 1); -+ -+ local_irq_restore(flags); -+ return 0; -+} -+ -+static int -+rs_tiocmget(struct tty_struct *tty) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ unsigned int result; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ -+ result = -+ (!E100_RTS_GET(info) ? TIOCM_RTS : 0) -+ | (!E100_DTR_GET(info) ? TIOCM_DTR : 0) -+ | (!E100_RI_GET(info) ? TIOCM_RNG : 0) -+ | (!E100_DSR_GET(info) ? TIOCM_DSR : 0) -+ | (!E100_CD_GET(info) ? TIOCM_CAR : 0) -+ | (!E100_CTS_GET(info) ? TIOCM_CTS : 0); -+ -+ local_irq_restore(flags); -+ -+#ifdef SERIAL_DEBUG_IO -+ printk(KERN_DEBUG "ser%i: modem state: %i 0x%08X\n", -+ info->line, result, result); -+ { -+ char s[100]; -+ -+ get_control_state_str(result, s); -+ printk(KERN_DEBUG "state: %s\n", s); -+ } -+#endif -+ return result; -+ -+} -+ -+ -+static int -+rs_ioctl(struct tty_struct *tty, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct e100_serial * info = (struct e100_serial *)tty->driver_data; -+ -+ if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && -+ (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && -+ (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { -+ if (tty->flags & (1 << TTY_IO_ERROR)) -+ return -EIO; -+ } -+ -+ switch (cmd) { -+ case TIOCGSERIAL: -+ return get_serial_info(info, -+ (struct serial_struct *) arg); -+ case TIOCSSERIAL: -+ return set_serial_info(info, -+ (struct serial_struct *) arg); -+ case TIOCSERGETLSR: /* Get line status register */ -+ return get_lsr_info(info, (unsigned int *) arg); -+ -+ case TIOCSERGSTRUCT: -+ if (copy_to_user((struct e100_serial *) arg, -+ info, sizeof(struct e100_serial))) -+ return -EFAULT; -+ return 0; -+ -+#if defined(CONFIG_ETRAX_RS485) -+ case TIOCSERSETRS485: -+ { -+ /* In this ioctl we still use the old structure -+ * rs485_control for backward compatibility -+ * (if we use serial_rs485, then old user-level code -+ * wouldn't work anymore...). -+ * The use of this ioctl is deprecated: use TIOCSRS485 -+ * instead.*/ -+ struct rs485_control rs485ctrl; -+ struct serial_rs485 rs485data; -+ printk(KERN_DEBUG "The use of this ioctl is deprecated. Use TIOCSRS485 instead\n"); -+ if (copy_from_user(&rs485ctrl, (struct rs485_control *)arg, -+ sizeof(rs485ctrl))) -+ return -EFAULT; -+ -+ rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send; -+ rs485data.flags = 0; -+ if (rs485data.delay_rts_before_send != 0) -+ rs485data.flags |= SER_RS485_RTS_BEFORE_SEND; -+ else -+ rs485data.flags &= ~(SER_RS485_RTS_BEFORE_SEND); -+ -+ if (rs485ctrl.enabled) -+ rs485data.flags |= SER_RS485_ENABLED; -+ else -+ rs485data.flags &= ~(SER_RS485_ENABLED); -+ -+ if (rs485ctrl.rts_on_send) -+ rs485data.flags |= SER_RS485_RTS_ON_SEND; -+ else -+ rs485data.flags &= ~(SER_RS485_RTS_ON_SEND); -+ -+ if (rs485ctrl.rts_after_sent) -+ rs485data.flags |= SER_RS485_RTS_AFTER_SEND; -+ else -+ rs485data.flags &= ~(SER_RS485_RTS_AFTER_SEND); -+ -+ return e100_enable_rs485(tty, &rs485data); -+ } -+ -+ case TIOCSRS485: -+ { -+ /* This is the new version of TIOCSRS485, with new -+ * data structure serial_rs485 */ -+ struct serial_rs485 rs485data; -+ if (copy_from_user(&rs485data, (struct rs485_control *)arg, -+ sizeof(rs485data))) -+ return -EFAULT; -+ -+ return e100_enable_rs485(tty, &rs485data); -+ } -+ -+ case TIOCGRS485: -+ { -+ struct serial_rs485 *rs485data = -+ &(((struct e100_serial *)tty->driver_data)->rs485); -+ /* This is the ioctl to get RS485 data from user-space */ -+ if (copy_to_user((struct serial_rs485 *) arg, -+ rs485data, -+ sizeof(struct serial_rs485))) -+ return -EFAULT; -+ break; -+ } -+ -+ case TIOCSERWRRS485: -+ { -+ struct rs485_write rs485wr; -+ if (copy_from_user(&rs485wr, (struct rs485_write *)arg, -+ sizeof(rs485wr))) -+ return -EFAULT; -+ -+ return e100_write_rs485(tty, rs485wr.outc, rs485wr.outc_size); -+ } -+#endif -+ -+ default: -+ return -ENOIOCTLCMD; -+ } -+ return 0; -+} -+ -+static void -+rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -+{ -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ -+ change_speed(info); -+ -+ /* Handle turning off CRTSCTS */ -+ if ((old_termios->c_cflag & CRTSCTS) && -+ !(tty->termios->c_cflag & CRTSCTS)) { -+ tty->hw_stopped = 0; -+ rs_start(tty); -+ } -+ -+} -+ -+/* -+ * ------------------------------------------------------------ -+ * rs_close() -+ * -+ * This routine is called when the serial port gets closed. First, we -+ * wait for the last remaining data to be sent. Then, we unlink its -+ * S structure from the interrupt chain if necessary, and we free -+ * that IRQ if nothing is left in the chain. -+ * ------------------------------------------------------------ -+ */ -+static void -+rs_close(struct tty_struct *tty, struct file * filp) -+{ -+ struct e100_serial * info = (struct e100_serial *)tty->driver_data; -+ unsigned long flags; -+ -+ if (!info) -+ return; -+ -+ /* interrupts are disabled for this entire function */ -+ -+ local_irq_save(flags); -+ -+ if (tty_hung_up_p(filp)) { -+ local_irq_restore(flags); -+ return; -+ } -+ -+#ifdef SERIAL_DEBUG_OPEN -+ printk("[%d] rs_close ttyS%d, count = %d\n", current->pid, -+ info->line, info->count); -+#endif -+ if ((tty->count == 1) && (info->count != 1)) { -+ /* -+ * Uh, oh. tty->count is 1, which means that the tty -+ * structure will be freed. Info->count should always -+ * be one in these conditions. If it's greater than -+ * one, we've got real problems, since it means the -+ * serial port won't be shutdown. -+ */ -+ printk(KERN_CRIT -+ "rs_close: bad serial port count; tty->count is 1, " -+ "info->count is %d\n", info->count); -+ info->count = 1; -+ } -+ if (--info->count < 0) { -+ printk(KERN_CRIT "rs_close: bad serial port count for ttyS%d: %d\n", -+ info->line, info->count); -+ info->count = 0; -+ } -+ if (info->count) { -+ local_irq_restore(flags); -+ return; -+ } -+ info->flags |= ASYNC_CLOSING; -+ /* -+ * Save the termios structure, since this port may have -+ * separate termios for callout and dialin. -+ */ -+ if (info->flags & ASYNC_NORMAL_ACTIVE) -+ info->normal_termios = *tty->termios; -+ /* -+ * Now we wait for the transmit buffer to clear; and we notify -+ * the line discipline to only process XON/XOFF characters. -+ */ -+ tty->closing = 1; -+ if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) -+ tty_wait_until_sent(tty, info->closing_wait); -+ /* -+ * At this point we stop accepting input. To do this, we -+ * disable the serial receiver and the DMA receive interrupt. -+ */ -+#ifdef SERIAL_HANDLE_EARLY_ERRORS -+ e100_disable_serial_data_irq(info); -+#endif -+ -+#ifndef CONFIG_SVINTO_SIM -+ e100_disable_rx(info); -+ e100_disable_rx_irq(info); -+ -+ if (info->flags & ASYNC_INITIALIZED) { -+ /* -+ * Before we drop DTR, make sure the UART transmitter -+ * has completely drained; this is especially -+ * important as we have a transmit FIFO! -+ */ -+ rs_wait_until_sent(tty, HZ); -+ } -+#endif -+ -+ shutdown(info); -+ rs_flush_buffer(tty); -+ tty_ldisc_flush(tty); -+ tty->closing = 0; -+ info->event = 0; -+ info->port.tty = NULL; -+ if (info->blocked_open) { -+ if (info->close_delay) -+ schedule_timeout_interruptible(info->close_delay); -+ wake_up_interruptible(&info->open_wait); -+ } -+ info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); -+ wake_up_interruptible(&info->close_wait); -+ local_irq_restore(flags); -+ -+ /* port closed */ -+ -+#if defined(CONFIG_ETRAX_RS485) -+ if (info->rs485.flags & SER_RS485_ENABLED) { -+ info->rs485.flags &= ~(SER_RS485_ENABLED); -+#if defined(CONFIG_ETRAX_RS485_ON_PA) -+ *R_PORT_PA_DATA = port_pa_data_shadow &= ~(1 << rs485_pa_bit); -+#endif -+#if defined(CONFIG_ETRAX_RS485_ON_PORT_G) -+ REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, -+ rs485_port_g_bit, 0); -+#endif -+#if defined(CONFIG_ETRAX_RS485_LTC1387) -+ REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, -+ CONFIG_ETRAX_RS485_LTC1387_DXEN_PORT_G_BIT, 0); -+ REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, -+ CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 0); -+#endif -+ } -+#endif -+ -+ /* -+ * Release any allocated DMA irq's. -+ */ -+ if (info->dma_in_enabled) { -+ free_irq(info->dma_in_irq_nbr, info); -+ cris_free_dma(info->dma_in_nbr, info->dma_in_irq_description); -+ info->uses_dma_in = 0; -+#ifdef SERIAL_DEBUG_OPEN -+ printk(KERN_DEBUG "DMA irq '%s' freed\n", -+ info->dma_in_irq_description); -+#endif -+ } -+ if (info->dma_out_enabled) { -+ free_irq(info->dma_out_irq_nbr, info); -+ cris_free_dma(info->dma_out_nbr, info->dma_out_irq_description); -+ info->uses_dma_out = 0; -+#ifdef SERIAL_DEBUG_OPEN -+ printk(KERN_DEBUG "DMA irq '%s' freed\n", -+ info->dma_out_irq_description); -+#endif -+ } -+} -+ -+/* -+ * rs_wait_until_sent() --- wait until the transmitter is empty -+ */ -+static void rs_wait_until_sent(struct tty_struct *tty, int timeout) -+{ -+ unsigned long orig_jiffies; -+ struct e100_serial *info = (struct e100_serial *)tty->driver_data; -+ unsigned long curr_time = jiffies; -+ unsigned long curr_time_usec = GET_JIFFIES_USEC(); -+ long elapsed_usec = -+ (curr_time - info->last_tx_active) * (1000000/HZ) + -+ curr_time_usec - info->last_tx_active_usec; -+ -+ /* -+ * Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO -+ * R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k) -+ */ -+ orig_jiffies = jiffies; -+ while (info->xmit.head != info->xmit.tail || /* More in send queue */ -+ (*info->ostatusadr & 0x007f) || /* more in FIFO */ -+ (elapsed_usec < 2*info->char_time_usec)) { -+ schedule_timeout_interruptible(1); -+ if (signal_pending(current)) -+ break; -+ if (timeout && time_after(jiffies, orig_jiffies + timeout)) -+ break; -+ curr_time = jiffies; -+ curr_time_usec = GET_JIFFIES_USEC(); -+ elapsed_usec = -+ (curr_time - info->last_tx_active) * (1000000/HZ) + -+ curr_time_usec - info->last_tx_active_usec; -+ } -+ set_current_state(TASK_RUNNING); -+} -+ -+/* -+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled. -+ */ -+void -+rs_hangup(struct tty_struct *tty) -+{ -+ struct e100_serial * info = (struct e100_serial *)tty->driver_data; -+ -+ rs_flush_buffer(tty); -+ shutdown(info); -+ info->event = 0; -+ info->count = 0; -+ info->flags &= ~ASYNC_NORMAL_ACTIVE; -+ info->port.tty = NULL; -+ wake_up_interruptible(&info->open_wait); -+} -+ -+/* -+ * ------------------------------------------------------------ -+ * rs_open() and friends -+ * ------------------------------------------------------------ -+ */ -+static int -+block_til_ready(struct tty_struct *tty, struct file * filp, -+ struct e100_serial *info) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ unsigned long flags; -+ int retval; -+ int do_clocal = 0, extra_count = 0; -+ -+ /* -+ * If the device is in the middle of being closed, then block -+ * until it's done, and then try again. -+ */ -+ if (tty_hung_up_p(filp) || -+ (info->flags & ASYNC_CLOSING)) { -+ wait_event_interruptible_tty(info->close_wait, -+ !(info->flags & ASYNC_CLOSING)); -+#ifdef SERIAL_DO_RESTART -+ if (info->flags & ASYNC_HUP_NOTIFY) -+ return -EAGAIN; -+ else -+ return -ERESTARTSYS; -+#else -+ return -EAGAIN; -+#endif -+ } -+ -+ /* -+ * If non-blocking mode is set, or the port is not enabled, -+ * then make the check up front and then exit. -+ */ -+ if ((filp->f_flags & O_NONBLOCK) || -+ (tty->flags & (1 << TTY_IO_ERROR))) { -+ info->flags |= ASYNC_NORMAL_ACTIVE; -+ return 0; -+ } -+ -+ if (tty->termios->c_cflag & CLOCAL) { -+ do_clocal = 1; -+ } -+ -+ /* -+ * Block waiting for the carrier detect and the line to become -+ * free (i.e., not in use by the callout). While we are in -+ * this loop, info->count is dropped by one, so that -+ * rs_close() knows when to free things. We restore it upon -+ * exit, either normal or abnormal. -+ */ -+ retval = 0; -+ add_wait_queue(&info->open_wait, &wait); -+#ifdef SERIAL_DEBUG_OPEN -+ printk("block_til_ready before block: ttyS%d, count = %d\n", -+ info->line, info->count); -+#endif -+ local_irq_save(flags); -+ if (!tty_hung_up_p(filp)) { -+ extra_count++; -+ info->count--; -+ } -+ local_irq_restore(flags); -+ info->blocked_open++; -+ while (1) { -+ local_irq_save(flags); -+ /* assert RTS and DTR */ -+ e100_rts(info, 1); -+ e100_dtr(info, 1); -+ local_irq_restore(flags); -+ set_current_state(TASK_INTERRUPTIBLE); -+ if (tty_hung_up_p(filp) || -+ !(info->flags & ASYNC_INITIALIZED)) { -+#ifdef SERIAL_DO_RESTART -+ if (info->flags & ASYNC_HUP_NOTIFY) -+ retval = -EAGAIN; -+ else -+ retval = -ERESTARTSYS; -+#else -+ retval = -EAGAIN; -+#endif -+ break; -+ } -+ if (!(info->flags & ASYNC_CLOSING) && do_clocal) -+ /* && (do_clocal || DCD_IS_ASSERTED) */ -+ break; -+ if (signal_pending(current)) { -+ retval = -ERESTARTSYS; -+ break; -+ } -+#ifdef SERIAL_DEBUG_OPEN -+ printk("block_til_ready blocking: ttyS%d, count = %d\n", -+ info->line, info->count); -+#endif -+ tty_unlock(); -+ schedule(); -+ tty_lock(); -+ } -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&info->open_wait, &wait); -+ if (extra_count) -+ info->count++; -+ info->blocked_open--; -+#ifdef SERIAL_DEBUG_OPEN -+ printk("block_til_ready after blocking: ttyS%d, count = %d\n", -+ info->line, info->count); -+#endif -+ if (retval) -+ return retval; -+ info->flags |= ASYNC_NORMAL_ACTIVE; -+ return 0; -+} -+ -+static void -+deinit_port(struct e100_serial *info) -+{ -+ if (info->dma_out_enabled) { -+ cris_free_dma(info->dma_out_nbr, info->dma_out_irq_description); -+ free_irq(info->dma_out_irq_nbr, info); -+ } -+ if (info->dma_in_enabled) { -+ cris_free_dma(info->dma_in_nbr, info->dma_in_irq_description); -+ free_irq(info->dma_in_irq_nbr, info); -+ } -+} -+ -+/* -+ * This routine is called whenever a serial port is opened. -+ * It performs the serial-specific initialization for the tty structure. -+ */ -+static int -+rs_open(struct tty_struct *tty, struct file * filp) -+{ -+ struct e100_serial *info; -+ int retval, line; -+ unsigned long page; -+ int allocated_resources = 0; -+ -+ /* find which port we want to open */ -+ line = tty->index; -+ -+ if (line < 0 || line >= NR_PORTS) -+ return -ENODEV; -+ -+ /* find the corresponding e100_serial struct in the table */ -+ info = rs_table + line; -+ -+ /* don't allow the opening of ports that are not enabled in the HW config */ -+ if (!info->enabled) -+ return -ENODEV; -+ -+#ifdef SERIAL_DEBUG_OPEN -+ printk("[%d] rs_open %s, count = %d\n", current->pid, tty->name, -+ info->count); -+#endif -+ -+ info->count++; -+ tty->driver_data = info; -+ info->port.tty = tty; -+ -+ info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; -+ -+ if (!tmp_buf) { -+ page = get_zeroed_page(GFP_KERNEL); -+ if (!page) { -+ return -ENOMEM; -+ } -+ if (tmp_buf) -+ free_page(page); -+ else -+ tmp_buf = (unsigned char *) page; -+ } -+ -+ /* -+ * If the port is in the middle of closing, bail out now -+ */ -+ if (tty_hung_up_p(filp) || -+ (info->flags & ASYNC_CLOSING)) { -+ wait_event_interruptible_tty(info->close_wait, -+ !(info->flags & ASYNC_CLOSING)); -+#ifdef SERIAL_DO_RESTART -+ return ((info->flags & ASYNC_HUP_NOTIFY) ? -+ -EAGAIN : -ERESTARTSYS); -+#else -+ return -EAGAIN; -+#endif -+ } -+ -+ /* -+ * If DMA is enabled try to allocate the irq's. -+ */ -+ if (info->count == 1) { -+ allocated_resources = 1; -+ if (info->dma_in_enabled) { -+ if (request_irq(info->dma_in_irq_nbr, -+ rec_interrupt, -+ info->dma_in_irq_flags, -+ info->dma_in_irq_description, -+ info)) { -+ printk(KERN_WARNING "DMA irq '%s' busy; " -+ "falling back to non-DMA mode\n", -+ info->dma_in_irq_description); -+ /* Make sure we never try to use DMA in */ -+ /* for the port again. */ -+ info->dma_in_enabled = 0; -+ } else if (cris_request_dma(info->dma_in_nbr, -+ info->dma_in_irq_description, -+ DMA_VERBOSE_ON_ERROR, -+ info->dma_owner)) { -+ free_irq(info->dma_in_irq_nbr, info); -+ printk(KERN_WARNING "DMA '%s' busy; " -+ "falling back to non-DMA mode\n", -+ info->dma_in_irq_description); -+ /* Make sure we never try to use DMA in */ -+ /* for the port again. */ -+ info->dma_in_enabled = 0; -+ } -+#ifdef SERIAL_DEBUG_OPEN -+ else -+ printk(KERN_DEBUG "DMA irq '%s' allocated\n", -+ info->dma_in_irq_description); -+#endif -+ } -+ if (info->dma_out_enabled) { -+ if (request_irq(info->dma_out_irq_nbr, -+ tr_interrupt, -+ info->dma_out_irq_flags, -+ info->dma_out_irq_description, -+ info)) { -+ printk(KERN_WARNING "DMA irq '%s' busy; " -+ "falling back to non-DMA mode\n", -+ info->dma_out_irq_description); -+ /* Make sure we never try to use DMA out */ -+ /* for the port again. */ -+ info->dma_out_enabled = 0; -+ } else if (cris_request_dma(info->dma_out_nbr, -+ info->dma_out_irq_description, -+ DMA_VERBOSE_ON_ERROR, -+ info->dma_owner)) { -+ free_irq(info->dma_out_irq_nbr, info); -+ printk(KERN_WARNING "DMA '%s' busy; " -+ "falling back to non-DMA mode\n", -+ info->dma_out_irq_description); -+ /* Make sure we never try to use DMA out */ -+ /* for the port again. */ -+ info->dma_out_enabled = 0; -+ } -+#ifdef SERIAL_DEBUG_OPEN -+ else -+ printk(KERN_DEBUG "DMA irq '%s' allocated\n", -+ info->dma_out_irq_description); -+#endif -+ } -+ } -+ -+ /* -+ * Start up the serial port -+ */ -+ -+ retval = startup(info); -+ if (retval) { -+ if (allocated_resources) -+ deinit_port(info); -+ -+ /* FIXME Decrease count info->count here too? */ -+ return retval; -+ } -+ -+ -+ retval = block_til_ready(tty, filp, info); -+ if (retval) { -+#ifdef SERIAL_DEBUG_OPEN -+ printk("rs_open returning after block_til_ready with %d\n", -+ retval); -+#endif -+ if (allocated_resources) -+ deinit_port(info); -+ -+ return retval; -+ } -+ -+ if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { -+ *tty->termios = info->normal_termios; -+ change_speed(info); -+ } -+ -+#ifdef SERIAL_DEBUG_OPEN -+ printk("rs_open ttyS%d successful...\n", info->line); -+#endif -+ DLOG_INT_TRIG( log_int_pos = 0); -+ -+ DFLIP( if (info->line == SERIAL_DEBUG_LINE) { -+ info->icount.rx = 0; -+ } ); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PROC_FS -+/* -+ * /proc fs routines.... -+ */ -+ -+static void seq_line_info(struct seq_file *m, struct e100_serial *info) -+{ -+ unsigned long tmp; -+ -+ seq_printf(m, "%d: uart:E100 port:%lX irq:%d", -+ info->line, (unsigned long)info->ioport, info->irq); -+ -+ if (!info->ioport || (info->type == PORT_UNKNOWN)) { -+ seq_printf(m, "\n"); -+ return; -+ } -+ -+ seq_printf(m, " baud:%d", info->baud); -+ seq_printf(m, " tx:%lu rx:%lu", -+ (unsigned long)info->icount.tx, -+ (unsigned long)info->icount.rx); -+ tmp = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -+ if (tmp) -+ seq_printf(m, " tx_pend:%lu/%lu", -+ (unsigned long)tmp, -+ (unsigned long)SERIAL_XMIT_SIZE); -+ -+ seq_printf(m, " rx_pend:%lu/%lu", -+ (unsigned long)info->recv_cnt, -+ (unsigned long)info->max_recv_cnt); -+ -+#if 1 -+ if (info->port.tty) { -+ if (info->port.tty->stopped) -+ seq_printf(m, " stopped:%i", -+ (int)info->port.tty->stopped); -+ if (info->port.tty->hw_stopped) -+ seq_printf(m, " hw_stopped:%i", -+ (int)info->port.tty->hw_stopped); -+ } -+ -+ { -+ unsigned char rstat = info->ioport[REG_STATUS]; -+ if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect)) -+ seq_printf(m, " xoff_detect:1"); -+ } -+ -+#endif -+ -+ if (info->icount.frame) -+ seq_printf(m, " fe:%lu", (unsigned long)info->icount.frame); -+ -+ if (info->icount.parity) -+ seq_printf(m, " pe:%lu", (unsigned long)info->icount.parity); -+ -+ if (info->icount.brk) -+ seq_printf(m, " brk:%lu", (unsigned long)info->icount.brk); -+ -+ if (info->icount.overrun) -+ seq_printf(m, " oe:%lu", (unsigned long)info->icount.overrun); -+ -+ /* -+ * Last thing is the RS-232 status lines -+ */ -+ if (!E100_RTS_GET(info)) -+ seq_puts(m, "|RTS"); -+ if (!E100_CTS_GET(info)) -+ seq_puts(m, "|CTS"); -+ if (!E100_DTR_GET(info)) -+ seq_puts(m, "|DTR"); -+ if (!E100_DSR_GET(info)) -+ seq_puts(m, "|DSR"); -+ if (!E100_CD_GET(info)) -+ seq_puts(m, "|CD"); -+ if (!E100_RI_GET(info)) -+ seq_puts(m, "|RI"); -+ seq_puts(m, "\n"); -+} -+ -+ -+static int crisv10_proc_show(struct seq_file *m, void *v) -+{ -+ int i; -+ -+ seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version); -+ -+ for (i = 0; i < NR_PORTS; i++) { -+ if (!rs_table[i].enabled) -+ continue; -+ seq_line_info(m, &rs_table[i]); -+ } -+#ifdef DEBUG_LOG_INCLUDED -+ for (i = 0; i < debug_log_pos; i++) { -+ seq_printf(m, "%-4i %lu.%lu ", -+ i, debug_log[i].time, -+ timer_data_to_ns(debug_log[i].timer_data)); -+ seq_printf(m, debug_log[i].string, debug_log[i].value); -+ } -+ seq_printf(m, "debug_log %i/%i\n", i, DEBUG_LOG_SIZE); -+ debug_log_pos = 0; -+#endif -+ return 0; -+} -+ -+static int crisv10_proc_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, crisv10_proc_show, NULL); -+} -+ -+static const struct file_operations crisv10_proc_fops = { -+ .owner = THIS_MODULE, -+ .open = crisv10_proc_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+#endif -+ -+ -+/* Finally, routines used to initialize the serial driver. */ -+ -+static void show_serial_version(void) -+{ -+ printk(KERN_INFO -+ "ETRAX 100LX serial-driver %s, " -+ "(c) 2000-2004 Axis Communications AB\r\n", -+ &serial_version[11]); /* "$Revision: x.yy" */ -+} -+ -+/* rs_init inits the driver at boot (using the module_init chain) */ -+ -+static const struct tty_operations rs_ops = { -+ .open = rs_open, -+ .close = rs_close, -+ .write = rs_write, -+ .flush_chars = rs_flush_chars, -+ .write_room = rs_write_room, -+ .chars_in_buffer = rs_chars_in_buffer, -+ .flush_buffer = rs_flush_buffer, -+ .ioctl = rs_ioctl, -+ .throttle = rs_throttle, -+ .unthrottle = rs_unthrottle, -+ .set_termios = rs_set_termios, -+ .stop = rs_stop, -+ .start = rs_start, -+ .hangup = rs_hangup, -+ .break_ctl = rs_break, -+ .send_xchar = rs_send_xchar, -+ .wait_until_sent = rs_wait_until_sent, -+ .tiocmget = rs_tiocmget, -+ .tiocmset = rs_tiocmset, -+#ifdef CONFIG_PROC_FS -+ .proc_fops = &crisv10_proc_fops, -+#endif -+}; -+ -+static int __init rs_init(void) -+{ -+ int i; -+ struct e100_serial *info; -+ struct tty_driver *driver = alloc_tty_driver(NR_PORTS); -+ -+ if (!driver) -+ return -ENOMEM; -+ -+ show_serial_version(); -+ -+ /* Setup the timed flush handler system */ -+ -+#if !defined(CONFIG_ETRAX_SERIAL_FAST_TIMER) -+ setup_timer(&flush_timer, timed_flush_handler, 0); -+ mod_timer(&flush_timer, jiffies + 5); -+#endif -+ -+#if defined(CONFIG_ETRAX_RS485) -+#if defined(CONFIG_ETRAX_RS485_ON_PA) -+ if (cris_io_interface_allocate_pins(if_ser0, 'a', rs485_pa_bit, -+ rs485_pa_bit)) { -+ printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " -+ "RS485 pin\n"); -+ put_tty_driver(driver); -+ return -EBUSY; -+ } -+#endif -+#if defined(CONFIG_ETRAX_RS485_ON_PORT_G) -+ if (cris_io_interface_allocate_pins(if_ser0, 'g', rs485_pa_bit, -+ rs485_port_g_bit)) { -+ printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " -+ "RS485 pin\n"); -+ put_tty_driver(driver); -+ return -EBUSY; -+ } -+#endif -+#endif -+ -+ /* Initialize the tty_driver structure */ -+ -+ driver->driver_name = "serial"; -+ driver->name = "ttyS"; -+ driver->major = TTY_MAJOR; -+ driver->minor_start = 64; -+ driver->type = TTY_DRIVER_TYPE_SERIAL; -+ driver->subtype = SERIAL_TYPE_NORMAL; -+ driver->init_termios = tty_std_termios; -+ driver->init_termios.c_cflag = -+ B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ -+ driver->init_termios.c_ispeed = 115200; -+ driver->init_termios.c_ospeed = 115200; -+ driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; -+ -+ tty_set_operations(driver, &rs_ops); -+ serial_driver = driver; -+ if (tty_register_driver(driver)) -+ panic("Couldn't register serial driver\n"); -+ /* do some initializing for the separate ports */ -+ -+ for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) { -+ if (info->enabled) { -+ if (cris_request_io_interface(info->io_if, -+ info->io_if_description)) { -+ printk(KERN_CRIT "ETRAX100LX async serial: " -+ "Could not allocate IO pins for " -+ "%s, port %d\n", -+ info->io_if_description, i); -+ info->enabled = 0; -+ } -+ } -+ info->uses_dma_in = 0; -+ info->uses_dma_out = 0; -+ info->line = i; -+ info->port.tty = NULL; -+ info->type = PORT_ETRAX; -+ info->tr_running = 0; -+ info->forced_eop = 0; -+ info->baud_base = DEF_BAUD_BASE; -+ info->custom_divisor = 0; -+ info->flags = 0; -+ info->close_delay = 5*HZ/10; -+ info->closing_wait = 30*HZ; -+ info->x_char = 0; -+ info->event = 0; -+ info->count = 0; -+ info->blocked_open = 0; -+ info->normal_termios = driver->init_termios; -+ init_waitqueue_head(&info->open_wait); -+ init_waitqueue_head(&info->close_wait); -+ info->xmit.buf = NULL; -+ info->xmit.tail = info->xmit.head = 0; -+ info->first_recv_buffer = info->last_recv_buffer = NULL; -+ info->recv_cnt = info->max_recv_cnt = 0; -+ info->last_tx_active_usec = 0; -+ info->last_tx_active = 0; -+ -+#if defined(CONFIG_ETRAX_RS485) -+ /* Set sane defaults */ -+ info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND); -+ info->rs485.flags |= SER_RS485_RTS_AFTER_SEND; -+ info->rs485.flags &= ~(SER_RS485_RTS_BEFORE_SEND); -+ info->rs485.delay_rts_before_send = 0; -+ info->rs485.flags &= ~(SER_RS485_ENABLED); -+#endif -+ INIT_WORK(&info->work, do_softint); -+ -+ if (info->enabled) { -+ printk(KERN_INFO "%s%d at %p is a builtin UART with DMA\n", -+ serial_driver->name, info->line, info->ioport); -+ } -+ } -+#ifdef CONFIG_ETRAX_FAST_TIMER -+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER -+ memset(fast_timers, 0, sizeof(fast_timers)); -+#endif -+#ifdef CONFIG_ETRAX_RS485 -+ memset(fast_timers_rs485, 0, sizeof(fast_timers_rs485)); -+#endif -+ fast_timer_init(); -+#endif -+ -+#ifndef CONFIG_SVINTO_SIM -+#ifndef CONFIG_ETRAX_KGDB -+ /* Not needed in simulator. May only complicate stuff. */ -+ /* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */ -+ -+ if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, -+ IRQF_SHARED | IRQF_DISABLED, "serial ", driver)) -+ panic("%s: Failed to request irq8", __func__); -+ -+#endif -+#endif /* CONFIG_SVINTO_SIM */ -+ -+ return 0; -+} -+ -+/* this makes sure that rs_init is called during kernel boot */ -+ -+module_init(rs_init); diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-cris-dbg.h linux-2.6.39/drivers/usb/host/hc-cris-dbg.h --- linux-2.6.39.orig/drivers/usb/host/hc-cris-dbg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/usb/host/hc-cris-dbg.h 2011-07-28 16:16:37.503543830 +0200 ++++ linux-2.6.39/drivers/usb/host/hc-cris-dbg.h 2011-08-22 08:58:56.307980767 +0200 @@ -0,0 +1,146 @@ + +/* macros for debug output */ @@ -8020,7 +563,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-cris-dbg.h linux-2.6.39/drivers/ + }) diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-crisv10.c linux-2.6.39/drivers/usb/host/hc-crisv10.c --- linux-2.6.39.orig/drivers/usb/host/hc-crisv10.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/usb/host/hc-crisv10.c 2011-07-28 16:16:37.633441816 +0200 ++++ linux-2.6.39/drivers/usb/host/hc-crisv10.c 2011-08-22 08:58:56.397980354 +0200 @@ -0,0 +1,4801 @@ +/* + * @@ -12825,7 +5368,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-crisv10.c linux-2.6.39/drivers/u +module_exit(module_hcd_exit); diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-crisv10.h linux-2.6.39/drivers/usb/host/hc-crisv10.h --- linux-2.6.39.orig/drivers/usb/host/hc-crisv10.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/usb/host/hc-crisv10.h 2011-07-28 16:16:37.757174124 +0200 ++++ linux-2.6.39/drivers/usb/host/hc-crisv10.h 2011-08-22 08:58:56.467980502 +0200 @@ -0,0 +1,331 @@ +#ifndef __LINUX_ETRAX_USB_H +#define __LINUX_ETRAX_USB_H @@ -13160,7 +5703,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-crisv10.h linux-2.6.39/drivers/u +#endif diff -Nur linux-2.6.39.orig/drivers/usb/host/Makefile linux-2.6.39/drivers/usb/host/Makefile --- linux-2.6.39.orig/drivers/usb/host/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/usb/host/Makefile 2011-07-28 16:16:37.863421513 +0200 ++++ linux-2.6.39/drivers/usb/host/Makefile 2011-08-22 08:58:56.527980204 +0200 @@ -32,6 +32,7 @@ obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o @@ -13171,7 +5714,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/Makefile linux-2.6.39/drivers/usb/h obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o diff -Nur linux-2.6.39.orig/drivers/usb/Makefile linux-2.6.39/drivers/usb/Makefile --- linux-2.6.39.orig/drivers/usb/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/usb/Makefile 2011-07-28 16:16:37.993659487 +0200 ++++ linux-2.6.39/drivers/usb/Makefile 2011-08-22 08:58:56.607990534 +0200 @@ -21,6 +21,7 @@ obj-$(CONFIG_USB_R8A66597_HCD) += host/ obj-$(CONFIG_USB_HWA_HCD) += host/ @@ -13182,7 +5725,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/Makefile linux-2.6.39/drivers/usb/Makefi obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ diff -Nur linux-2.6.39.orig/lib/klist.c linux-2.6.39/lib/klist.c --- linux-2.6.39.orig/lib/klist.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/lib/klist.c 2011-07-28 16:16:38.103425277 +0200 ++++ linux-2.6.39/lib/klist.c 2011-08-22 08:58:56.667990229 +0200 @@ -60,7 +60,7 @@ { knode->n_klist = klist; -- cgit v1.2.3 From 1430d117c0fcfc9f3b954ebce078745fb172a826 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 22 Aug 2011 09:59:55 +0200 Subject: enable x86_64 --- jtools/qemu/Makefile | 2 +- mk/vars.mk | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/jtools/qemu/Makefile b/jtools/qemu/Makefile index c83a6d987..b6add732e 100644 --- a/jtools/qemu/Makefile +++ b/jtools/qemu/Makefile @@ -18,7 +18,7 @@ $(WRKBUILD)/.configured: ${WRKDIST}/.prepared --host-cc=$(CC_FOR_BUILD) \ --disable-system \ --disable-sdl \ - --target-list=arm-linux-user,i386-linux-user,mipsel-linux-user \ + --target-list=arm-linux-user,i386-linux-user,mipsel-linux-user,x86_64-linux-user \ ) touch $@ diff --git a/mk/vars.mk b/mk/vars.mk index d4f64d068..89d78be83 100644 --- a/mk/vars.mk +++ b/mk/vars.mk @@ -59,6 +59,9 @@ endif ifeq ($(CPU_ARCH),i686) QEMU:= qemu-i386 endif +ifeq ($(CPU_ARCH),x86_64) +QEMU:= qemu-x86_64 +endif ifeq ($(ADK_NATIVE),y) TARGET_CROSS:= -- cgit v1.2.3 From 31b8a0a342a4525e9540a25883d0600ce9d374dc Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 23 Aug 2011 14:26:33 +0200 Subject: finetune qemu-ppc support, usable now --- target/linux/config/Config.in.netdevice | 10 +++ target/ppc/Makefile | 6 +- target/ppc/kernel.config | 150 ++++++++++++++++++++------------ 3 files changed, 108 insertions(+), 58 deletions(-) diff --git a/target/linux/config/Config.in.netdevice b/target/linux/config/Config.in.netdevice index 14820b810..dad3fcb0f 100644 --- a/target/linux/config/Config.in.netdevice +++ b/target/linux/config/Config.in.netdevice @@ -87,6 +87,16 @@ config ADK_KERNEL_AR231X_ETHERNET default n help +config ADK_KERNEL_NE2K_PCI + boolean + select ADK_KERNEL_NETDEVICES + select ADK_KERNEL_NET_ETHERNET + select ADK_KERNEL_NET_PCI + select ADK_KERNEL_MII + default y if ADK_TARGET_SYSTEM_QEMU_PPC + default n + help + config ADK_KERNEL_KORINA boolean select ADK_KERNEL_NETDEVICES diff --git a/target/ppc/Makefile b/target/ppc/Makefile index c643d6c5c..1b225d657 100644 --- a/target/ppc/Makefile +++ b/target/ppc/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/mk/modules.mk include $(TOPDIR)/mk/kernel-build.mk include $(TOPDIR)/mk/image.mk -KERNEL:=$(LINUX_DIR)/arch/powerpc/boot/zImage +KERNEL:=$(LINUX_DIR)/vmlinux ifeq ($(ADK_TARGET_FS),archive) imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) @@ -22,7 +22,7 @@ imageinstall: $(BIN_DIR)/$(INITRAMFS) @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' ifeq ($(ADK_TARGET_SYSTEM_QEMU_PPC),y) @echo "Start qemu with following command line:" - @echo 'qemu-system-ppc -M mac99 -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' + @echo 'qemu-system-ppc -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' endif endif ifeq ($(ADK_TARGET_FS),initramfs-piggyback) @@ -31,6 +31,6 @@ imageinstall: ${BUILD_DIR}/${INITRAMFS_PIGGYBACK} createinitramfs @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' ifeq ($(ADK_TARGET_SYSTEM_QEMU_PPC),y) @echo "Start qemu with following command line:" - @echo 'qemu-system-ppc -M mac99 -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' + @echo 'qemu-system-ppc -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' endif endif diff --git a/target/ppc/kernel.config b/target/ppc/kernel.config index e075fd4ba..d97b641cc 100644 --- a/target/ppc/kernel.config +++ b/target/ppc/kernel.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.36 -# Fri Nov 19 00:22:49 2010 +# Linux/powerpc 2.6.39 Kernel Configuration +# Tue Aug 23 14:16:21 2011 # # CONFIG_PPC64 is not set @@ -17,24 +17,23 @@ CONFIG_PPC_BOOK3S_32=y CONFIG_PPC_BOOK3S=y CONFIG_6xx=y CONFIG_PPC_FPU=y -# CONFIG_ALTIVEC is not set +CONFIG_ALTIVEC=y CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y # CONFIG_PPC_MM_SLICES is not set CONFIG_PPC_HAVE_PMU_SUPPORT=y # CONFIG_SMP is not set CONFIG_PPC32=y +CONFIG_32BIT=y CONFIG_WORD_SIZE=32 # CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set CONFIG_MMU=y CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set -CONFIG_IRQ_PER_CPU=y CONFIG_NR_IRQS=512 CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y @@ -44,6 +43,7 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_FIND_BIT_LE=y # CONFIG_ARCH_NO_VIRT_TO_BUS is not set CONFIG_PPC=y CONFIG_EARLY_PRINTK=y @@ -62,6 +62,7 @@ CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y +CONFIG_HAVE_IRQ_WORK=y # # General setup @@ -78,30 +79,40 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_FHANDLE is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_HAVE_SPARSE_IRQ=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +# CONFIG_SPARSE_IRQ is not set # # RCU Subsystem # -CONFIG_TREE_RCU=y -# CONFIG_TINY_RCU is not set +CONFIG_TINY_RCU=y +# CONFIG_PREEMPT_RCU is not set # CONFIG_RCU_TRACE is not set -CONFIG_RCU_FANOUT=32 -# CONFIG_RCU_FANOUT_EXACT is not set # CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=15 # CONFIG_CGROUPS is not set -# CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set # CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y -CONFIG_EMBEDDED=y +CONFIG_EXPERT=y CONFIG_SYSCTL_SYSCALL=y # CONFIG_KALLSYMS is not set CONFIG_HOTPLUG=y @@ -117,6 +128,7 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_EMBEDDED=y CONFIG_HAVE_PERF_EVENTS=y # @@ -215,6 +227,7 @@ CONFIG_PPC_PMAC=y # CONFIG_PPC_86xx is not set # CONFIG_EMBEDDED6xx is not set # CONFIG_AMIGAONE is not set +# CONFIG_KVM_GUEST is not set CONFIG_PPC_NATIVE=y CONFIG_PPC_OF_BOOT_TRAMPOLINE=y # CONFIG_UDBG_RTAS_CONSOLE is not set @@ -225,7 +238,7 @@ CONFIG_PPC_I8259=y CONFIG_PPC_RTAS=y CONFIG_RTAS_ERROR_LOGGING=y CONFIG_PPC_RTAS_DAEMON=y -CONFIG_RTAS_PROC=y +# CONFIG_RTAS_PROC is not set # CONFIG_MMIO_NVRAM is not set # CONFIG_MPIC_U3_HT_IRQS is not set CONFIG_PPC_MPC106=y @@ -233,7 +246,7 @@ CONFIG_PPC_MPC106=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_PPC601_SYNC_FIX is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_TAU is not set # CONFIG_FSL_ULI1575 is not set # CONFIG_SIMPLE_GPIO is not set @@ -264,7 +277,6 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y # CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set -# CONFIG_SPARSE_IRQ is not set CONFIG_MAX_ACTIVE_REGIONS=32 CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y @@ -275,6 +287,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_HAVE_MEMBLOCK=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set # CONFIG_MIGRATION is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -282,11 +295,13 @@ CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NEED_PER_CPU_KM=y CONFIG_PPC_4K_PAGES=y CONFIG_FORCE_MAX_ZONEORDER=11 -# CONFIG_CMDLINE_BOOL is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyS0,9600 console=tty0" CONFIG_EXTRA_TARGETS="" -# CONFIG_PM is not set +# CONFIG_PM_RUNTIME is not set # CONFIG_SECCOMP is not set CONFIG_ISA_DMA_API=y @@ -310,6 +325,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set # CONFIG_HAS_RAPIDIO is not set +# CONFIG_RAPIDIO is not set # # Advanced setup @@ -335,10 +351,9 @@ CONFIG_UNIX=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set +# CONFIG_NET_IPGRE_DEMUX is not set # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set @@ -379,6 +394,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set # CONFIG_DCB is not set +# CONFIG_BATMAN_ADV is not set # # Network testing @@ -389,11 +405,18 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set # # Device Drivers @@ -415,16 +438,19 @@ CONFIG_DTC=y CONFIG_OF=y # -# Flattened Device Tree and Open Firmware support +# Device Tree and Open Firmware support # # CONFIG_PROC_DEVICETREE is not set CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y CONFIG_OF_DYNAMIC=y CONFIG_OF_ADDRESS=y CONFIG_OF_IRQ=y CONFIG_OF_DEVICE=y +CONFIG_OF_PCI=y # CONFIG_PARPORT is not set # CONFIG_BLK_DEV is not set +# CONFIG_SENSORS_LIS3LV02D is not set # CONFIG_MISC_DEVICES is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -444,25 +470,19 @@ CONFIG_SCSI_MOD=y # # IEEE 1394 (FireWire) support # - -# -# You can enable one or both FireWire driver stacks. -# - -# -# The newer stack is recommended. -# # CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set # CONFIG_FIREWIRE_NOSY is not set # CONFIG_I2O is not set CONFIG_MACINTOSH_DRIVERS=y -# CONFIG_ADB is not set -# CONFIG_ADB_CUDA is not set +CONFIG_ADB=y +CONFIG_ADB_CUDA=y # CONFIG_ADB_PMU is not set # CONFIG_PMAC_MEDIABAY is not set +# CONFIG_ADB_MACIO is not set +CONFIG_INPUT_ADBHID=y # CONFIG_MAC_EMUMOUSEBTN is not set # CONFIG_WINDFARM is not set +# CONFIG_ANSLCD is not set # CONFIG_PMAC_RACKMETER is not set # CONFIG_NETDEVICES is not set # CONFIG_ISDN is not set @@ -497,7 +517,15 @@ CONFIG_INPUT=y # # Hardware I/O ports # -# CONFIG_SERIO is not set +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_XILINX_XPS_PS2 is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set # CONFIG_GAMEPORT is not set # @@ -508,20 +536,18 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set -# CONFIG_DEVKMEM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_N_GSM is not set # CONFIG_NOZOMI is not set +# CONFIG_N_GSM is not set +# CONFIG_DEVKMEM is not set # # Serial drivers # -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250 is not set # # Non-8250 serial port support @@ -530,16 +556,15 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_PMACZILOG is not set +CONFIG_SERIAL_PMACZILOG=y +CONFIG_SERIAL_PMACZILOG_TTYS=y +CONFIG_SERIAL_PMACZILOG_CONSOLE=y # CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_OF_PLATFORM is not set # CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set # CONFIG_SERIAL_ALTERA_UART is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_PCH_UART is not set +# CONFIG_TTY_PRINTK is not set # CONFIG_BRIQ_PANEL is not set # CONFIG_HVC_RTAS is not set # CONFIG_HVC_UDBG is not set @@ -559,6 +584,10 @@ CONFIG_DEVPORT=y # PPS support # # CONFIG_PPS is not set + +# +# PPS generators support +# CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_GPIOLIB is not set # CONFIG_W1 is not set @@ -582,6 +611,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_AGP is not set # CONFIG_VGA_ARB is not set # CONFIG_DRM is not set +# CONFIG_STUB_POULSBO is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set # CONFIG_FB is not set @@ -605,6 +635,7 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_NFC_DEVICES is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set @@ -661,17 +692,18 @@ CONFIG_RTC_DRV_M48T59=y # CONFIG_EXT4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set # CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y -# CONFIG_FSNOTIFY is not set +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set +# CONFIG_FANOTIFY is not set # CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set +# CONFIG_QUOTACTL is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -715,7 +747,6 @@ CONFIG_TMPFS=y CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set -# CONFIG_DLM is not set # CONFIG_BINARY_PRINTF is not set # @@ -730,16 +761,20 @@ CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC32=y # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y CONFIG_NLATTR=y CONFIG_GENERIC_ATOMIC64=y +# CONFIG_AVERAGE is not set # # Kernel hacking # CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=1024 @@ -748,11 +783,12 @@ CONFIG_FRAME_WARN=1024 # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_SPARSE_RCU_POINTER is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -764,16 +800,18 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_TEST_KSTRTOX is not set # CONFIG_PPC_DISABLE_WERROR is not set CONFIG_PPC_WERROR=y CONFIG_PRINT_STACK_DEPTH=64 -# CONFIG_BOOTX_TEXT is not set +CONFIG_BOOTX_TEXT=y # CONFIG_PPC_EARLY_DEBUG is not set # # Security options # # CONFIG_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set CONFIG_DEFAULT_SECURITY_DAC=y @@ -864,6 +902,8 @@ CONFIG_CRYPTO=y # Random Number Generation # # CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set # CONFIG_CRYPTO_HW is not set # -- cgit v1.2.3 From 0f664e8007ce59f13ae5c79cc4f88658b0c1338e Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 24 Aug 2011 04:09:28 +0200 Subject: better ppc64 support, qemu still hangs @ returning from prom_init --- target/config/Config.in | 4 + target/ppc64/Makefile | 10 +- target/ppc64/kernel.config | 339 ++++++++++++++++++++++------------ target/ppc64/sys-available/qemu-ppc64 | 13 ++ toolchain/gcc/patches/no-lib64.patch | 48 +++-- 5 files changed, 283 insertions(+), 131 deletions(-) create mode 100644 target/ppc64/sys-available/qemu-ppc64 diff --git a/target/config/Config.in b/target/config/Config.in index a15e42e27..a5bbf06ef 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -249,6 +249,9 @@ config ADK_CPU_GEODE config ADK_CPU_PPC boolean +config ADK_CPU_PPC64 + boolean + config ADK_CPU_PENTIUM_M boolean @@ -278,6 +281,7 @@ config ADK_TARGET_CPU_ARCH default "armeb" if ADK_LINUX_ARM && ADK_big default "sparc" if ADK_LINUX_SPARC default "ppc" if ADK_CPU_PPC + default "ppc64" if ADK_CPU_PPC64 config ADK_TARGET_ABI_CFLAGS string diff --git a/target/ppc64/Makefile b/target/ppc64/Makefile index a60d376a9..0e9ac9547 100644 --- a/target/ppc64/Makefile +++ b/target/ppc64/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/mk/modules.mk include $(TOPDIR)/mk/kernel-build.mk include $(TOPDIR)/mk/image.mk -KERNEL:=$(LINUX_DIR)/arch/powerpc/boot/zImage +KERNEL:=$(LINUX_DIR)/vmlinux ifeq ($(ADK_TARGET_FS),archive) imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) @@ -20,9 +20,17 @@ imageinstall: $(BIN_DIR)/$(INITRAMFS) @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_PPC64),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-ppc64 -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' +endif endif ifeq ($(ADK_TARGET_FS),initramfs-piggyback) imageinstall: ${BUILD_DIR}/${INITRAMFS_PIGGYBACK} createinitramfs @cp $(KERNEL) $(BIN_DIR)/${TARGET_KERNEL} @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_PPC64),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-ppc64 -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' +endif endif diff --git a/target/ppc64/kernel.config b/target/ppc64/kernel.config index e075fd4ba..0095cb373 100644 --- a/target/ppc64/kernel.config +++ b/target/ppc64/kernel.config @@ -1,40 +1,39 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.36 -# Fri Nov 19 00:22:49 2010 +# Linux/powerpc 2.6.39 Kernel Configuration +# Wed Aug 24 03:57:23 2011 # -# CONFIG_PPC64 is not set +CONFIG_PPC64=y # # Processor support # -CONFIG_PPC_BOOK3S_32=y -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set +CONFIG_PPC_BOOK3S_64=y +# CONFIG_PPC_BOOK3E_64 is not set CONFIG_PPC_BOOK3S=y -CONFIG_6xx=y +# CONFIG_POWER4_ONLY is not set +CONFIG_POWER3=y +CONFIG_POWER4=y +# CONFIG_TUNE_CELL is not set CONFIG_PPC_FPU=y -# CONFIG_ALTIVEC is not set +CONFIG_ALTIVEC=y +# CONFIG_VSX is not set CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y +CONFIG_PPC_STD_MMU_64=y # CONFIG_PPC_MM_SLICES is not set +CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_PPC_HAVE_PMU_SUPPORT=y # CONFIG_SMP is not set -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_64BIT=y +CONFIG_WORD_SIZE=64 +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_MMU=y CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set -CONFIG_IRQ_PER_CPU=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_NR_IRQS=512 CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y @@ -42,26 +41,32 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_ARCH_HAS_ILOG2_U64=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_FIND_NEXT_BIT=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_GENERIC_FIND_BIT_LE=y +CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y -CONFIG_PPC_UDBG_16550=y -# CONFIG_GENERIC_TBSYNC is not set +# CONFIG_PPC_UDBG_16550 is not set +CONFIG_GENERIC_TBSYNC=y CONFIG_AUDIT_ARCH=y CONFIG_GENERIC_BUG=y # CONFIG_DEFAULT_UIMAGE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y # CONFIG_PPC_DCR_NATIVE is not set # CONFIG_PPC_DCR_MMIO is not set +# CONFIG_PPC_OF_PLATFORM_PCI is not set CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y +CONFIG_HAVE_IRQ_WORK=y # # General setup @@ -78,37 +83,46 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_FHANDLE is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_HAVE_SPARSE_IRQ=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +# CONFIG_SPARSE_IRQ is not set # # RCU Subsystem # -CONFIG_TREE_RCU=y -# CONFIG_TINY_RCU is not set +CONFIG_TINY_RCU=y +# CONFIG_PREEMPT_RCU is not set # CONFIG_RCU_TRACE is not set -CONFIG_RCU_FANOUT=32 -# CONFIG_RCU_FANOUT_EXACT is not set # CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=15 # CONFIG_CGROUPS is not set -# CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set # CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y -CONFIG_EMBEDDED=y +CONFIG_EXPERT=y CONFIG_SYSCTL_SYSCALL=y # CONFIG_KALLSYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set -CONFIG_PCSPKR_PLATFORM=y # CONFIG_BASE_FULL is not set CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -117,6 +131,7 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_EMBEDDED=y CONFIG_HAVE_PERF_EVENTS=y # @@ -134,6 +149,7 @@ CONFIG_SLAB=y CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_SYSCALL_WRAPPERS=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y @@ -156,9 +172,9 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y -# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLOCK_COMPAT=y # # IO Schedulers @@ -198,50 +214,47 @@ CONFIG_INLINE_WRITE_UNLOCK=y CONFIG_INLINE_WRITE_UNLOCK_IRQ=y # CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set # CONFIG_MUTEX_SPIN_ON_OWNER is not set -# CONFIG_FREEZER is not set +CONFIG_FREEZER=y +CONFIG_PPC_MSI_BITMAP=y # # Platform support # -CONFIG_PPC_CHRP=y -# CONFIG_PPC_MPC512x is not set -# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_PSERIES is not set +# CONFIG_PPC_ISERIES is not set CONFIG_PPC_PMAC=y +CONFIG_PPC_PMAC64=y +# CONFIG_PPC_MAPLE is not set +# CONFIG_PPC_PASEMI is not set +# CONFIG_PPC_PS3 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PPC_82xx is not set +# CONFIG_PPC_IBM_CELL_BLADE is not set +# CONFIG_PPC_CELLEB is not set +# CONFIG_PPC_CELL_QPACE is not set # CONFIG_PQ2ADS is not set -# CONFIG_PPC_83xx is not set -# CONFIG_PPC_86xx is not set -# CONFIG_EMBEDDED6xx is not set -# CONFIG_AMIGAONE is not set +# CONFIG_KVM_GUEST is not set CONFIG_PPC_NATIVE=y CONFIG_PPC_OF_BOOT_TRAMPOLINE=y -# CONFIG_UDBG_RTAS_CONSOLE is not set # CONFIG_IPIC is not set CONFIG_MPIC=y # CONFIG_MPIC_WEIRD is not set -CONFIG_PPC_I8259=y -CONFIG_PPC_RTAS=y -CONFIG_RTAS_ERROR_LOGGING=y -CONFIG_PPC_RTAS_DAEMON=y -CONFIG_RTAS_PROC=y +# CONFIG_PPC_I8259 is not set +CONFIG_U3_DART=y +# CONFIG_PPC_RTAS is not set # CONFIG_MMIO_NVRAM is not set -# CONFIG_MPIC_U3_HT_IRQS is not set -CONFIG_PPC_MPC106=y -# CONFIG_PPC_970_NAP is not set +CONFIG_MPIC_U3_HT_IRQS=y +# CONFIG_PPC_MPC106 is not set +CONFIG_PPC_970_NAP=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_PPC601_SYNC_FIX is not set -# CONFIG_TAU is not set # CONFIG_FSL_ULI1575 is not set # CONFIG_SIMPLE_GPIO is not set # # Kernel options # -CONFIG_HIGHMEM=y # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set CONFIG_GENERIC_CLOCKEVENTS_BUILD=y @@ -255,75 +268,81 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y # CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_IOMMU_HELPER is not set +CONFIG_IOMMU_HELPER=y # CONFIG_SWIOTLB is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_HAS_WALK_MEMORY=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y # CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set -# CONFIG_SPARSE_IRQ is not set -CONFIG_MAX_ACTIVE_REGIONS=32 +# CONFIG_NUMA is not set +CONFIG_MAX_ACTIVE_REGIONS=256 +CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_HAVE_MEMBLOCK=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set # CONFIG_MIGRATION is not set -# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NEED_PER_CPU_KM=y +# CONFIG_PPC_HAS_HASH_64K is not set CONFIG_PPC_4K_PAGES=y -CONFIG_FORCE_MAX_ZONEORDER=11 -# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PPC_64K_PAGES is not set +CONFIG_FORCE_MAX_ZONEORDER=13 +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyS0,9600 console=tty0" CONFIG_EXTRA_TARGETS="" -# CONFIG_PM is not set +CONFIG_ARCH_WANTS_FREEZER_CONTROL=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_PM_SLEEP=y +# CONFIG_PM_RUNTIME is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set # CONFIG_SECCOMP is not set CONFIG_ISA_DMA_API=y # # Bus options # -# CONFIG_ISA is not set CONFIG_ZONE_DMA=y -# CONFIG_NEED_DMA_MAP_STATE is not set +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_GENERIC_ISA_DMA=y -CONFIG_PPC_INDIRECT_PCI=y +# CONFIG_PPC_INDIRECT_PCI is not set CONFIG_PCI=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_SYSCALL=y # CONFIG_PCIEPORTBUS is not set CONFIG_ARCH_SUPPORTS_MSI=y -# CONFIG_PCI_MSI is not set +CONFIG_PCI_MSI=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set # CONFIG_HAS_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_PAGE_OFFSET=0xc0000000 -CONFIG_KERNEL_START=0xc0000000 +# CONFIG_RAPIDIO is not set +# CONFIG_RELOCATABLE is not set +CONFIG_PAGE_OFFSET=0xc000000000000000 +CONFIG_KERNEL_START=0xc000000000000000 CONFIG_PHYSICAL_START=0x00000000 -CONFIG_TASK_SIZE=0xc0000000 CONFIG_NET=y # @@ -335,10 +354,9 @@ CONFIG_UNIX=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set +# CONFIG_NET_IPGRE_DEMUX is not set # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set @@ -379,6 +397,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set # CONFIG_DCB is not set +# CONFIG_BATMAN_ADV is not set # # Network testing @@ -389,11 +408,18 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set # # Device Drivers @@ -415,16 +441,19 @@ CONFIG_DTC=y CONFIG_OF=y # -# Flattened Device Tree and Open Firmware support +# Device Tree and Open Firmware support # # CONFIG_PROC_DEVICETREE is not set CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y CONFIG_OF_DYNAMIC=y CONFIG_OF_ADDRESS=y CONFIG_OF_IRQ=y CONFIG_OF_DEVICE=y +CONFIG_OF_PCI=y # CONFIG_PARPORT is not set # CONFIG_BLK_DEV is not set +# CONFIG_SENSORS_LIS3LV02D is not set # CONFIG_MISC_DEVICES is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -444,23 +473,13 @@ CONFIG_SCSI_MOD=y # # IEEE 1394 (FireWire) support # - -# -# You can enable one or both FireWire driver stacks. -# - -# -# The newer stack is recommended. -# # CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set # CONFIG_FIREWIRE_NOSY is not set # CONFIG_I2O is not set CONFIG_MACINTOSH_DRIVERS=y -# CONFIG_ADB is not set -# CONFIG_ADB_CUDA is not set -# CONFIG_ADB_PMU is not set -# CONFIG_PMAC_MEDIABAY is not set +CONFIG_ADB_PMU=y +# CONFIG_ADB_PMU_LED is not set +CONFIG_PMAC_SMU=y # CONFIG_MAC_EMUMOUSEBTN is not set # CONFIG_WINDFARM is not set # CONFIG_PMAC_RACKMETER is not set @@ -497,7 +516,15 @@ CONFIG_INPUT=y # # Hardware I/O ports # -# CONFIG_SERIO is not set +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_XILINX_XPS_PS2 is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set # CONFIG_GAMEPORT is not set # @@ -508,17 +535,20 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set -# CONFIG_DEVKMEM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_N_GSM is not set # CONFIG_NOZOMI is not set +# CONFIG_N_GSM is not set +# CONFIG_DEVKMEM is not set # # Serial drivers # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set @@ -527,28 +557,25 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # Non-8250 serial port support # # CONFIG_SERIAL_MFD_HSU is not set -# CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_PMACZILOG is not set +CONFIG_SERIAL_PMACZILOG=y +CONFIG_SERIAL_PMACZILOG_TTYS=y +CONFIG_SERIAL_PMACZILOG_CONSOLE=y # CONFIG_SERIAL_JSM is not set # CONFIG_SERIAL_OF_PLATFORM is not set # CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set # CONFIG_SERIAL_ALTERA_UART is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_BRIQ_PANEL is not set -# CONFIG_HVC_RTAS is not set +# CONFIG_SERIAL_PCH_UART is not set +# CONFIG_TTY_PRINTK is not set # CONFIG_HVC_UDBG is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set -# CONFIG_NVRAM is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # CONFIG_TCG_TPM is not set CONFIG_DEVPORT=y # CONFIG_RAMOOPS is not set @@ -559,6 +586,10 @@ CONFIG_DEVPORT=y # PPS support # # CONFIG_PPS is not set + +# +# PPS generators support +# CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_GPIOLIB is not set # CONFIG_W1 is not set @@ -582,9 +613,63 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_AGP is not set # CONFIG_VGA_ARB is not set # CONFIG_DRM is not set +# CONFIG_STUB_POULSBO is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_WMT_GE_ROPS is not set +# CONFIG_FB_SVGALIB is not set +CONFIG_FB_MACMODES=y +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -598,6 +683,13 @@ CONFIG_SSB_POSSIBLE=y CONFIG_VGA_CONSOLE=y # CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set # CONFIG_SOUND is not set # CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set @@ -605,6 +697,7 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_NFC_DEVICES is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set @@ -661,17 +754,19 @@ CONFIG_RTC_DRV_M48T59=y # CONFIG_EXT4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_BTRFS_FS is not set # CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y -# CONFIG_FSNOTIFY is not set +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set +# CONFIG_FANOTIFY is not set # CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set +# CONFIG_QUOTACTL is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -703,6 +798,7 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set # CONFIG_MISC_FILESYSTEMS is not set @@ -715,7 +811,6 @@ CONFIG_TMPFS=y CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set -# CONFIG_DLM is not set # CONFIG_BINARY_PRINTF is not set # @@ -730,16 +825,19 @@ CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC32=y # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y CONFIG_NLATTR=y -CONFIG_GENERIC_ATOMIC64=y +# CONFIG_AVERAGE is not set # # Kernel hacking # CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=1024 @@ -748,11 +846,12 @@ CONFIG_FRAME_WARN=1024 # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_SPARSE_RCU_POINTER is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -764,16 +863,18 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_TEST_KSTRTOX is not set # CONFIG_PPC_DISABLE_WERROR is not set CONFIG_PPC_WERROR=y CONFIG_PRINT_STACK_DEPTH=64 -# CONFIG_BOOTX_TEXT is not set +CONFIG_BOOTX_TEXT=y # CONFIG_PPC_EARLY_DEBUG is not set # # Security options # # CONFIG_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set CONFIG_DEFAULT_SECURITY_DAC=y @@ -864,6 +965,8 @@ CONFIG_CRYPTO=y # Random Number Generation # # CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set # CONFIG_CRYPTO_HW is not set # diff --git a/target/ppc64/sys-available/qemu-ppc64 b/target/ppc64/sys-available/qemu-ppc64 new file mode 100644 index 000000000..cb559267e --- /dev/null +++ b/target/ppc64/sys-available/qemu-ppc64 @@ -0,0 +1,13 @@ +config ADK_TARGET_SYSTEM_QEMU_PPC64 + bool "Qemu Emulator" + select ADK_ppc64 + select ADK_qemu_ppc64 + select ADK_CPU_PPC64 + select ADK_HARDWARE_QEMU + select ADK_TARGET_WITH_VGA + select ADK_TARGET_WITH_INPUT + select ADK_TARGET_WITH_PCI + select ADK_TARGET_WITH_HDD + help + Support for Qemu Emulator (PPC64). + diff --git a/toolchain/gcc/patches/no-lib64.patch b/toolchain/gcc/patches/no-lib64.patch index 5ad91ea50..5fc1225e1 100644 --- a/toolchain/gcc/patches/no-lib64.patch +++ b/toolchain/gcc/patches/no-lib64.patch @@ -1,6 +1,6 @@ -diff -Nur gcc-4.5.2.orig/gcc/config/i386/linux64.h gcc-4.5.2/gcc/config/i386/linux64.h ---- gcc-4.5.2.orig/gcc/config/i386/linux64.h 2010-03-24 21:44:48.000000000 +0100 -+++ gcc-4.5.2/gcc/config/i386/linux64.h 2011-04-23 22:49:31.087660410 +0200 +diff -Nur gcc-4.5.3.orig/gcc/config/i386/linux64.h gcc-4.5.3/gcc/config/i386/linux64.h +--- gcc-4.5.3.orig/gcc/config/i386/linux64.h 2010-03-24 21:44:48.000000000 +0100 ++++ gcc-4.5.3/gcc/config/i386/linux64.h 2011-08-24 01:58:27.000000000 +0200 @@ -59,7 +59,7 @@ done. */ @@ -10,9 +10,9 @@ diff -Nur gcc-4.5.2.orig/gcc/config/i386/linux64.h gcc-4.5.2/gcc/config/i386/lin #if TARGET_64BIT_DEFAULT #define SPEC_32 "m32" -diff -Nur gcc-4.5.2.orig/gcc/config/i386/t-linux64 gcc-4.5.2/gcc/config/i386/t-linux64 ---- gcc-4.5.2.orig/gcc/config/i386/t-linux64 2009-04-21 21:03:23.000000000 +0200 -+++ gcc-4.5.2/gcc/config/i386/t-linux64 2011-04-23 22:49:31.107660436 +0200 +diff -Nur gcc-4.5.3.orig/gcc/config/i386/t-linux64 gcc-4.5.3/gcc/config/i386/t-linux64 +--- gcc-4.5.3.orig/gcc/config/i386/t-linux64 2009-04-21 21:03:23.000000000 +0200 ++++ gcc-4.5.3/gcc/config/i386/t-linux64 2011-08-24 01:58:27.000000000 +0200 @@ -25,7 +25,7 @@ MULTILIB_OPTIONS = m64/m32 @@ -22,9 +22,9 @@ diff -Nur gcc-4.5.2.orig/gcc/config/i386/t-linux64 gcc-4.5.2/gcc/config/i386/t-l LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib -diff -Nur gcc-4.5.2.orig/gcc/config/mips/linux64.h gcc-4.5.2/gcc/config/mips/linux64.h ---- gcc-4.5.2.orig/gcc/config/mips/linux64.h 2009-02-20 16:20:38.000000000 +0100 -+++ gcc-4.5.2/gcc/config/mips/linux64.h 2011-04-23 22:50:17.267672629 +0200 +diff -Nur gcc-4.5.3.orig/gcc/config/mips/linux64.h gcc-4.5.3/gcc/config/mips/linux64.h +--- gcc-4.5.3.orig/gcc/config/mips/linux64.h 2009-02-20 16:20:38.000000000 +0100 ++++ gcc-4.5.3/gcc/config/mips/linux64.h 2011-08-24 01:58:27.000000000 +0200 @@ -36,9 +36,9 @@ %{profile:-lc_p} %{!profile:-lc}}" @@ -38,9 +38,9 @@ diff -Nur gcc-4.5.2.orig/gcc/config/mips/linux64.h gcc-4.5.2/gcc/config/mips/lin #define LINUX_DYNAMIC_LINKERN32 \ CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERN32, UCLIBC_DYNAMIC_LINKERN32) -diff -Nur gcc-4.5.2.orig/gcc/config/mips/t-linux64 gcc-4.5.2/gcc/config/mips/t-linux64 ---- gcc-4.5.2.orig/gcc/config/mips/t-linux64 2009-04-21 21:03:23.000000000 +0200 -+++ gcc-4.5.2/gcc/config/mips/t-linux64 2011-04-23 22:49:31.207663770 +0200 +diff -Nur gcc-4.5.3.orig/gcc/config/mips/t-linux64 gcc-4.5.3/gcc/config/mips/t-linux64 +--- gcc-4.5.3.orig/gcc/config/mips/t-linux64 2009-04-21 21:03:23.000000000 +0200 ++++ gcc-4.5.3/gcc/config/mips/t-linux64 2011-08-24 01:58:27.000000000 +0200 @@ -18,7 +18,7 @@ MULTILIB_OPTIONS = mabi=n32/mabi=32/mabi=64 @@ -50,3 +50,27 @@ diff -Nur gcc-4.5.2.orig/gcc/config/mips/t-linux64 gcc-4.5.2/gcc/config/mips/t-l EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o +diff -Nur gcc-4.5.3.orig/gcc/config/rs6000/linux64.h gcc-4.5.3/gcc/config/rs6000/linux64.h +--- gcc-4.5.3.orig/gcc/config/rs6000/linux64.h 2010-11-17 07:09:53.000000000 +0100 ++++ gcc-4.5.3/gcc/config/rs6000/linux64.h 2011-08-24 02:01:35.000000000 +0200 +@@ -341,7 +341,7 @@ + #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" + + #define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1" +-#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld64.so.1" ++#define GLIBC_DYNAMIC_LINKER64 "/lib/ld64.so.1" + #define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0" + #define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0" + #if UCLIBC_DEFAULT +diff -Nur gcc-4.5.3.orig/gcc/config/rs6000/t-linux64 gcc-4.5.3/gcc/config/rs6000/t-linux64 +--- gcc-4.5.3.orig/gcc/config/rs6000/t-linux64 2009-04-21 21:03:23.000000000 +0200 ++++ gcc-4.5.3/gcc/config/rs6000/t-linux64 2011-08-24 02:00:50.000000000 +0200 +@@ -36,7 +36,7 @@ + MULTILIB_EXTRA_OPTS = fPIC mstrict-align + MULTILIB_EXCEPTIONS = m64/msoft-float + MULTILIB_EXCLUSIONS = m64/!m32/msoft-float +-MULTILIB_OSDIRNAMES = ../lib64 $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib) nof ++MULTILIB_OSDIRNAMES = ../lib $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib) nof + MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT) + + softfp_wrap_start := '\#ifndef __powerpc64__' -- cgit v1.2.3 From c39e8b5f6441ae3a9ba351bd5e3c2d31e0371415 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 24 Aug 2011 05:38:26 +0200 Subject: add qemu sparc support --- mk/image.mk | 9 ++ target/config/Config.in | 1 + target/sparc/Makefile | 8 ++ target/sparc/kernel.config | 167 +++++++++++++++++++++++++++++++--- target/sparc/sys-available/qemu-sparc | 13 +++ 5 files changed, 183 insertions(+), 15 deletions(-) create mode 100644 target/sparc/sys-available/qemu-sparc diff --git a/mk/image.mk b/mk/image.mk index 8053ba43d..185164c22 100644 --- a/mk/image.mk +++ b/mk/image.mk @@ -65,12 +65,21 @@ kernel-package: $(KERNEL) $(TRACE) target/$(ADK_TARGET_ARCH)-install-kernel-package $(PKG_INSTALL) $(KERNEL_PKG) $(MAKE_TRACE) +ifeq ($(ADK_HARDWARE_QEMU),y) +TARGET_KERNEL= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_FS}-kernel +INITRAMFS= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_LIBC}-${ADK_TARGET_FS} +ROOTFSSQUASHFS= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}.img +ROOTFSTARBALL= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}+kernel.tar.gz +ROOTFSUSERTARBALL= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}.tar.gz +INITRAMFS_PIGGYBACK= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}.cpio +else TARGET_KERNEL= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_FS}-kernel INITRAMFS= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}-${ADK_TARGET_FS} ROOTFSSQUASHFS= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}.img ROOTFSTARBALL= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}+kernel.tar.gz ROOTFSUSERTARBALL= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}.tar.gz INITRAMFS_PIGGYBACK= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}.cpio +endif ${BIN_DIR}/${ROOTFSTARBALL}: ${TARGET_DIR} kernel-package cd ${TARGET_DIR}; find . | sed -n '/^\.\//s///p' | \ diff --git a/target/config/Config.in b/target/config/Config.in index a5bbf06ef..62bcbf071 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -371,6 +371,7 @@ config ADK_TARGET_LIB_EGLIBC ADK_LINUX_MIPS64EL || \ ADK_LINUX_PPC || \ ADK_LINUX_PPC64 || \ + ADK_LINUX_SPARC || \ ADK_LINUX_SPARC64 || \ ADK_LINUX_X86 || \ ADK_LINUX_X86_64 diff --git a/target/sparc/Makefile b/target/sparc/Makefile index 39212d52e..5fe97c12a 100644 --- a/target/sparc/Makefile +++ b/target/sparc/Makefile @@ -20,9 +20,17 @@ imageinstall: $(BIN_DIR)/$(INITRAMFS) @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_SPARC),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-sparc -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' +endif endif ifeq ($(ADK_TARGET_FS),initramfs-piggyback) imageinstall: ${BUILD_DIR}/${INITRAMFS_PIGGYBACK} createinitramfs @cp $(KERNEL) $(BIN_DIR)/${TARGET_KERNEL} @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_SPARC),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-sparc -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' +endif endif diff --git a/target/sparc/kernel.config b/target/sparc/kernel.config index 47f75db63..7f48a15da 100644 --- a/target/sparc/kernel.config +++ b/target/sparc/kernel.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux/sparc 2.6.39-rc7 Kernel Configuration -# Sat May 21 13:52:37 2011 +# Linux/sparc 2.6.39 Kernel Configuration +# Wed Aug 24 05:35:52 2011 # # CONFIG_64BIT is not set CONFIG_SPARC=y @@ -250,6 +250,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ATM is not set # CONFIG_L2TP is not set # CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set @@ -304,6 +305,7 @@ CONFIG_OF=y # CONFIG_OF_PROMTREE=y CONFIG_OF_DEVICE=y +CONFIG_OF_NET=y # CONFIG_PARPORT is not set # CONFIG_BLK_DEV is not set # CONFIG_SENSORS_LIS3LV02D is not set @@ -316,11 +318,90 @@ CONFIG_HAVE_IDE=y # CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +# CONFIG_BLK_DEV_SD is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_SCSI_BNX2X_FCOE is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_FCOE is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLOGICPTI is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_SUNESP=y +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set # CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set # CONFIG_FUSION is not set # @@ -329,7 +410,62 @@ CONFIG_SCSI_MOD=y # CONFIG_FIREWIRE is not set # CONFIG_FIREWIRE_NOSY is not set # CONFIG_I2O is not set -# CONFIG_NETDEVICES is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +# CONFIG_MII is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_SUNLANCE=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_ETHOC is not set +# CONFIG_GRETH is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_ATL2 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set + +# +# CAIF transport drivers +# +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -384,25 +520,20 @@ CONFIG_UNIX98_PTYS=y # # Serial drivers # -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250 is not set # # Non-8250 serial port support # # CONFIG_SERIAL_MFD_HSU is not set CONFIG_SERIAL_SUNCORE=y -# CONFIG_SERIAL_SUNZILOG is not set +CONFIG_SERIAL_SUNZILOG=y +CONFIG_SERIAL_SUNZILOG_CONSOLE=y # CONFIG_SERIAL_SUNSU is not set # CONFIG_SERIAL_SUNSAB is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_OF_PLATFORM is not set # CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set @@ -535,9 +666,10 @@ CONFIG_RTC_DRV_M48T59=y # CONFIG_XFS_FS is not set # CONFIG_BTRFS_FS is not set # CONFIG_NILFS2_FS is not set -# CONFIG_FS_POSIX_ACL is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y -# CONFIG_FSNOTIFY is not set +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set # CONFIG_FANOTIFY is not set @@ -712,6 +844,11 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_USER_API_HASH is not set # CONFIG_CRYPTO_USER_API_SKCIPHER is not set # CONFIG_CRYPTO_HW is not set + +# +# OCF Configuration +# +# CONFIG_OCF_OCF is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/target/sparc/sys-available/qemu-sparc b/target/sparc/sys-available/qemu-sparc new file mode 100644 index 000000000..0a20db581 --- /dev/null +++ b/target/sparc/sys-available/qemu-sparc @@ -0,0 +1,13 @@ +config ADK_TARGET_SYSTEM_QEMU_SPARC + bool "Qemu Emulator" + select ADK_sparc + select ADK_qemu_sparc + select ADK_CPU_SPARC_V8 + select ADK_HARDWARE_QEMU + select ADK_TARGET_WITH_VGA + select ADK_TARGET_WITH_INPUT + select ADK_TARGET_WITH_PCI + select ADK_TARGET_WITH_HDD + help + Support for Qemu Emulator (SPARC). + -- cgit v1.2.3 From 0e930c133951dffe8c933fe02f67e72fec57dc8d Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 24 Aug 2011 06:08:24 +0200 Subject: sync patch with OpenWrt, combine both targets (rb411/rb433) --- mk/rootfs.mk | 2 +- package/adkinstall/Makefile | 5 +- target/linux/Config.in | 1 + target/linux/config/Config.in.flash | 3 +- target/linux/config/Config.in.netdevice | 3 +- target/linux/config/Config.in.spi | 14 + target/linux/patches/2.6.39/rb4xx.patch | 36530 ++++++++++++++++++----------- target/mips/Makefile | 6 +- target/mips/kernel.config | 212 +- target/mips/sys-available/mikrotik-rb411 | 13 - target/mips/sys-available/mikrotik-rb433 | 13 - target/mips/sys-available/mikrotik-rb4xx | 15 + 12 files changed, 23402 insertions(+), 13415 deletions(-) create mode 100644 target/linux/config/Config.in.spi delete mode 100644 target/mips/sys-available/mikrotik-rb411 delete mode 100644 target/mips/sys-available/mikrotik-rb433 create mode 100644 target/mips/sys-available/mikrotik-rb4xx diff --git a/mk/rootfs.mk b/mk/rootfs.mk index 241a237fa..5080944e6 100644 --- a/mk/rootfs.mk +++ b/mk/rootfs.mk @@ -17,7 +17,7 @@ ROOTFS:= root=/dev/sda2 MTDDEV:= root=/dev/mtdblock1 endif -ifeq ($(ADK_TARGET_SYSTEM_MIKROTIK_RB433),y) +ifeq ($(ADK_TARGET_SYSTEM_MIKROTIK_RB4XX),y) MTDDEV:= root=/dev/mtdblock2 endif diff --git a/package/adkinstall/Makefile b/package/adkinstall/Makefile index 6aae012f8..a4ab0d8eb 100644 --- a/package/adkinstall/Makefile +++ b/package/adkinstall/Makefile @@ -36,10 +36,7 @@ else ifeq ($(ADK_TARGET_SYSTEM_ACMESYSTEMS_FOXG20),y) else ifeq ($(ADK_TARGET_SYSTEM_LEMOTE_YEELONG),y) ${INSTALL_BIN} ./src/adkinstall.yeelong \ $(IDIR_ADKINSTALL)/sbin/adkinstall -else ifeq ($(ADK_TARGET_SYSTEM_MIKROTIK_RB411),y) - ${INSTALL_BIN} ./src/adkinstall.rb4xx \ - $(IDIR_ADKINSTALL)/sbin/adkinstall -else ifeq ($(ADK_TARGET_SYSTEM_MIKROTIK_RB433),y) +else ifeq ($(ADK_TARGET_SYSTEM_MIKROTIK_RB4XX),y) ${INSTALL_BIN} ./src/adkinstall.rb4xx \ $(IDIR_ADKINSTALL)/sbin/adkinstall else diff --git a/target/linux/Config.in b/target/linux/Config.in index cf4890059..7b52a3003 100644 --- a/target/linux/Config.in +++ b/target/linux/Config.in @@ -20,5 +20,6 @@ source target/linux/config/Config.in.misc source target/linux/config/Config.in.mips source target/linux/config/Config.in.lib source target/linux/config/Config.in.pm +source target/linux/config/Config.in.spi source target/linux/config/Config.in.kvm source target/linux/config/Config.in.debug diff --git a/target/linux/config/Config.in.flash b/target/linux/config/Config.in.flash index 4d9bf6828..3e2898617 100644 --- a/target/linux/config/Config.in.flash +++ b/target/linux/config/Config.in.flash @@ -43,8 +43,7 @@ config ADK_KERNEL_MTD_CFI_ADV_OPTIONS config ADK_KERNEL_MTD_NAND_RB4XX boolean - default y if ADK_TARGET_SYSTEM_MIKROTIK_RB411 - default y if ADK_TARGET_SYSTEM_MIKROTIK_RB433 + default y if ADK_TARGET_SYSTEM_MIKROTIK_RB4XX default n config ADK_KERNEL_MTD_AR7_PARTS diff --git a/target/linux/config/Config.in.netdevice b/target/linux/config/Config.in.netdevice index 1a84f6bcc..cd90f3af2 100644 --- a/target/linux/config/Config.in.netdevice +++ b/target/linux/config/Config.in.netdevice @@ -104,8 +104,7 @@ config ADK_KERNEL_AG71XX select ADK_KERNEL_NET_PCI select ADK_KERNEL_MII select ADK_KERNEL_NETDEV_1000 - default y if ADK_TARGET_SYSTEM_MIKROTIK_RB411 - default y if ADK_TARGET_SYSTEM_MIKROTIK_RB433 + default y if ADK_TARGET_SYSTEM_MIKROTIK_RB4XX default n help diff --git a/target/linux/config/Config.in.spi b/target/linux/config/Config.in.spi new file mode 100644 index 000000000..a141f8231 --- /dev/null +++ b/target/linux/config/Config.in.spi @@ -0,0 +1,14 @@ +config ADK_KERNEL_SPI + boolean + +config ADK_KERNEL_SPI_AR71XX + select ADK_KERNEL_SPI + boolean + +config ADK_KERNEL_SPI_RB4XX + select ADK_KERNEL_SPI + boolean + +config ADK_KERNEL_SPI_RB4XX_CPLD + select ADK_KERNEL_SPI + boolean diff --git a/target/linux/patches/2.6.39/rb4xx.patch b/target/linux/patches/2.6.39/rb4xx.patch index 1739221bf..49fd204d7 100644 --- a/target/linux/patches/2.6.39/rb4xx.patch +++ b/target/linux/patches/2.6.39/rb4xx.patch @@ -1,548 +1,223 @@ -diff -Nur linux-2.6.39.orig/arch/mips/Kconfig linux-2.6.39/arch/mips/Kconfig ---- linux-2.6.39.orig/arch/mips/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/Kconfig 2011-05-27 14:36:50.000000000 +0200 -@@ -84,6 +84,23 @@ - help - Support for the Atheros AR71XX/AR724X/AR913X SoCs. - -+config ATHEROS_AR71XX -+ bool "Atheros AR71xx based boards" -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select HW_HAS_PCI -+ select IRQ_CPU -+ select ARCH_REQUIRE_GPIOLIB -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_HAS_CPU_MIPS32_R2 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_HAS_EARLY_PRINTK -+ select MIPS_MACHINE -+ help -+ Support for Atheros AR71xx based boards. +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.39/arch/mips/ar71xx/ar71xx.c +--- linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/ar71xx.c 2011-08-24 02:41:55.227990426 +0200 +@@ -0,0 +1,230 @@ ++/* ++ * AR71xx SoC routines ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + - config BCM47XX - bool "Broadcom BCM47XX based boards" - select CEVT_R4K -@@ -740,6 +757,7 @@ - - source "arch/mips/alchemy/Kconfig" - source "arch/mips/ath79/Kconfig" -+source "arch/mips/ar71xx/Kconfig" - source "arch/mips/bcm63xx/Kconfig" - source "arch/mips/jazz/Kconfig" - source "arch/mips/jz4740/Kconfig" -diff -Nur linux-2.6.39.orig/arch/mips/Makefile linux-2.6.39/arch/mips/Makefile ---- linux-2.6.39.orig/arch/mips/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/Makefile 2011-05-27 14:36:50.000000000 +0200 -@@ -158,6 +158,13 @@ - endif - cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1 - -+# -+# Atheros AR71xx -+# -+core-$(CONFIG_ATHEROS_AR71XX) += arch/mips/ar71xx/ -+cflags-$(CONFIG_ATHEROS_AR71XX) += -I$(srctree)/arch/mips/include/asm/mach-ar71xx -+load-$(CONFIG_ATHEROS_AR71XX) += 0xffffffff80060000 ++#include ++#include ++#include ++#include ++#include + - cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,) - cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,) - cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,) -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Kconfig linux-2.6.39/arch/mips/ar71xx/Kconfig ---- linux-2.6.39.orig/arch/mips/ar71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/Kconfig 2011-05-27 14:36:50.000000000 +0200 -@@ -0,0 +1,264 @@ -+if ATHEROS_AR71XX ++#include + -+menu "Atheros AR71xx machine selection" ++static DEFINE_MUTEX(ar71xx_flash_mutex); ++static DEFINE_SPINLOCK(ar71xx_device_lock); + -+config AR71XX_MACH_AP81 -+ bool "Atheros AP81 board support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++void __iomem *ar71xx_ddr_base; ++EXPORT_SYMBOL_GPL(ar71xx_ddr_base); + -+config AR71XX_MACH_AP83 -+ bool "Atheros AP83 board support" -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++void __iomem *ar71xx_pll_base; ++EXPORT_SYMBOL_GPL(ar71xx_pll_base); + -+config AR71XX_MACH_DIR_600_A1 -+ bool "D-Link DIR-600 rev. A1 support" -+ select AR71XX_DEV_AP91_ETH -+ select AR71XX_DEV_AP91_PCI if PCI -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_NVRAM -+ default n ++void __iomem *ar71xx_reset_base; ++EXPORT_SYMBOL_GPL(ar71xx_reset_base); + -+config AR71XX_MACH_DIR_615_C1 -+ bool "D-Link DIR-615 rev. C1 support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_NVRAM -+ default n ++void __iomem *ar71xx_gpio_base; ++EXPORT_SYMBOL_GPL(ar71xx_gpio_base); + -+config AR71XX_MACH_DIR_825_B1 -+ bool "D-Link DIR-825 rev. B1 board support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP94_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++void __iomem *ar71xx_usb_ctrl_base; ++EXPORT_SYMBOL_GPL(ar71xx_usb_ctrl_base); + -+config AR71XX_MACH_PB42 -+ bool "Atheros PB42 board support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB42_PCI if PCI -+ default n ++void ar71xx_device_stop(u32 mask) ++{ ++ unsigned long flags; ++ u32 mask_inv; ++ u32 t; + -+config AR71XX_MACH_PB44 -+ bool "Atheros PB44 board support" -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+config AR71XX_MACH_PB92 -+ bool "Atheros PB92 board support" -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB9X_PCI if PCI -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240; ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); ++ t |= mask; ++ t &= ~mask_inv; ++ ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+config AR71XX_MACH_AW_NR580 -+ bool "AzureWave AW-NR580 board support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t | mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+config AR71XX_MACH_WZR_HP_G300NH -+ bool "Buffalo WZR-HP-G300NH board support" -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default y ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR933X_RESET_REG_RESET_MODULE, t | mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+config AR71XX_MACH_WP543 -+ bool "Compex WP543/WPJ543 board support" -+ select MYLOADER -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR934X_RESET_REG_RESET_MODULE, t | mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+config AR71XX_MACH_WRT160NL -+ bool "Linksys WRT160NL board support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ select AR71XX_NVRAM -+ default n ++ default: ++ BUG(); ++ } ++} ++EXPORT_SYMBOL_GPL(ar71xx_device_stop); + -+config AR71XX_MACH_WRT400N -+ bool "Linksys WRT400N board support" -+ select AR71XX_DEV_AP94_PCI if PCI -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++void ar71xx_device_start(u32 mask) ++{ ++ unsigned long flags; ++ u32 mask_inv; ++ u32 t; + -+config AR71XX_MACH_RB4XX -+ bool "MikroTik RouterBOARD 4xx series support" -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t & ~mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+config AR71XX_MACH_RB750 -+ bool "MikroTik RouterBOARD 750 support" -+ select AR71XX_DEV_AP91_ETH -+ default n ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240; ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); ++ t &= ~mask; ++ t |= mask_inv; ++ ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+config AR71XX_MACH_WNDR3700 -+ bool "NETGEAR WNDR3700 board support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP94_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t & ~mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+config AR71XX_MACH_WNR2000 -+ bool "NETGEAR WNR2000 board support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR933X_RESET_REG_RESET_MODULE, t & ~mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+config AR71XX_MACH_MZK_W04NU -+ bool "Planex MZK-W04NU board support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n -+ -+config AR71XX_MACH_MZK_W300NH -+ bool "Planex MZK-W300NH board support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n -+ -+config AR71XX_MACH_NBG460N -+ bool "Zyxel NBG460N/550N/550NH board support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n -+ -+config AR71XX_MACH_TL_WR741ND -+ bool "TP-LINK TL-WR741ND support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP91_ETH -+ select AR71XX_DEV_AP91_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n -+ -+config AR71XX_MACH_TL_WR841N_V1 -+ bool "TP-LINK TL-WR841N v1 support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_DSA -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n -+ -+config AR71XX_MACH_TL_WR941ND -+ bool "TP-LINK TL-WR941ND support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_DSA -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n -+ -+config AR71XX_MACH_TL_WR1043ND -+ bool "TP-LINK TL-WR1043ND support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n -+ -+config AR71XX_MACH_TEW_632BRP -+ bool "TRENDnet TEW-632BRP support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR913X_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_NVRAM -+ default n -+ -+config AR71XX_MACH_UBNT -+ bool "Ubiquiti AR71xx based boards support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP91_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_USB -+ default n -+ -+endmenu -+ -+config AR71XX_DEV_M25P80 -+ def_bool n -+ -+config AR71XX_DEV_AP91_PCI -+ def_bool n -+ -+config AR71XX_DEV_AP91_ETH -+ def_bool n -+ -+config AR71XX_DEV_AP94_PCI -+ def_bool n -+ -+config AR71XX_DEV_AR913X_WMAC -+ def_bool n -+ -+config AR71XX_DEV_DSA -+ def_bool n -+ -+config AR71XX_DEV_GPIO_BUTTONS -+ def_bool n -+ -+config AR71XX_DEV_LEDS_GPIO -+ def_bool n -+ -+config AR71XX_DEV_PB42_PCI -+ def_bool n -+ -+config AR71XX_DEV_PB9X_PCI -+ def_bool n -+ -+config AR71XX_DEV_USB -+ def_bool n -+ -+config AR71XX_NVRAM -+ def_bool n -+ -+endif -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Makefile linux-2.6.39/arch/mips/ar71xx/Makefile ---- linux-2.6.39.orig/arch/mips/ar71xx/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/Makefile 2011-05-27 14:36:50.000000000 +0200 -@@ -0,0 +1,54 @@ -+# -+# Makefile for the Atheros AR71xx SoC specific parts of the kernel -+# -+# Copyright (C) 2008-2009 Gabor Juhos -+# Copyright (C) 2008 Imre Kaloz -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License version 2 as published -+# by the Free Software Foundation. -+ -+obj-y := prom.o irq.o setup.o devices.o gpio.o ar71xx.o -+ -+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -+obj-$(CONFIG_PCI) += pci.o -+ -+obj-$(CONFIG_AR71XX_DEV_AP91_ETH) += dev-ap91-eth.o -+obj-$(CONFIG_AR71XX_DEV_AP91_PCI) += dev-ap91-pci.o -+obj-$(CONFIG_AR71XX_DEV_AP94_PCI) += dev-ap94-pci.o -+obj-$(CONFIG_AR71XX_DEV_AR913X_WMAC) += dev-ar913x-wmac.o -+obj-$(CONFIG_AR71XX_DEV_DSA) += dev-dsa.o -+obj-$(CONFIG_AR71XX_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o -+obj-$(CONFIG_AR71XX_DEV_LEDS_GPIO) += dev-leds-gpio.o -+obj-$(CONFIG_AR71XX_DEV_M25P80) += dev-m25p80.o -+obj-$(CONFIG_AR71XX_DEV_PB42_PCI) += dev-pb42-pci.o -+obj-$(CONFIG_AR71XX_DEV_PB9X_PCI) += dev-pb9x-pci.o -+obj-$(CONFIG_AR71XX_DEV_USB) += dev-usb.o -+ -+obj-$(CONFIG_AR71XX_NVRAM) += nvram.o -+ -+obj-$(CONFIG_AR71XX_MACH_AP81) += mach-ap81.o -+obj-$(CONFIG_AR71XX_MACH_AP83) += mach-ap83.o -+obj-$(CONFIG_AR71XX_MACH_AW_NR580) += mach-aw-nr580.o -+obj-$(CONFIG_AR71XX_MACH_DIR_600_A1) += mach-dir-600-a1.o -+obj-$(CONFIG_AR71XX_MACH_DIR_615_C1) += mach-dir-615-c1.o -+obj-$(CONFIG_AR71XX_MACH_DIR_825_B1) += mach-dir-825-b1.o -+obj-$(CONFIG_AR71XX_MACH_MZK_W04NU) += mach-mzk-w04nu.o -+obj-$(CONFIG_AR71XX_MACH_MZK_W300NH) += mach-mzk-w300nh.o -+obj-$(CONFIG_AR71XX_MACH_NBG460N) += mach-nbg460n.o -+obj-$(CONFIG_AR71XX_MACH_PB42) += mach-pb42.o -+obj-$(CONFIG_AR71XX_MACH_PB44) += mach-pb44.o -+obj-$(CONFIG_AR71XX_MACH_PB92) += mach-pb92.o -+obj-$(CONFIG_AR71XX_MACH_RB4XX) += mach-rb4xx.o -+obj-$(CONFIG_AR71XX_MACH_RB750) += mach-rb750.o -+obj-$(CONFIG_AR71XX_MACH_TEW_632BRP) += mach-tew-632brp.o -+obj-$(CONFIG_AR71XX_MACH_TL_WR741ND) += mach-tl-wr741nd.o -+obj-$(CONFIG_AR71XX_MACH_TL_WR841N_V1) += mach-tl-wr841n.o -+obj-$(CONFIG_AR71XX_MACH_TL_WR941ND) += mach-tl-wr941nd.o -+obj-$(CONFIG_AR71XX_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o -+obj-$(CONFIG_AR71XX_MACH_UBNT) += mach-ubnt.o -+obj-$(CONFIG_AR71XX_MACH_WNDR3700) += mach-wndr3700.o -+obj-$(CONFIG_AR71XX_MACH_WNR2000) += mach-wnr2000.o -+obj-$(CONFIG_AR71XX_MACH_WP543) += mach-wp543.o -+obj-$(CONFIG_AR71XX_MACH_WRT160NL) += mach-wrt160nl.o -+obj-$(CONFIG_AR71XX_MACH_WRT400N) += mach-wrt400n.o -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.39/arch/mips/ar71xx/ar71xx.c ---- linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/ar71xx.c 2011-05-27 14:36:50.000000000 +0200 -@@ -0,0 +1,177 @@ -+/* -+ * AR71xx SoC routines -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+static DEFINE_MUTEX(ar71xx_flash_mutex); -+ -+void __iomem *ar71xx_ddr_base; -+EXPORT_SYMBOL_GPL(ar71xx_ddr_base); -+ -+void __iomem *ar71xx_pll_base; -+EXPORT_SYMBOL_GPL(ar71xx_pll_base); -+ -+void __iomem *ar71xx_reset_base; -+EXPORT_SYMBOL_GPL(ar71xx_reset_base); -+ -+void __iomem *ar71xx_gpio_base; -+EXPORT_SYMBOL_GPL(ar71xx_gpio_base); -+ -+void __iomem *ar71xx_usb_ctrl_base; -+EXPORT_SYMBOL_GPL(ar71xx_usb_ctrl_base); -+ -+void ar71xx_device_stop(u32 mask) -+{ -+ unsigned long flags; -+ u32 mask_inv; -+ u32 t; -+ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ local_irq_save(flags); -+ t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | mask); -+ local_irq_restore(flags); -+ break; -+ -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240; -+ local_irq_save(flags); -+ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); -+ t |= mask; -+ t &= ~mask_inv; -+ ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t); -+ local_irq_restore(flags); -+ break; -+ -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ local_irq_save(flags); -+ t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t | mask); -+ local_irq_restore(flags); ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR934X_RESET_REG_RESET_MODULE, t & ~mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); + break; + + default: + BUG(); + } +} -+EXPORT_SYMBOL_GPL(ar71xx_device_stop); ++EXPORT_SYMBOL_GPL(ar71xx_device_start); + -+void ar71xx_device_start(u32 mask) ++int ar71xx_device_stopped(u32 mask) +{ + unsigned long flags; -+ u32 mask_inv; + u32 t; + + switch (ar71xx_soc) { + case AR71XX_SOC_AR7130: + case AR71XX_SOC_AR7141: + case AR71XX_SOC_AR7161: -+ local_irq_save(flags); ++ spin_lock_irqsave(&ar71xx_device_lock, flags); + t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t & ~mask); -+ local_irq_restore(flags); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); + break; + + case AR71XX_SOC_AR7240: + case AR71XX_SOC_AR7241: + case AR71XX_SOC_AR7242: -+ mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240; -+ local_irq_save(flags); ++ spin_lock_irqsave(&ar71xx_device_lock, flags); + t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); -+ t &= ~mask; -+ t |= mask_inv; -+ ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t); -+ local_irq_restore(flags); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); + break; + + case AR71XX_SOC_AR9130: + case AR71XX_SOC_AR9132: -+ local_irq_save(flags); ++ spin_lock_irqsave(&ar71xx_device_lock, flags); + t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t & ~mask); -+ local_irq_restore(flags); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; ++ ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; ++ ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); + break; + + default: + BUG(); + } ++ ++ return ((t & mask) == mask); +} -+EXPORT_SYMBOL_GPL(ar71xx_device_start); ++EXPORT_SYMBOL_GPL(ar71xx_device_stopped); + -+int ar71xx_device_stopped(u32 mask) ++void ar71xx_ddr_flush(u32 reg) +{ -+ unsigned long flags; -+ u32 t; -+ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ local_irq_save(flags); -+ t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE); -+ local_irq_restore(flags); -+ break; -+ -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ local_irq_save(flags); -+ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); -+ local_irq_restore(flags); -+ break; -+ -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ local_irq_save(flags); -+ t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); -+ local_irq_restore(flags); -+ break; -+ -+ default: -+ BUG(); -+ } -+ -+ return ((t & mask) == mask); -+} -+EXPORT_SYMBOL_GPL(ar71xx_device_stopped); -+ -+void ar71xx_ddr_flush(u32 reg) -+{ -+ ar71xx_ddr_wr(reg, 1); -+ while ((ar71xx_ddr_rr(reg) & 0x1)); ++ ar71xx_ddr_wr(reg, 1); ++ while ((ar71xx_ddr_rr(reg) & 0x1)) ++ ; + + ar71xx_ddr_wr(reg, 1); -+ while ((ar71xx_ddr_rr(reg) & 0x1)); ++ while ((ar71xx_ddr_rr(reg) & 0x1)) ++ ; +} +EXPORT_SYMBOL_GPL(ar71xx_ddr_flush); + @@ -557,111 +232,10 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.39/arch/mips/ar7 + mutex_unlock(&ar71xx_flash_mutex); +} +EXPORT_SYMBOL_GPL(ar71xx_flash_release); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-eth.c linux-2.6.39/arch/mips/ar71xx/dev-ap91-eth.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-eth.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-eth.c 2011-05-27 14:36:50.000000000 +0200 -@@ -0,0 +1,70 @@ -+/* -+ * Atheros AP91 reference board ethernet initialization -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "devices.h" -+#include "dev-dsa.h" -+#include "dev-ap91-eth.h" -+ -+static struct dsa_chip_data ap91_dsa_chip = { -+ .port_names[0] = "cpu", -+ .port_names[1] = "lan1", -+ .port_names[2] = "lan2", -+ .port_names[3] = "lan3", -+ .port_names[4] = "lan4", -+}; -+ -+static struct dsa_platform_data ap91_dsa_data = { -+ .nr_chips = 1, -+ .chip = &ap91_dsa_chip, -+}; -+ -+static void ap91_eth_set_port_name(unsigned port, const char *name) -+{ -+ if (port < 1 || port > 5) -+ return; -+ -+ if (name) -+ ap91_dsa_chip.port_names[port] = (char *) name; -+} -+ -+void __init ap91_eth_init(u8 *mac_addr, const char *port_names[]) -+{ -+ if (mac_addr) -+ ar71xx_set_mac_base(mac_addr); -+ -+ if (port_names) { -+ int i; -+ -+ for (i = 0; i < AP91_ETH_NUM_PORT_NAMES; i++) -+ ap91_eth_set_port_name(i + 1, port_names[i]); -+ } -+ -+ /* WAN port */ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.fifo_cfg1 = 0x0fff0000; -+ ar71xx_eth0_data.fifo_cfg2 = 0x00001fff; -+ ar71xx_eth0_data.fifo_cfg3 = 0x008001ff; -+ -+ /* LAN ports */ -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; -+ ar71xx_eth1_data.fifo_cfg1 = 0x0fff0000; -+ ar71xx_eth1_data.fifo_cfg2 = 0x00001fff; -+ ar71xx_eth1_data.fifo_cfg3 = 0x008001ff; -+ -+ ar71xx_add_device_mdio(0x0); -+ ar71xx_add_device_eth(1); -+ ar71xx_add_device_eth(0); -+ -+ ar71xx_add_device_dsa(1, &ap91_dsa_data); -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-eth.h linux-2.6.39/arch/mips/ar71xx/dev-ap91-eth.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-eth.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-eth.h 2011-05-27 14:36:50.000000000 +0200 -@@ -0,0 +1,23 @@ -+/* -+ * Atheros AP91 reference board ethernet initialization -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _AR71XX_DEV_AP91_ETH_H -+#define _AR71XX_DEV_AP91_ETH_H -+ -+#define AP91_ETH_NUM_PORT_NAMES 4 -+ -+#if defined(CONFIG_AR71XX_DEV_AP91_ETH) -+void ap91_eth_init(u8 *mac_addr, const char *port_names[]) __init; -+#else -+static inline void ap91_eth_init(u8 *mac_addr) { } -+#endif -+ -+#endif /* _AR71XX_DEV_AP91_ETH_H */ -+ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.c --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.c 2011-05-27 14:36:50.000000000 +0200 -@@ -0,0 +1,114 @@ ++++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.c 2011-08-24 02:41:55.277990824 +0200 +@@ -0,0 +1,71 @@ +/* + * Atheros AP91 reference board PCI initialization + * @@ -680,10 +254,12 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.39/arch/mi +#include + +#include "dev-ap91-pci.h" ++#include "pci-ath9k-fixup.h" + -+static struct ath9k_platform_data ap91_wmac_data; ++static struct ath9k_platform_data ap91_wmac_data = { ++ .led_pin = -1, ++}; +static char ap91_wmac_mac[6]; -+static int ap91_pci_fixup_enabled; + +static struct ar71xx_pci_irq ap91_pci_irqs[] __initdata = { + { @@ -695,7 +271,7 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.39/arch/mi + +static int ap91_pci_plat_dev_init(struct pci_dev *dev) +{ -+ switch(PCI_SLOT(dev->devfn)) { ++ switch (PCI_SLOT(dev->devfn)) { + case 0: + dev->dev.platform_data = &ap91_wmac_data; + break; @@ -704,61 +280,16 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.39/arch/mi + return 0; +} + -+static void ap91_pci_fixup(struct pci_dev *dev) ++__init void ap91_pci_setup_wmac_led_pin(int pin) +{ -+ void __iomem *mem; -+ u16 *cal_data; -+ u16 cmd; -+ u32 val; -+ -+ if (!ap91_pci_fixup_enabled) -+ return; -+ -+ printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev)); -+ -+ cal_data = ap91_wmac_data.eeprom_data; -+ if (*cal_data != 0xa55a) { -+ printk(KERN_ERR "PCI: no calibration data found for %s\n", -+ pci_name(dev)); -+ return; -+ } -+ -+ mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000); -+ if (!mem) { -+ printk(KERN_ERR "PCI: ioremap error for device %s\n", -+ pci_name(dev)); -+ return; -+ } -+ -+ /* Setup the PCI device to allow access to the internal registers */ -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff); -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ -+ /* set pointer to first reg address */ -+ cal_data += 3; -+ while (*cal_data != 0xffff) { -+ u32 reg; -+ reg = *cal_data++; -+ val = *cal_data++; -+ val |= (*cal_data++) << 16; -+ -+ __raw_writel(val, mem + reg); -+ udelay(100); -+ } -+ -+ pci_read_config_dword(dev, PCI_VENDOR_ID, &val); -+ dev->vendor = val & 0xffff; -+ dev->device = (val >> 16) & 0xffff; -+ -+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); -+ dev->revision = val & 0xff; -+ dev->class = val >> 8; /* upper 3 bytes */ ++ ap91_wmac_data.led_pin = pin; ++} + -+ iounmap(mem); ++__init void ap91_pci_setup_wmac_gpio(u32 mask, u32 val) ++{ ++ ap91_wmac_data.gpio_mask = mask; ++ ap91_wmac_data.gpio_val = val; +} -+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap91_pci_fixup); + +void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr) +{ @@ -774,12 +305,12 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.39/arch/mi + ar71xx_pci_plat_dev_init = ap91_pci_plat_dev_init; + ar71xx_pci_init(ARRAY_SIZE(ap91_pci_irqs), ap91_pci_irqs); + -+ ap91_pci_fixup_enabled = 1; ++ pci_enable_ath9k_fixup(0, ap91_wmac_data.eeprom_data); +} diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.h linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.h --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.h 2011-05-27 14:36:50.000000000 +0200 -@@ -0,0 +1,21 @@ ++++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.h 2011-08-24 02:41:55.287981779 +0200 +@@ -0,0 +1,25 @@ +/* + * Atheros AP91 reference board PCI initialization + * @@ -795,16 +326,20 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.h linux-2.6.39/arch/mi + +#if defined(CONFIG_AR71XX_DEV_AP91_PCI) +void ap91_pci_init(u8 *cal_data, u8 *mac_addr) __init; ++void ap91_pci_setup_wmac_led_pin(int pin) __init; ++void ap91_pci_setup_wmac_gpio(u32 mask, u32 val) __init; +#else +static inline void ap91_pci_init(u8 *cal_data, u8 *mac_addr) { } ++static inline void ap91_pci_setup_wmac_led_pin(int pin) { } ++static inline void ap91_pci_setup_wmac_gpio(u32 mask, u32 gpio) { } +#endif + +#endif /* _AR71XX_DEV_AP91_PCI_H */ + diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.c --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,159 @@ ++++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.c 2011-08-24 02:41:55.287981779 +0200 +@@ -0,0 +1,109 @@ +/* + * Atheros AP94 reference board PCI initialization + * @@ -823,28 +358,32 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c linux-2.6.39/arch/mi +#include + +#include "dev-ap94-pci.h" ++#include "pci-ath9k-fixup.h" + -+static struct ath9k_platform_data ap94_wmac0_data; -+static struct ath9k_platform_data ap94_wmac1_data; ++static struct ath9k_platform_data ap94_wmac0_data = { ++ .led_pin = -1, ++}; ++static struct ath9k_platform_data ap94_wmac1_data = { ++ .led_pin = -1, ++}; +static char ap94_wmac0_mac[6]; +static char ap94_wmac1_mac[6]; -+static int ap94_pci_fixup_enabled; + +static struct ar71xx_pci_irq ap94_pci_irqs[] __initdata = { -+ { -+ .slot = 0, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV0, -+ }, { -+ .slot = 1, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV1, -+ } ++ { ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, ++ }, { ++ .slot = 1, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV1, ++ } +}; + +static int ap94_pci_plat_dev_init(struct pci_dev *dev) +{ -+ switch(PCI_SLOT(dev->devfn)) { ++ switch (PCI_SLOT(dev->devfn)) { + case 17: + dev->dev.platform_data = &ap94_wmac0_data; + break; @@ -857,85 +396,30 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c linux-2.6.39/arch/mi + return 0; +} + -+static void ap94_pci_fixup(struct pci_dev *dev) ++__init void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin) +{ -+ void __iomem *mem; -+ u16 *cal_data; -+ u16 cmd; -+ u32 bar0; -+ u32 val; -+ -+ if (!ap94_pci_fixup_enabled) -+ return; -+ -+ switch (PCI_SLOT(dev->devfn)) { -+ case 17: -+ cal_data = ap94_wmac0_data.eeprom_data; ++ switch (wmac) { ++ case 0: ++ ap94_wmac0_data.led_pin = pin; + break; -+ case 18: -+ cal_data = ap94_wmac1_data.eeprom_data; ++ case 1: ++ ap94_wmac1_data.led_pin = pin; + break; -+ default: -+ return; -+ } -+ -+ if (*cal_data != 0xa55a) { -+ printk(KERN_ERR "PCI: no calibration data found for %s\n", -+ pci_name(dev)); -+ return; -+ } -+ -+ mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000); -+ if (!mem) { -+ printk(KERN_ERR "PCI: ioremap error for device %s\n", -+ pci_name(dev)); -+ return; -+ } -+ -+ printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev)); -+ -+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); -+ -+ /* Setup the PCI device to allow access to the internal registers */ -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, AR71XX_PCI_MEM_BASE); -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ -+ /* set pointer to first reg address */ -+ cal_data += 3; -+ while (*cal_data != 0xffff) { -+ u32 reg; -+ reg = *cal_data++; -+ val = *cal_data++; -+ val |= (*cal_data++) << 16; -+ -+ __raw_writel(val, mem + reg); -+ udelay(100); + } -+ -+ pci_read_config_dword(dev, PCI_VENDOR_ID, &val); -+ dev->vendor = val & 0xffff; -+ dev->device = (val >> 16) & 0xffff; -+ -+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); -+ dev->revision = val & 0xff; -+ dev->class = val >> 8; /* upper 3 bytes */ -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); -+ -+ iounmap(mem); +} -+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap94_pci_fixup); + -+void __init ap94_pci_enable_quirk_wndr3700(void) ++__init void ap94_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val) +{ -+ ap94_wmac0_data.quirk_wndr3700 = 1; -+ ap94_wmac1_data.quirk_wndr3700 = 1; ++ switch (wmac) { ++ case 0: ++ ap94_wmac0_data.gpio_mask = mask; ++ ap94_wmac0_data.gpio_val = val; ++ break; ++ case 1: ++ ap94_wmac1_data.gpio_mask = mask; ++ ap94_wmac1_data.gpio_val = val; ++ break; ++ } +} + +void __init ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, @@ -962,12 +446,13 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c linux-2.6.39/arch/mi + ar71xx_pci_plat_dev_init = ap94_pci_plat_dev_init; + ar71xx_pci_init(ARRAY_SIZE(ap94_pci_irqs), ap94_pci_irqs); + -+ ap94_pci_fixup_enabled = 1; ++ pci_enable_ath9k_fixup(17, ap94_wmac0_data.eeprom_data); ++ pci_enable_ath9k_fixup(18, ap94_wmac1_data.eeprom_data); +} diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.h linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.h --- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,28 @@ ++++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.h 2011-08-24 02:41:55.287981779 +0200 +@@ -0,0 +1,31 @@ +/* + * Atheros AP94 reference board PCI initialization + * @@ -985,28 +470,32 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.h linux-2.6.39/arch/mi +void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, + u8 *cal_data1, u8 *mac_addr1) __init; + -+void ap94_pci_enable_quirk_wndr3700(void) __init; ++void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin) __init; ++void ap94_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val) __init; + +#else +static inline void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, + u8 *cal_data1, u8 *mac_addr1) {} + -+static inline void ap94_pci_enable_quirk_wndr3700(void) {} ++static inline void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin) {} ++static inline void ap94_pci_setup_wmac_gpio(unsigned wmac, ++ u32 mask, u32 val) {} +#endif + +#endif /* _AR71XX_DEV_AP94_PCI_H */ + -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar913x-wmac.c linux-2.6.39/arch/mips/ar71xx/dev-ar913x-wmac.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar913x-wmac.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ar913x-wmac.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,68 @@ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.c linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.c 2011-08-24 02:41:55.287981779 +0200 +@@ -0,0 +1,154 @@ +/* -+ * Atheros AR913x SoC built-in WMAC device support ++ * Atheros AR9XXX SoCs built-in WMAC device support + * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -1022,15 +511,18 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar913x-wmac.c linux-2.6.39/arch + +#include + -+#include "dev-ar913x-wmac.h" ++#include "dev-ar9xxx-wmac.h" ++ ++#define MHZ_25 (25 * 1000 * 1000) + -+static struct ath9k_platform_data ar913x_wmac_data; -+static char ar913x_wmac_mac[6]; ++static struct ath9k_platform_data ar9xxx_wmac_data = { ++ .led_pin = -1, ++}; ++static char ar9xxx_wmac_mac[6]; + -+static struct resource ar913x_wmac_resources[] = { ++static struct resource ar9xxx_wmac_resources[] = { + { -+ .start = AR91XX_WMAC_BASE, -+ .end = AR91XX_WMAC_BASE + AR91XX_WMAC_SIZE - 1, ++ /* .start and .end fields are filled dynamically */ + .flags = IORESOURCE_MEM, + }, { + .start = AR71XX_CPU_IRQ_IP2, @@ -1039,90 +531,234 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar913x-wmac.c linux-2.6.39/arch + }, +}; + -+static struct platform_device ar913x_wmac_device = { ++static struct platform_device ar9xxx_wmac_device = { + .name = "ath9k", + .id = -1, -+ .resource = ar913x_wmac_resources, -+ .num_resources = ARRAY_SIZE(ar913x_wmac_resources), ++ .resource = ar9xxx_wmac_resources, ++ .num_resources = ARRAY_SIZE(ar9xxx_wmac_resources), + .dev = { -+ .platform_data = &ar913x_wmac_data, ++ .platform_data = &ar9xxx_wmac_data, + }, +}; + -+void __init ar913x_add_device_wmac(u8 *cal_data, u8 *mac_addr) ++static void ar913x_wmac_init(void) +{ -+ if (cal_data) -+ memcpy(ar913x_wmac_data.eeprom_data, cal_data, -+ sizeof(ar913x_wmac_data.eeprom_data)); -+ -+ if (mac_addr) { -+ memcpy(ar913x_wmac_mac, mac_addr, sizeof(ar913x_wmac_mac)); -+ ar913x_wmac_data.macaddr = ar913x_wmac_mac; -+ } -+ + ar71xx_device_stop(RESET_MODULE_AMBA2WMAC); + mdelay(10); + + ar71xx_device_start(RESET_MODULE_AMBA2WMAC); + mdelay(10); + -+ platform_device_register(&ar913x_wmac_device); ++ ar9xxx_wmac_resources[0].start = AR91XX_WMAC_BASE; ++ ar9xxx_wmac_resources[0].end = AR91XX_WMAC_BASE + AR91XX_WMAC_SIZE - 1; +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar913x-wmac.h linux-2.6.39/arch/mips/ar71xx/dev-ar913x-wmac.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar913x-wmac.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ar913x-wmac.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,19 @@ -+/* -+ * Atheros AR913x SoC built-in WMAC device support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ + -+#ifndef _AR71XX_DEV_AR913X_WMAC_H -+#define _AR71XX_DEV_AR913X_WMAC_H ++static int ar933x_r1_get_wmac_revision(void) ++{ ++ return ar71xx_soc_rev; ++} + -+void ar913x_add_device_wmac(u8 *cal_data, u8 *mac_addr) __init; ++static int ar933x_wmac_reset(void) ++{ ++ unsigned retries = 0; + -+#endif /* _AR71XX_DEV_AR913X_WMAC_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c linux-2.6.39/arch/mips/ar71xx/dev-dsa.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,50 @@ -+/* -+ * Atheros AR71xx DSA switch device support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ ar71xx_device_stop(AR933X_RESET_WMAC); ++ ar71xx_device_start(AR933X_RESET_WMAC); + -+#include -+#include ++ while (1) { ++ u32 bootstrap; + -+#include ++ bootstrap = ar71xx_reset_rr(AR933X_RESET_REG_BOOTSTRAP); ++ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0) ++ return 0; + -+#include "devices.h" -+#include "dev-dsa.h" ++ if (retries > 20) ++ break; + -+static struct platform_device ar71xx_dsa_switch_device = { -+ .name = "dsa", -+ .id = 0, -+}; ++ udelay(10000); ++ retries++; ++ } + -+void __init ar71xx_add_device_dsa(unsigned int id, -+ struct dsa_platform_data *d) -+{ -+ int i; ++ pr_err("ar93xx: WMAC reset timed out"); ++ return -ETIMEDOUT; ++} ++ ++static void ar933x_wmac_init(void) ++{ ++ ar9xxx_wmac_device.name = "ar933x_wmac"; ++ ar9xxx_wmac_resources[0].start = AR933X_WMAC_BASE; ++ ar9xxx_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; ++ if (ar71xx_ref_freq == MHZ_25) ++ ar9xxx_wmac_data.is_clk_25mhz = true; ++ ++ if (ar71xx_soc_rev == 1) ++ ar9xxx_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision; ++ ++ ar9xxx_wmac_data.external_reset = ar933x_wmac_reset; ++ ++ ar933x_wmac_reset(); ++} ++ ++static void ar934x_wmac_init(void) ++{ ++ ar9xxx_wmac_device.name = "ar934x_wmac"; ++ ar9xxx_wmac_resources[0].start = AR934X_WMAC_BASE; ++ ar9xxx_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1; ++ if (ar71xx_ref_freq == MHZ_25) ++ ar9xxx_wmac_data.is_clk_25mhz = true; ++} ++ ++void __init ar9xxx_add_device_wmac(u8 *cal_data, u8 *mac_addr) ++{ ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ ar913x_wmac_init(); ++ break; ++ ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ ar933x_wmac_init(); ++ break; ++ ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ar934x_wmac_init(); ++ break; ++ ++ default: ++ BUG(); ++ } ++ ++ if (cal_data) ++ memcpy(ar9xxx_wmac_data.eeprom_data, cal_data, ++ sizeof(ar9xxx_wmac_data.eeprom_data)); ++ ++ if (mac_addr) { ++ memcpy(ar9xxx_wmac_mac, mac_addr, sizeof(ar9xxx_wmac_mac)); ++ ar9xxx_wmac_data.macaddr = ar9xxx_wmac_mac; ++ } ++ ++ platform_device_register(&ar9xxx_wmac_device); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.h linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.h 2011-08-24 02:41:55.297981663 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * Atheros AR9XXX SoCs built-in WMAC device support ++ * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#ifndef _AR71XX_DEV_AR9XXX_WMAC_H ++#define _AR71XX_DEV_AR9XXX_WMAC_H ++ ++void ar9xxx_add_device_wmac(u8 *cal_data, u8 *mac_addr) __init; ++ ++#endif /* _AR71XX_DEV_AR9XXX_WMAC_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.c linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.c 2011-08-24 02:41:55.317990461 +0200 +@@ -0,0 +1,31 @@ ++/* ++ * Atheros db120 reference board PCI initialization ++ * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * ++ * Parts of this file are based on Atheros linux 2.6.31 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++ ++#include ++#include ++ ++#include "dev-db120-pci.h" ++ ++static struct ar71xx_pci_irq db120_pci_irqs[] __initdata = { ++ { ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, ++ } ++}; ++ ++void __init db120_pci_init(void) ++{ ++ ar71xx_pci_init(ARRAY_SIZE(db120_pci_irqs), db120_pci_irqs); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.h linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.h 2011-08-24 02:41:55.327990934 +0200 +@@ -0,0 +1,22 @@ ++/* ++ * Atheros DB120 reference board PCI initialization ++ * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * ++ * Parts of this file are based on Atheros linux 2.6.31 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#ifndef _AR71XX_DEV_DB120_PCI_H ++#define _AR71XX_DEV_DB120_PCI_H ++ ++#if defined(CONFIG_AR71XX_DEV_DB120_PCI) ++void db120_pci_init(void); ++#else ++static inline void db120_pci_init(void) { } ++#endif ++ ++#endif /* _AR71XX_DEV_DB120_PCI_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c linux-2.6.39/arch/mips/ar71xx/dev-dsa.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.c 2011-08-24 02:41:55.337990441 +0200 +@@ -0,0 +1,50 @@ ++/* ++ * Atheros AR71xx DSA switch device support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++ ++#include ++ ++#include "devices.h" ++#include "dev-dsa.h" ++ ++static struct platform_device ar71xx_dsa_switch_device = { ++ .name = "dsa", ++ .id = 0, ++}; ++ ++void __init ar71xx_add_device_dsa(unsigned int id, ++ struct dsa_platform_data *d) ++{ ++ int i; + + switch (id) { + case 0: @@ -1147,7 +783,7 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c linux-2.6.39/arch/mips/ar +} diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.h linux-2.6.39/arch/mips/ar71xx/dev-dsa.h --- linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.h 2011-05-27 14:36:51.000000000 +0200 ++++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.h 2011-08-24 02:41:55.347990727 +0200 @@ -0,0 +1,20 @@ +/* + * Atheros AR71xx DSA switch device support @@ -1171,7 +807,7 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.h linux-2.6.39/arch/mips/ar +#endif /* _AR71XX_DEV_DSA_H */ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.c --- linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.c 2011-05-27 14:36:51.000000000 +0200 ++++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.c 2011-08-24 02:41:55.347990727 +0200 @@ -0,0 +1,58 @@ +/* + * Atheros AR71xx GPIO button support @@ -1185,18 +821,19 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.39/arc + */ + +#include "linux/init.h" ++#include "linux/slab.h" +#include + +#include "dev-gpio-buttons.h" + -+void __init ar71xx_add_device_gpio_buttons(int id, -+ unsigned poll_interval, -+ unsigned nbuttons, -+ struct gpio_button *buttons) ++void __init ar71xx_register_gpio_keys_polled(int id, ++ unsigned poll_interval, ++ unsigned nbuttons, ++ struct gpio_keys_button *buttons) +{ + struct platform_device *pdev; -+ struct gpio_buttons_platform_data pdata; -+ struct gpio_button *p; ++ struct gpio_keys_platform_data pdata; ++ struct gpio_keys_button *p; + int err; + + p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL); @@ -1205,7 +842,7 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.39/arc + + memcpy(p, buttons, nbuttons * sizeof(*p)); + -+ pdev = platform_device_alloc("gpio-buttons", id); ++ pdev = platform_device_alloc("gpio-keys-polled", id); + if (!pdev) + goto err_free_buttons; + @@ -1218,7 +855,6 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.39/arc + if (err) + goto err_put_pdev; + -+ + err = platform_device_add(pdev); + if (err) + goto err_put_pdev; @@ -1233,8 +869,8 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.39/arc +} diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.h linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.h --- linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,25 @@ ++++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.h 2011-08-24 02:41:55.347990727 +0200 +@@ -0,0 +1,23 @@ +/* + * Atheros AR71xx GPIO button support + * @@ -1250,1169 +886,1121 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.h linux-2.6.39/arc +#define _AR71XX_DEV_GPIO_BUTTONS_H + +#include -+#include -+ -+#include ++#include + -+void ar71xx_add_device_gpio_buttons(int id, -+ unsigned poll_interval, -+ unsigned nbuttons, -+ struct gpio_button *buttons) __init; ++void ar71xx_register_gpio_keys_polled(int id, ++ unsigned poll_interval, ++ unsigned nbuttons, ++ struct gpio_keys_button *buttons); + +#endif /* _AR71XX_DEV_GPIO_BUTTONS_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,57 @@ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.c linux-2.6.39/arch/mips/ar71xx/devices.c +--- linux-2.6.39.orig/arch/mips/ar71xx/devices.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/devices.c 2011-08-24 02:41:55.347990727 +0200 +@@ -0,0 +1,765 @@ +/* -+ * Atheros AR71xx GPIO LED device support ++ * Atheros AR71xx SoC platform devices + * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.31 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include +#include ++#include ++#include +#include -+#include -+ -+#include "dev-leds-gpio.h" -+ -+void __init ar71xx_add_device_leds_gpio(int id, unsigned num_leds, -+ struct gpio_led *leds) -+{ -+ struct platform_device *pdev; -+ struct gpio_led_platform_data pdata; -+ struct gpio_led *p; -+ int err; ++#include + -+ p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL); -+ if (!p) -+ return; ++#include ++#include + -+ memcpy(p, leds, num_leds * sizeof(*p)); ++#include "devices.h" + -+ pdev = platform_device_alloc("leds-gpio", id); -+ if (!pdev) -+ goto err_free_leds; ++unsigned char ar71xx_mac_base[ETH_ALEN] __initdata; + -+ memset(&pdata, 0, sizeof(pdata)); -+ pdata.num_leds = num_leds; -+ pdata.leds = p; ++static struct resource ar71xx_uart_resources[] = { ++ { ++ .start = AR71XX_UART_BASE, ++ .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; + -+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); -+ if (err) -+ goto err_put_pdev; ++#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) ++static struct plat_serial8250_port ar71xx_uart_data[] = { ++ { ++ .mapbase = AR71XX_UART_BASE, ++ .irq = AR71XX_MISC_IRQ_UART, ++ .flags = AR71XX_UART_FLAGS, ++ .iotype = UPIO_MEM32, ++ .regshift = 2, ++ }, { ++ /* terminating entry */ ++ } ++}; + -+ err = platform_device_add(pdev); -+ if (err) -+ goto err_put_pdev; ++static struct platform_device ar71xx_uart_device = { ++ .name = "serial8250", ++ .id = PLAT8250_DEV_PLATFORM, ++ .resource = ar71xx_uart_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_uart_resources), ++ .dev = { ++ .platform_data = ar71xx_uart_data ++ }, ++}; + -+ return; ++static struct resource ar933x_uart_resources[] = { ++ { ++ .start = AR933X_UART_BASE, ++ .end = AR933X_UART_BASE + AR71XX_UART_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = AR71XX_MISC_IRQ_UART, ++ .end = AR71XX_MISC_IRQ_UART, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; + -+err_put_pdev: -+ platform_device_put(pdev); ++static struct ar933x_uart_platform_data ar933x_uart_data; ++static struct platform_device ar933x_uart_device = { ++ .name = "ar933x-uart", ++ .id = -1, ++ .resource = ar933x_uart_resources, ++ .num_resources = ARRAY_SIZE(ar933x_uart_resources), ++ .dev = { ++ .platform_data = &ar933x_uart_data, ++ }, ++}; + -+err_free_leds: -+ kfree(p); -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,21 @@ -+/* -+ * Atheros AR71xx GPIO LED device support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++void __init ar71xx_add_device_uart(void) ++{ ++ struct platform_device *pdev; + -+#ifndef _AR71XX_DEV_LEDS_GPIO_H -+#define _AR71XX_DEV_LEDS_GPIO_H ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ pdev = &ar71xx_uart_device; ++ ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq; ++ break; + -+#include ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ pdev = &ar933x_uart_device; ++ ar933x_uart_data.uartclk = ar71xx_ref_freq; ++ break; + -+void ar71xx_add_device_leds_gpio(int id, -+ unsigned num_leds, -+ struct gpio_led *leds) __init; ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ pdev = &ar71xx_uart_device; ++ ar71xx_uart_data[0].uartclk = ar71xx_ref_freq; ++ break; + -+#endif /* _AR71XX_DEV_LEDS_GPIO_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ default: ++ BUG(); ++ } + -+#include -+#include -+#include ++ platform_device_register(pdev); ++} + -+#include "devices.h" -+#include "dev-m25p80.h" -+ -+static struct spi_board_info ar71xx_spi_info[] = { ++static struct resource ar71xx_mdio_resources[] = { + { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", ++ .name = "mdio_base", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_GE0_BASE, ++ .end = AR71XX_GE0_BASE + 0x200 - 1, + } +}; + -+void __init ar71xx_add_device_m25p80(struct flash_platform_data *pdata) -+{ -+ ar71xx_spi_info[0].platform_data = pdata; -+ ar71xx_add_device_spi(NULL, ar71xx_spi_info, -+ ARRAY_SIZE(ar71xx_spi_info)); -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,16 @@ -+/* -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++static struct ag71xx_mdio_platform_data ar71xx_mdio_data; + -+#ifndef _AR71XX_DEV_M25P80_H -+#define _AR71XX_DEV_M25P80_H ++struct platform_device ar71xx_mdio_device = { ++ .name = "ag71xx-mdio", ++ .id = -1, ++ .resource = ar71xx_mdio_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_mdio_resources), ++ .dev = { ++ .platform_data = &ar71xx_mdio_data, ++ }, ++}; + -+#include ++static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift) ++{ ++ void __iomem *base; ++ u32 t; + -+void ar71xx_add_device_m25p80(struct flash_platform_data *pdata) __init; ++ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); + -+#endif /* _AR71XX_DEV_M25P80_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* -+ * Atheros PB42 reference board PCI initialization -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ t = __raw_readl(base + cfg_reg); ++ t &= ~(3 << shift); ++ t |= (2 << shift); ++ __raw_writel(t, base + cfg_reg); ++ udelay(100); + -+#include ++ __raw_writel(pll_val, base + pll_reg); + -+#include -+#include ++ t |= (3 << shift); ++ __raw_writel(t, base + cfg_reg); ++ udelay(100); + -+#include "dev-pb42-pci.h" ++ t &= ~(3 << shift); ++ __raw_writel(t, base + cfg_reg); ++ udelay(100); + -+static struct ar71xx_pci_irq pb42_pci_irqs[] __initdata = { -+ { -+ .slot = 0, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV0, -+ }, { -+ .slot = 1, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV1, -+ }, { -+ .slot = 2, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV2, -+ } -+}; ++ printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n", ++ (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg)); + -+void __init pb42_pci_init(void) -+{ -+ ar71xx_pci_init(ARRAY_SIZE(pb42_pci_irqs), pb42_pci_irqs); ++ iounmap(base); +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,21 @@ -+/* -+ * Atheros PB42 reference board PCI initialization -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ + -+#ifndef _AR71XX_DEV_PB42_PCI_H -+#define _AR71XX_DEV_PB42_PCI_H ++void __init ar71xx_add_device_mdio(u32 phy_mask) ++{ ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7240: ++ ar71xx_mdio_data.is_ar7240 = 1; ++ break; ++ case AR71XX_SOC_AR7241: ++ ar71xx_mdio_data.is_ar7240 = 1; ++ ar71xx_mdio_resources[0].start = AR71XX_GE1_BASE; ++ ar71xx_mdio_resources[0].end = AR71XX_GE1_BASE + 0x200 - 1; ++ break; ++ case AR71XX_SOC_AR7242: ++ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, ++ AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000, ++ AR71XX_ETH0_PLL_SHIFT); ++ break; ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ ar71xx_mdio_data.is_ar7240 = 1; ++ ar71xx_mdio_resources[0].start = AR71XX_GE1_BASE; ++ ar71xx_mdio_resources[0].end = AR71XX_GE1_BASE + 0x200 - 1; ++ break; ++ default: ++ break; ++ } + -+#if defined(CONFIG_AR71XX_DEV_PB42_PCI) -+void pb42_pci_init(void) __init; -+#else -+static inline void pb42_pci_init(void) { } -+#endif ++ ar71xx_mdio_data.phy_mask = phy_mask; + -+#endif /* _AR71XX_DEV_PB42_PCI_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,33 @@ -+/* -+ * Atheros PB9x reference board PCI initialization -+ * -+ * Copyright (C) 2010 Felix Fietkau -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ platform_device_register(&ar71xx_mdio_device); ++} + -+#include ++struct ar71xx_eth_pll_data ar71xx_eth0_pll_data; ++struct ar71xx_eth_pll_data ar71xx_eth1_pll_data; + -+#include -+#include ++static u32 ar71xx_get_eth_pll(unsigned int mac, int speed) ++{ ++ struct ar71xx_eth_pll_data *pll_data; ++ u32 pll_val; + -+#include "dev-pb9x-pci.h" ++ switch (mac) { ++ case 0: ++ pll_data = &ar71xx_eth0_pll_data; ++ break; ++ case 1: ++ pll_data = &ar71xx_eth1_pll_data; ++ break; ++ default: ++ BUG(); ++ } + -+static struct ar71xx_pci_irq pb9x_pci_irqs[] __initdata = { -+ { -+ .slot = 0, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV0, ++ switch (speed) { ++ case SPEED_10: ++ pll_val = pll_data->pll_10; ++ break; ++ case SPEED_100: ++ pll_val = pll_data->pll_100; ++ break; ++ case SPEED_1000: ++ pll_val = pll_data->pll_1000; ++ break; ++ default: ++ BUG(); + } -+}; + -+void __init pb9x_pci_init(void) -+{ -+ ar71xx_pci_init(ARRAY_SIZE(pb9x_pci_irqs), pb9x_pci_irqs); ++ return pll_val; +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,22 @@ -+/* -+ * Atheros PB9x reference board PCI initialization -+ * -+ * Copyright (C) 2010 Felix Fietkau -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _AR71XX_DEV_PB9X_PCI_H -+#define _AR71XX_DEV_PB9X_PCI_H + -+#if defined(CONFIG_AR71XX_DEV_PB9X_PCI) -+void pb9x_pci_init(void) __init; -+#else -+static inline void pb9x_pci_init(void) { } -+#endif ++static void ar71xx_set_pll_ge0(int speed) ++{ ++ u32 val = ar71xx_get_eth_pll(0, speed); + -+#endif /* _AR71XX_DEV_PB9X_PCI_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c linux-2.6.39/arch/mips/ar71xx/dev-usb.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-usb.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,181 @@ -+/* -+ * Atheros AR71xx USB host device support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK, ++ val, AR71XX_ETH0_PLL_SHIFT); ++} + -+#include -+#include -+#include -+#include -+#include ++static void ar71xx_set_pll_ge1(int speed) ++{ ++ u32 val = ar71xx_get_eth_pll(1, speed); + -+#include -+#include ++ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK, ++ val, AR71XX_ETH1_PLL_SHIFT); ++} + -+#include "dev-usb.h" ++static void ar724x_set_pll_ge0(int speed) ++{ ++ /* TODO */ ++} + -+/* -+ * OHCI (USB full speed host controller) -+ */ -+static struct resource ar71xx_ohci_resources[] = { -+ [0] = { -+ .start = AR71XX_OHCI_BASE, -+ .end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1, ++static void ar724x_set_pll_ge1(int speed) ++{ ++ /* TODO */ ++} ++ ++static void ar7242_set_pll_ge0(int speed) ++{ ++ u32 val = ar71xx_get_eth_pll(0, speed); ++ ++ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR7242_PLL_REG_ETH0_INT_CLOCK, ++ val, AR71XX_ETH0_PLL_SHIFT); ++} ++ ++static void ar91xx_set_pll_ge0(int speed) ++{ ++ u32 val = ar71xx_get_eth_pll(0, speed); ++ ++ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK, ++ val, AR91XX_ETH0_PLL_SHIFT); ++} ++ ++static void ar91xx_set_pll_ge1(int speed) ++{ ++ u32 val = ar71xx_get_eth_pll(1, speed); ++ ++ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK, ++ val, AR91XX_ETH1_PLL_SHIFT); ++} ++ ++static void ar933x_set_pll_ge0(int speed) ++{ ++ /* TODO */ ++} ++ ++static void ar933x_set_pll_ge1(int speed) ++{ ++ /* TODO */ ++} ++ ++static void ar71xx_ddr_flush_ge0(void) ++{ ++ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0); ++} ++ ++static void ar71xx_ddr_flush_ge1(void) ++{ ++ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1); ++} ++ ++static void ar724x_ddr_flush_ge0(void) ++{ ++ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0); ++} ++ ++static void ar724x_ddr_flush_ge1(void) ++{ ++ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE1); ++} ++ ++static void ar91xx_ddr_flush_ge0(void) ++{ ++ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0); ++} ++ ++static void ar91xx_ddr_flush_ge1(void) ++{ ++ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1); ++} ++ ++static void ar933x_ddr_flush_ge0(void) ++{ ++ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE0); ++} ++ ++static void ar933x_ddr_flush_ge1(void) ++{ ++ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE1); ++} ++ ++static struct resource ar71xx_eth0_resources[] = { ++ { ++ .name = "mac_base", + .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = AR71XX_MISC_IRQ_OHCI, -+ .end = AR71XX_MISC_IRQ_OHCI, ++ .start = AR71XX_GE0_BASE, ++ .end = AR71XX_GE0_BASE + 0x200 - 1, ++ }, { ++ .name = "mii_ctrl", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_MII_BASE + MII_REG_MII0_CTRL, ++ .end = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3, ++ }, { ++ .name = "mac_irq", + .flags = IORESOURCE_IRQ, ++ .start = AR71XX_CPU_IRQ_GE0, ++ .end = AR71XX_CPU_IRQ_GE0, + }, +}; + -+static struct resource ar7240_ohci_resources[] = { -+ [0] = { -+ .start = AR7240_OHCI_BASE, -+ .end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = AR71XX_CPU_IRQ_USB, -+ .end = AR71XX_CPU_IRQ_USB, -+ .flags = IORESOURCE_IRQ, -+ }, ++struct ag71xx_platform_data ar71xx_eth0_data = { ++ .reset_bit = RESET_MODULE_GE0_MAC, +}; + -+static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32); -+static struct platform_device ar71xx_ohci_device = { -+ .name = "ar71xx-ohci", -+ .id = -1, -+ .resource = ar71xx_ohci_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_ohci_resources), ++struct platform_device ar71xx_eth0_device = { ++ .name = "ag71xx", ++ .id = 0, ++ .resource = ar71xx_eth0_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_eth0_resources), + .dev = { -+ .dma_mask = &ar71xx_ohci_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), ++ .platform_data = &ar71xx_eth0_data, + }, +}; + -+/* -+ * EHCI (USB full speed host controller) -+ */ -+static struct resource ar71xx_ehci_resources[] = { -+ [0] = { -+ .start = AR71XX_EHCI_BASE, -+ .end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1, ++static struct resource ar71xx_eth1_resources[] = { ++ { ++ .name = "mac_base", + .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = AR71XX_CPU_IRQ_USB, -+ .end = AR71XX_CPU_IRQ_USB, ++ .start = AR71XX_GE1_BASE, ++ .end = AR71XX_GE1_BASE + 0x200 - 1, ++ }, { ++ .name = "mii_ctrl", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_MII_BASE + MII_REG_MII1_CTRL, ++ .end = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3, ++ }, { ++ .name = "mac_irq", + .flags = IORESOURCE_IRQ, ++ .start = AR71XX_CPU_IRQ_GE1, ++ .end = AR71XX_CPU_IRQ_GE1, + }, +}; + -+static u64 ar71xx_ehci_dmamask = DMA_BIT_MASK(32); -+static struct ar71xx_ehci_platform_data ar71xx_ehci_data; ++struct ag71xx_platform_data ar71xx_eth1_data = { ++ .reset_bit = RESET_MODULE_GE1_MAC, ++}; + -+static struct platform_device ar71xx_ehci_device = { -+ .name = "ar71xx-ehci", -+ .id = -1, -+ .resource = ar71xx_ehci_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_ehci_resources), ++struct platform_device ar71xx_eth1_device = { ++ .name = "ag71xx", ++ .id = 1, ++ .resource = ar71xx_eth1_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_eth1_resources), + .dev = { -+ .dma_mask = &ar71xx_ehci_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), -+ .platform_data = &ar71xx_ehci_data, ++ .platform_data = &ar71xx_eth1_data, + }, +}; + -+#define AR71XX_USB_RESET_MASK \ -+ (RESET_MODULE_USB_HOST | RESET_MODULE_USB_PHY \ -+ | RESET_MODULE_USB_OHCI_DLL) -+ -+#define AR7240_USB_RESET_MASK \ -+ (RESET_MODULE_USB_HOST | RESET_MODULE_USB_OHCI_DLL_7240) -+ -+static void __init ar71xx_usb_setup(void) -+{ -+ ar71xx_device_stop(AR71XX_USB_RESET_MASK); -+ mdelay(1000); -+ ar71xx_device_start(AR71XX_USB_RESET_MASK); ++#define AR71XX_PLL_VAL_1000 0x00110000 ++#define AR71XX_PLL_VAL_100 0x00001099 ++#define AR71XX_PLL_VAL_10 0x00991099 + -+ /* Turning on the Buff and Desc swap bits */ -+ ar71xx_usb_ctrl_wr(USB_CTRL_REG_CONFIG, 0xf0000); ++#define AR724X_PLL_VAL_1000 0x00110000 ++#define AR724X_PLL_VAL_100 0x00001099 ++#define AR724X_PLL_VAL_10 0x00991099 + -+ /* WAR for HW bug. Here it adjusts the duration between two SOFS */ -+ ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x20c00); ++#define AR7242_PLL_VAL_1000 0x1c000000 ++#define AR7242_PLL_VAL_100 0x00000101 ++#define AR7242_PLL_VAL_10 0x00001616 + -+ mdelay(900); ++#define AR91XX_PLL_VAL_1000 0x1a000000 ++#define AR91XX_PLL_VAL_100 0x13000a44 ++#define AR91XX_PLL_VAL_10 0x00441099 + -+ platform_device_register(&ar71xx_ohci_device); -+ platform_device_register(&ar71xx_ehci_device); -+} ++#define AR933X_PLL_VAL_1000 0x00110000 ++#define AR933X_PLL_VAL_100 0x00001099 ++#define AR933X_PLL_VAL_10 0x00991099 + -+static void __init ar7240_usb_setup(void) ++static void __init ar71xx_init_eth_pll_data(unsigned int id) +{ -+ ar71xx_device_stop(AR7240_USB_RESET_MASK); -+ mdelay(1000); -+ ar71xx_device_start(AR7240_USB_RESET_MASK); -+ -+ /* WAR for HW bug. Here it adjusts the duration between two SOFS */ -+ ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x3); ++ struct ar71xx_eth_pll_data *pll_data; ++ u32 pll_10, pll_100, pll_1000; + -+ if (ar71xx_soc == AR71XX_SOC_AR7241 || ar71xx_soc == AR71XX_SOC_AR7242) { -+ ar71xx_ehci_data.is_ar91xx = 1; -+ ar71xx_ehci_device.resource = ar7240_ohci_resources; -+ ar71xx_ehci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources); -+ platform_device_register(&ar71xx_ehci_device); -+ } else { -+ ar71xx_ohci_device.resource = ar7240_ohci_resources; -+ ar71xx_ohci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources); -+ platform_device_register(&ar71xx_ohci_device); ++ switch (id) { ++ case 0: ++ pll_data = &ar71xx_eth0_pll_data; ++ break; ++ case 1: ++ pll_data = &ar71xx_eth1_pll_data; ++ break; ++ default: ++ BUG(); + } -+} -+ -+static void __init ar91xx_usb_setup(void) -+{ -+ ar71xx_device_stop(RESET_MODULE_USBSUS_OVERRIDE); -+ mdelay(10); + -+ ar71xx_device_start(RESET_MODULE_USB_HOST); -+ mdelay(10); -+ -+ ar71xx_device_start(RESET_MODULE_USB_PHY); -+ mdelay(10); -+ -+ ar71xx_ehci_data.is_ar91xx = 1; -+ platform_device_register(&ar71xx_ehci_device); -+} -+ -+void __init ar71xx_add_device_usb(void) -+{ + switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ pll_10 = AR71XX_PLL_VAL_10; ++ pll_100 = AR71XX_PLL_VAL_100; ++ pll_1000 = AR71XX_PLL_VAL_1000; ++ break; ++ + case AR71XX_SOC_AR7240: + case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ ar7240_usb_setup(); ++ pll_10 = AR724X_PLL_VAL_10; ++ pll_100 = AR724X_PLL_VAL_100; ++ pll_1000 = AR724X_PLL_VAL_1000; + break; + -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ ar71xx_usb_setup(); ++ case AR71XX_SOC_AR7242: ++ pll_10 = AR7242_PLL_VAL_10; ++ pll_100 = AR7242_PLL_VAL_100; ++ pll_1000 = AR7242_PLL_VAL_1000; + break; + + case AR71XX_SOC_AR9130: + case AR71XX_SOC_AR9132: -+ ar91xx_usb_setup(); -+ break; ++ pll_10 = AR91XX_PLL_VAL_10; ++ pll_100 = AR91XX_PLL_VAL_100; ++ pll_1000 = AR91XX_PLL_VAL_1000; ++ break; ++ ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ pll_10 = AR933X_PLL_VAL_10; ++ pll_100 = AR933X_PLL_VAL_100; ++ pll_1000 = AR933X_PLL_VAL_1000; ++ break; + + default: + BUG(); + } -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.h linux-2.6.39/arch/mips/ar71xx/dev-usb.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-usb.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,17 @@ -+/* -+ * Atheros AR71xx USB host device support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _AR71XX_DEV_USB_H -+#define _AR71XX_DEV_USB_H -+ -+void ar71xx_add_device_usb(void) __init; -+ -+#endif /* _AR71XX_DEV_USB_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.c linux-2.6.39/arch/mips/ar71xx/devices.c ---- linux-2.6.39.orig/arch/mips/ar71xx/devices.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/devices.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,575 @@ -+/* -+ * Atheros AR71xx SoC platform devices -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include + -+#include -+ -+#include "devices.h" -+ -+static u8 ar71xx_mac_base[ETH_ALEN] __initdata; -+ -+static struct resource ar71xx_uart_resources[] = { -+ { -+ .start = AR71XX_UART_BASE, -+ .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) -+static struct plat_serial8250_port ar71xx_uart_data[] = { -+ { -+ .mapbase = AR71XX_UART_BASE, -+ .irq = AR71XX_MISC_IRQ_UART, -+ .flags = AR71XX_UART_FLAGS, -+ .iotype = UPIO_MEM32, -+ .regshift = 2, -+ }, { -+ /* terminating entry */ -+ } -+}; ++ if (!pll_data->pll_10) ++ pll_data->pll_10 = pll_10; + -+static struct platform_device ar71xx_uart_device = { -+ .name = "serial8250", -+ .id = PLAT8250_DEV_PLATFORM, -+ .resource = ar71xx_uart_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_uart_resources), -+ .dev = { -+ .platform_data = ar71xx_uart_data -+ }, -+}; ++ if (!pll_data->pll_100) ++ pll_data->pll_100 = pll_100; + -+void __init ar71xx_add_device_uart(void) -+{ -+ ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq; -+ platform_device_register(&ar71xx_uart_device); ++ if (!pll_data->pll_1000) ++ pll_data->pll_1000 = pll_1000; +} + -+static struct resource ar71xx_mdio_resources[] = { -+ { -+ .name = "mdio_base", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_GE0_BASE, -+ .end = AR71XX_GE0_BASE + 0x200 - 1, -+ } -+}; -+ -+static struct ag71xx_mdio_platform_data ar71xx_mdio_data; ++static int ar71xx_eth_instance __initdata; ++void __init ar71xx_add_device_eth(unsigned int id) ++{ ++ struct platform_device *pdev; ++ struct ag71xx_platform_data *pdata; + -+struct platform_device ar71xx_mdio_device = { -+ .name = "ag71xx-mdio", -+ .id = -1, -+ .resource = ar71xx_mdio_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_mdio_resources), -+ .dev = { -+ .platform_data = &ar71xx_mdio_data, -+ }, -+}; ++ ar71xx_init_eth_pll_data(id); + -+void __init ar71xx_add_device_mdio(u32 phy_mask) -+{ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ ar71xx_mdio_data.is_ar7240 = 1; ++ switch (id) { ++ case 0: ++ switch (ar71xx_eth0_data.phy_if_mode) { ++ case PHY_INTERFACE_MODE_MII: ++ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII; ++ break; ++ case PHY_INTERFACE_MODE_GMII: ++ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII; ++ break; ++ case PHY_INTERFACE_MODE_RMII: ++ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII; ++ break; ++ default: ++ printk(KERN_ERR "ar71xx: invalid PHY interface mode " ++ "for eth0\n"); ++ return; ++ } ++ pdev = &ar71xx_eth0_device; + break; -+ default: ++ case 1: ++ switch (ar71xx_eth1_data.phy_if_mode) { ++ case PHY_INTERFACE_MODE_RMII: ++ ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII; ++ break; ++ default: ++ printk(KERN_ERR "ar71xx: invalid PHY interface mode " ++ "for eth1\n"); ++ return; ++ } ++ pdev = &ar71xx_eth1_device; + break; ++ default: ++ printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id); ++ return; + } + -+ ar71xx_mdio_data.phy_mask = phy_mask; -+ -+ platform_device_register(&ar71xx_mdio_device); -+} -+ -+static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); ++ pdata = pdev->dev.platform_data; + -+ t = __raw_readl(base + cfg_reg); -+ t &= ~(3 << shift); -+ t |= (2 << shift); -+ __raw_writel(t, base + cfg_reg); -+ udelay(100); ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1 ++ : ar71xx_ddr_flush_ge0; ++ pdata->set_pll = id ? ar71xx_set_pll_ge1 ++ : ar71xx_set_pll_ge0; ++ break; + -+ __raw_writel(pll_val, base + pll_reg); ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1 ++ : ar71xx_ddr_flush_ge0; ++ pdata->set_pll = id ? ar71xx_set_pll_ge1 ++ : ar71xx_set_pll_ge0; ++ pdata->has_gbit = 1; ++ break; + -+ t |= (3 << shift); -+ __raw_writel(t, base + cfg_reg); -+ udelay(100); ++ case AR71XX_SOC_AR7242: ++ ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO | ++ RESET_MODULE_GE0_PHY; ++ ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO | ++ RESET_MODULE_GE1_PHY; ++ pdata->ddr_flush = id ? ar724x_ddr_flush_ge1 ++ : ar724x_ddr_flush_ge0; ++ pdata->set_pll = id ? ar724x_set_pll_ge1 ++ : ar7242_set_pll_ge0; ++ pdata->has_gbit = 1; ++ pdata->is_ar724x = 1; + -+ t &= ~(3 << shift); -+ __raw_writel(t, base + cfg_reg); -+ udelay(100); ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; ++ break; + -+ printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n", -+ (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg)); ++ case AR71XX_SOC_AR7241: ++ ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO; ++ ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO; ++ /* fall through */ ++ case AR71XX_SOC_AR7240: ++ ar71xx_eth0_data.reset_bit |= RESET_MODULE_GE0_PHY; ++ ar71xx_eth1_data.reset_bit |= RESET_MODULE_GE1_PHY; ++ pdata->ddr_flush = id ? ar724x_ddr_flush_ge1 ++ : ar724x_ddr_flush_ge0; ++ pdata->set_pll = id ? ar724x_set_pll_ge1 ++ : ar724x_set_pll_ge0; ++ pdata->is_ar724x = 1; ++ if (ar71xx_soc == AR71XX_SOC_AR7240) ++ pdata->is_ar7240 = 1; ++ ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; ++ break; + -+ iounmap(base); -+} ++ case AR71XX_SOC_AR9130: ++ pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1 ++ : ar91xx_ddr_flush_ge0; ++ pdata->set_pll = id ? ar91xx_set_pll_ge1 ++ : ar91xx_set_pll_ge0; ++ pdata->is_ar91xx = 1; ++ break; + -+struct ar71xx_eth_pll_data ar71xx_eth0_pll_data; -+struct ar71xx_eth_pll_data ar71xx_eth1_pll_data; ++ case AR71XX_SOC_AR9132: ++ pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1 ++ : ar91xx_ddr_flush_ge0; ++ pdata->set_pll = id ? ar91xx_set_pll_ge1 ++ : ar91xx_set_pll_ge0; ++ pdata->is_ar91xx = 1; ++ pdata->has_gbit = 1; ++ break; + -+static u32 ar71xx_get_eth_pll(unsigned int mac, int speed) -+{ -+ struct ar71xx_eth_pll_data *pll_data; -+ u32 pll_val; ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ ar71xx_eth0_data.reset_bit = AR933X_RESET_GE0_MAC | ++ AR933X_RESET_GE0_MDIO; ++ ar71xx_eth1_data.reset_bit = AR933X_RESET_GE1_MAC | ++ AR933X_RESET_GE1_MDIO; ++ pdata->ddr_flush = id ? ar933x_ddr_flush_ge1 ++ : ar933x_ddr_flush_ge0; ++ pdata->set_pll = id ? ar933x_set_pll_ge1 ++ : ar933x_set_pll_ge0; ++ pdata->has_gbit = 1; ++ pdata->is_ar724x = 1; + -+ switch (mac) { -+ case 0: -+ pll_data = &ar71xx_eth0_pll_data; -+ break; -+ case 1: -+ pll_data = &ar71xx_eth1_pll_data; ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; + break; ++ + default: + BUG(); + } + -+ switch (speed) { -+ case SPEED_10: -+ pll_val = pll_data->pll_10; -+ break; -+ case SPEED_100: -+ pll_val = pll_data->pll_100; -+ break; -+ case SPEED_1000: -+ pll_val = pll_data->pll_1000; -+ break; ++ switch (pdata->phy_if_mode) { ++ case PHY_INTERFACE_MODE_GMII: ++ case PHY_INTERFACE_MODE_RGMII: ++ if (!pdata->has_gbit) { ++ printk(KERN_ERR "ar71xx: no gbit available on eth%d\n", ++ id); ++ return; ++ } ++ /* fallthrough */ + default: -+ BUG(); ++ break; + } + -+ return pll_val; -+} ++ if (!is_valid_ether_addr(pdata->mac_addr)) { ++ random_ether_addr(pdata->mac_addr); ++ printk(KERN_DEBUG ++ "ar71xx: using random MAC address for eth%d\n", ++ ar71xx_eth_instance); ++ } + -+static void ar71xx_set_pll_ge0(int speed) -+{ -+ u32 val = ar71xx_get_eth_pll(0, speed); ++ if (pdata->mii_bus_dev == NULL) ++ pdata->mii_bus_dev = &ar71xx_mdio_device.dev; + -+ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK, -+ val, AR71XX_ETH0_PLL_SHIFT); -+} ++ /* Reset the device */ ++ ar71xx_device_stop(pdata->reset_bit); ++ mdelay(100); + -+static void ar71xx_set_pll_ge1(int speed) -+{ -+ u32 val = ar71xx_get_eth_pll(1, speed); ++ ar71xx_device_start(pdata->reset_bit); ++ mdelay(100); + -+ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK, -+ val, AR71XX_ETH1_PLL_SHIFT); ++ platform_device_register(pdev); ++ ar71xx_eth_instance++; +} + -+static void ar724x_set_pll_ge0(int speed) ++static struct resource ar71xx_spi_resources[] = { ++ [0] = { ++ .start = AR71XX_SPI_BASE, ++ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static struct platform_device ar71xx_spi_device = { ++ .name = "ar71xx-spi", ++ .id = -1, ++ .resource = ar71xx_spi_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_spi_resources), ++}; ++ ++void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata, ++ struct spi_board_info const *info, ++ unsigned n) +{ -+ /* TODO */ ++ spi_register_board_info(info, n); ++ ar71xx_spi_device.dev.platform_data = pdata; ++ platform_device_register(&ar71xx_spi_device); +} + -+static void ar724x_set_pll_ge1(int speed) ++void __init ar71xx_add_device_wdt(void) +{ -+ /* TODO */ ++ platform_device_register_simple("ar71xx-wdt", -1, NULL, 0); +} + -+static void ar91xx_set_pll_ge0(int speed) ++void __init ar71xx_set_mac_base(unsigned char *mac) +{ -+ u32 val = ar71xx_get_eth_pll(0, speed); -+ -+ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK, -+ val, AR91XX_ETH0_PLL_SHIFT); ++ memcpy(ar71xx_mac_base, mac, ETH_ALEN); +} + -+static void ar91xx_set_pll_ge1(int speed) ++void __init ar71xx_parse_mac_addr(char *mac_str) +{ -+ u32 val = ar71xx_get_eth_pll(1, speed); ++ u8 tmp[ETH_ALEN]; ++ int t; + -+ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK, -+ val, AR91XX_ETH1_PLL_SHIFT); -+} ++ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", ++ &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); + -+static void ar71xx_ddr_flush_ge0(void) -+{ -+ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0); -+} ++ if (t != ETH_ALEN) ++ t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx", ++ &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); + -+static void ar71xx_ddr_flush_ge1(void) -+{ -+ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1); ++ if (t == ETH_ALEN) ++ ar71xx_set_mac_base(tmp); ++ else ++ printk(KERN_DEBUG "ar71xx: failed to parse mac address " ++ "\"%s\"\n", mac_str); +} + -+static void ar724x_ddr_flush_ge0(void) ++static int __init ar71xx_ethaddr_setup(char *str) +{ -+ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0); ++ ar71xx_parse_mac_addr(str); ++ return 1; +} ++__setup("ethaddr=", ar71xx_ethaddr_setup); + -+static void ar724x_ddr_flush_ge1(void) ++static int __init ar71xx_kmac_setup(char *str) +{ -+ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE1); ++ ar71xx_parse_mac_addr(str); ++ return 1; +} ++__setup("kmac=", ar71xx_kmac_setup); + -+static void ar91xx_ddr_flush_ge0(void) ++void __init ar71xx_init_mac(unsigned char *dst, const unsigned char *src, ++ unsigned offset) +{ -+ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0); -+} ++ u32 t; + -+static void ar91xx_ddr_flush_ge1(void) -+{ -+ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1); ++ if (!is_valid_ether_addr(src)) { ++ memset(dst, '\0', ETH_ALEN); ++ return; ++ } ++ ++ t = (((u32) src[3]) << 16) + (((u32) src[4]) << 8) + ((u32) src[5]); ++ t += offset; ++ ++ dst[0] = src[0]; ++ dst[1] = src[1]; ++ dst[2] = src[2]; ++ dst[3] = (t >> 16) & 0xff; ++ dst[4] = (t >> 8) & 0xff; ++ dst[5] = t & 0xff; +} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.h linux-2.6.39/arch/mips/ar71xx/devices.h +--- linux-2.6.39.orig/arch/mips/ar71xx/devices.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/devices.h 2011-08-24 02:41:55.347990727 +0200 +@@ -0,0 +1,50 @@ ++/* ++ * Atheros AR71xx SoC device definitions ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+static struct resource ar71xx_eth0_resources[] = { -+ { -+ .name = "mac_base", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_GE0_BASE, -+ .end = AR71XX_GE0_BASE + 0x200 - 1, -+ }, { -+ .name = "mii_ctrl", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_MII_BASE + MII_REG_MII0_CTRL, -+ .end = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3, -+ }, { -+ .name = "mac_irq", -+ .flags = IORESOURCE_IRQ, -+ .start = AR71XX_CPU_IRQ_GE0, -+ .end = AR71XX_CPU_IRQ_GE0, -+ }, -+}; ++#ifndef __AR71XX_DEVICES_H ++#define __AR71XX_DEVICES_H + -+struct ag71xx_platform_data ar71xx_eth0_data = { -+ .reset_bit = RESET_MODULE_GE0_MAC, -+}; ++#include + -+struct platform_device ar71xx_eth0_device = { -+ .name = "ag71xx", -+ .id = 0, -+ .resource = ar71xx_eth0_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_eth0_resources), -+ .dev = { -+ .platform_data = &ar71xx_eth0_data, -+ }, -+}; ++struct platform_device; + -+static struct resource ar71xx_eth1_resources[] = { -+ { -+ .name = "mac_base", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_GE1_BASE, -+ .end = AR71XX_GE1_BASE + 0x200 - 1, -+ }, { -+ .name = "mii_ctrl", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_MII_BASE + MII_REG_MII1_CTRL, -+ .end = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3, -+ }, { -+ .name = "mac_irq", -+ .flags = IORESOURCE_IRQ, -+ .start = AR71XX_CPU_IRQ_GE1, -+ .end = AR71XX_CPU_IRQ_GE1, -+ }, -+}; ++void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata, ++ struct spi_board_info const *info, ++ unsigned n) __init; + -+struct ag71xx_platform_data ar71xx_eth1_data = { -+ .reset_bit = RESET_MODULE_GE1_MAC, -+}; ++extern unsigned char ar71xx_mac_base[] __initdata; ++void ar71xx_parse_mac_addr(char *mac_str) __init; ++void ar71xx_init_mac(unsigned char *dst, const unsigned char *src, ++ unsigned offset) __init; + -+struct platform_device ar71xx_eth1_device = { -+ .name = "ag71xx", -+ .id = 1, -+ .resource = ar71xx_eth1_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_eth1_resources), -+ .dev = { -+ .platform_data = &ar71xx_eth1_data, -+ }, ++struct ar71xx_eth_pll_data { ++ u32 pll_10; ++ u32 pll_100; ++ u32 pll_1000; +}; + -+#define AR71XX_PLL_VAL_1000 0x00110000 -+#define AR71XX_PLL_VAL_100 0x00001099 -+#define AR71XX_PLL_VAL_10 0x00991099 -+ -+#define AR724X_PLL_VAL_1000 0x00110000 -+#define AR724X_PLL_VAL_100 0x00001099 -+#define AR724X_PLL_VAL_10 0x00991099 ++extern struct ar71xx_eth_pll_data ar71xx_eth0_pll_data; ++extern struct ar71xx_eth_pll_data ar71xx_eth1_pll_data; + -+#define AR91XX_PLL_VAL_1000 0x1a000000 -+#define AR91XX_PLL_VAL_100 0x13000a44 -+#define AR91XX_PLL_VAL_10 0x00441099 ++extern struct ag71xx_platform_data ar71xx_eth0_data; ++extern struct ag71xx_platform_data ar71xx_eth1_data; ++extern struct platform_device ar71xx_eth0_device; ++extern struct platform_device ar71xx_eth1_device; ++void ar71xx_add_device_eth(unsigned int id) __init; + -+static void __init ar71xx_init_eth_pll_data(unsigned int id) -+{ -+ struct ar71xx_eth_pll_data *pll_data; -+ u32 pll_10, pll_100, pll_1000; ++extern struct platform_device ar71xx_mdio_device; ++void ar71xx_add_device_mdio(u32 phy_mask) __init; + -+ switch (id) { -+ case 0: -+ pll_data = &ar71xx_eth0_pll_data; -+ break; -+ case 1: -+ pll_data = &ar71xx_eth1_pll_data; -+ break; -+ default: -+ BUG(); -+ } ++void ar71xx_add_device_uart(void) __init; + -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ pll_10 = AR71XX_PLL_VAL_10; -+ pll_100 = AR71XX_PLL_VAL_100; -+ pll_1000 = AR71XX_PLL_VAL_1000; -+ break; ++void ar71xx_add_device_wdt(void) __init; + -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ pll_10 = AR724X_PLL_VAL_10; -+ pll_100 = AR724X_PLL_VAL_100; -+ pll_1000 = AR724X_PLL_VAL_1000; -+ break; -+ -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ pll_10 = AR91XX_PLL_VAL_10; -+ pll_100 = AR91XX_PLL_VAL_100; -+ pll_1000 = AR91XX_PLL_VAL_1000; -+ break; -+ default: -+ BUG(); -+ } -+ -+ if (!pll_data->pll_10) -+ pll_data->pll_10 = pll_10; ++#endif /* __AR71XX_DEVICES_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c 2011-08-24 02:41:55.347990727 +0200 +@@ -0,0 +1,57 @@ ++/* ++ * Atheros AR71xx GPIO LED device support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ if (!pll_data->pll_100) -+ pll_data->pll_100 = pll_100; ++#include ++#include ++#include + -+ if (!pll_data->pll_1000) -+ pll_data->pll_1000 = pll_1000; -+} ++#include "dev-leds-gpio.h" + -+static int ar71xx_eth_instance __initdata; -+void __init ar71xx_add_device_eth(unsigned int id) ++void __init ar71xx_add_device_leds_gpio(int id, unsigned num_leds, ++ struct gpio_led *leds) +{ + struct platform_device *pdev; -+ struct ag71xx_platform_data *pdata; -+ -+ ar71xx_init_eth_pll_data(id); ++ struct gpio_led_platform_data pdata; ++ struct gpio_led *p; ++ int err; + -+ switch (id) { -+ case 0: -+ switch (ar71xx_eth0_data.phy_if_mode) { -+ case PHY_INTERFACE_MODE_MII: -+ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII; -+ break; -+ case PHY_INTERFACE_MODE_GMII: -+ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII; -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII; -+ break; -+ case PHY_INTERFACE_MODE_RMII: -+ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII; -+ break; -+ default: -+ printk(KERN_ERR "ar71xx: invalid PHY interface mode " -+ "for eth0\n"); -+ return; -+ } -+ pdev = &ar71xx_eth0_device; -+ break; -+ case 1: -+ switch (ar71xx_eth1_data.phy_if_mode) { -+ case PHY_INTERFACE_MODE_RMII: -+ ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII; -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII; -+ break; -+ default: -+ printk(KERN_ERR "ar71xx: invalid PHY interface mode " -+ "for eth1\n"); -+ return; -+ } -+ pdev = &ar71xx_eth1_device; -+ break; -+ default: -+ printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id); ++ p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL); ++ if (!p) + return; -+ } + -+ pdata = pdev->dev.platform_data; ++ memcpy(p, leds, num_leds * sizeof(*p)); + -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1 -+ : ar71xx_ddr_flush_ge0; -+ pdata->set_pll = id ? ar71xx_set_pll_ge1 -+ : ar71xx_set_pll_ge0; -+ break; ++ pdev = platform_device_alloc("leds-gpio", id); ++ if (!pdev) ++ goto err_free_leds; + -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1 -+ : ar71xx_ddr_flush_ge0; -+ pdata->set_pll = id ? ar71xx_set_pll_ge1 -+ : ar71xx_set_pll_ge0; -+ pdata->has_gbit = 1; -+ break; ++ memset(&pdata, 0, sizeof(pdata)); ++ pdata.num_leds = num_leds; ++ pdata.leds = p; + -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO; -+ ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO; -+ /* fall through */ -+ case AR71XX_SOC_AR7240: -+ pdata->ddr_flush = id ? ar724x_ddr_flush_ge1 -+ : ar724x_ddr_flush_ge0; -+ pdata->set_pll = id ? ar724x_set_pll_ge1 -+ : ar724x_set_pll_ge0; -+ pdata->is_ar724x = 1; -+ break; ++ err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); ++ if (err) ++ goto err_put_pdev; + -+ case AR71XX_SOC_AR9130: -+ pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1 -+ : ar91xx_ddr_flush_ge0; -+ pdata->set_pll = id ? ar91xx_set_pll_ge1 -+ : ar91xx_set_pll_ge0; -+ pdata->is_ar91xx = 1; -+ break; ++ err = platform_device_add(pdev); ++ if (err) ++ goto err_put_pdev; + -+ case AR71XX_SOC_AR9132: -+ pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1 -+ : ar91xx_ddr_flush_ge0; -+ pdata->set_pll = id ? ar91xx_set_pll_ge1 -+ : ar91xx_set_pll_ge0; -+ pdata->is_ar91xx = 1; -+ pdata->has_gbit = 1; -+ break; ++ return; + -+ default: -+ BUG(); -+ } ++err_put_pdev: ++ platform_device_put(pdev); + -+ switch (pdata->phy_if_mode) { -+ case PHY_INTERFACE_MODE_GMII: -+ case PHY_INTERFACE_MODE_RGMII: -+ if (!pdata->has_gbit) { -+ printk(KERN_ERR "ar71xx: no gbit available on eth%d\n", -+ id); -+ return; -+ } -+ /* fallthrough */ -+ default: -+ break; -+ } ++err_free_leds: ++ kfree(p); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h 2011-08-24 02:41:55.367990903 +0200 +@@ -0,0 +1,21 @@ ++/* ++ * Atheros AR71xx GPIO LED device support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ if (is_valid_ether_addr(ar71xx_mac_base)) { -+ memcpy(pdata->mac_addr, ar71xx_mac_base, ETH_ALEN); -+ pdata->mac_addr[5] += ar71xx_eth_instance; -+ } else { -+ random_ether_addr(pdata->mac_addr); -+ printk(KERN_DEBUG -+ "ar71xx: using random MAC address for eth%d\n", -+ ar71xx_eth_instance); -+ } ++#ifndef _AR71XX_DEV_LEDS_GPIO_H ++#define _AR71XX_DEV_LEDS_GPIO_H + -+ if (pdata->mii_bus_dev == NULL) -+ pdata->mii_bus_dev = &ar71xx_mdio_device.dev; ++#include + -+ /* Reset the device */ -+ ar71xx_device_stop(pdata->reset_bit); -+ mdelay(100); ++void ar71xx_add_device_leds_gpio(int id, ++ unsigned num_leds, ++ struct gpio_led *leds) __init; + -+ ar71xx_device_start(pdata->reset_bit); -+ mdelay(100); ++#endif /* _AR71XX_DEV_LEDS_GPIO_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c 2011-08-24 02:41:55.367990903 +0200 +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ platform_device_register(pdev); -+ ar71xx_eth_instance++; -+} ++#include ++#include ++#include + -+static struct resource ar71xx_spi_resources[] = { -+ [0] = { -+ .start = AR71XX_SPI_BASE, -+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; ++#include "devices.h" ++#include "dev-m25p80.h" + -+static struct platform_device ar71xx_spi_device = { -+ .name = "ar71xx-spi", -+ .id = -1, -+ .resource = ar71xx_spi_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_spi_resources), ++static struct spi_board_info ar71xx_spi_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "m25p80", ++ } +}; + -+void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata, -+ struct spi_board_info const *info, -+ unsigned n) ++void __init ar71xx_add_device_m25p80(struct flash_platform_data *pdata) +{ -+ spi_register_board_info(info, n); -+ ar71xx_spi_device.dev.platform_data = pdata; -+ platform_device_register(&ar71xx_spi_device); ++ ar71xx_spi_info[0].platform_data = pdata; ++ ar71xx_add_device_spi(NULL, ar71xx_spi_info, ++ ARRAY_SIZE(ar71xx_spi_info)); +} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h 2011-08-24 02:41:55.377990515 +0200 +@@ -0,0 +1,16 @@ ++/* ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+void __init ar71xx_add_device_wdt(void) -+{ -+ platform_device_register_simple("ar71xx-wdt", -1, NULL, 0); -+} -+ -+void __init ar71xx_set_mac_base(unsigned char *mac) -+{ -+ memcpy(ar71xx_mac_base, mac, ETH_ALEN); -+} -+ -+void __init ar71xx_parse_mac_addr(char *mac_str) -+{ -+ u8 tmp[ETH_ALEN]; -+ int t; -+ -+ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", -+ &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); -+ -+ if (t != ETH_ALEN) -+ t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx", -+ &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); ++#ifndef _AR71XX_DEV_M25P80_H ++#define _AR71XX_DEV_M25P80_H + -+ if (t == ETH_ALEN) -+ ar71xx_set_mac_base(tmp); -+ else -+ printk(KERN_DEBUG "ar71xx: failed to parse mac address " -+ "\"%s\"\n", mac_str); -+} ++#include + -+static int __init ar71xx_ethaddr_setup(char *str) -+{ -+ ar71xx_parse_mac_addr(str); -+ return 1; -+} -+__setup("ethaddr=", ar71xx_ethaddr_setup); ++void ar71xx_add_device_m25p80(struct flash_platform_data *pdata) __init; + -+static int __init ar71xx_kmac_setup(char *str) -+{ -+ ar71xx_parse_mac_addr(str); -+ return 1; -+} -+__setup("kmac=", ar71xx_kmac_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.h linux-2.6.39/arch/mips/ar71xx/devices.h ---- linux-2.6.39.orig/arch/mips/ar71xx/devices.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/devices.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,48 @@ ++#endif /* _AR71XX_DEV_M25P80_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c 2011-08-24 02:41:55.377990515 +0200 +@@ -0,0 +1,40 @@ +/* -+ * Atheros AR71xx SoC device definitions ++ * Atheros PB42 reference board PCI initialization + * + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#ifndef __AR71XX_DEVICES_H -+#define __AR71XX_DEVICES_H -+ -+#include -+ -+struct platform_device; ++#include + -+void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata, -+ struct spi_board_info const *info, -+ unsigned n) __init; ++#include ++#include + -+void ar71xx_set_mac_base(unsigned char *mac) __init; -+void ar71xx_parse_mac_addr(char *mac_str) __init; ++#include "dev-pb42-pci.h" + -+struct ar71xx_eth_pll_data { -+ u32 pll_10; -+ u32 pll_100; -+ u32 pll_1000; ++static struct ar71xx_pci_irq pb42_pci_irqs[] __initdata = { ++ { ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, ++ }, { ++ .slot = 1, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV1, ++ }, { ++ .slot = 2, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV2, ++ } +}; + -+extern struct ar71xx_eth_pll_data ar71xx_eth0_pll_data; -+extern struct ar71xx_eth_pll_data ar71xx_eth1_pll_data; -+ -+extern struct ag71xx_platform_data ar71xx_eth0_data; -+extern struct ag71xx_platform_data ar71xx_eth1_data; -+extern struct platform_device ar71xx_eth0_device; -+extern struct platform_device ar71xx_eth1_device; -+void ar71xx_add_device_eth(unsigned int id) __init; -+ -+extern struct platform_device ar71xx_mdio_device; -+void ar71xx_add_device_mdio(u32 phy_mask) __init; ++void __init pb42_pci_init(void) ++{ ++ ar71xx_pci_init(ARRAY_SIZE(pb42_pci_irqs), pb42_pci_irqs); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h 2011-08-24 02:41:55.387991243 +0200 +@@ -0,0 +1,21 @@ ++/* ++ * Atheros PB42 reference board PCI initialization ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+void ar71xx_add_device_uart(void) __init; ++#ifndef _AR71XX_DEV_PB42_PCI_H ++#define _AR71XX_DEV_PB42_PCI_H + -+void ar71xx_add_device_wdt(void) __init; ++#if defined(CONFIG_AR71XX_DEV_PB42_PCI) ++void pb42_pci_init(void) __init; ++#else ++static inline void pb42_pci_init(void) { } ++#endif + -+#endif /* __AR71XX_DEVICES_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c linux-2.6.39/arch/mips/ar71xx/early_printk.c ---- linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/early_printk.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,30 @@ ++#endif /* _AR71XX_DEV_PB42_PCI_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c 2011-08-24 02:41:55.387991243 +0200 +@@ -0,0 +1,33 @@ +/* -+ * Atheros AR71xx SoC early printk support ++ * Atheros PB9x reference board PCI initialization + * ++ * Copyright (C) 2010 Felix Fietkau + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include ++#include + +#include ++#include + -+#define UART_READ(r) \ -+ __raw_readl((void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4 * (r))) ++#include "dev-pb9x-pci.h" + -+#define UART_WRITE(r, v) \ -+ __raw_writel((v), (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4*(r))) ++static struct ar71xx_pci_irq pb9x_pci_irqs[] __initdata = { ++ { ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, ++ } ++}; + -+void prom_putchar(unsigned char ch) ++void __init pb9x_pci_init(void) +{ -+ while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0); -+ UART_WRITE(UART_TX, ch); -+ while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0); ++ ar71xx_pci_init(ARRAY_SIZE(pb9x_pci_irqs), pb9x_pci_irqs); +} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h 2011-08-24 02:41:55.387991243 +0200 +@@ -0,0 +1,22 @@ ++/* ++ * Atheros PB9x reference board PCI initialization ++ * ++ * Copyright (C) 2010 Felix Fietkau ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/gpio.c linux-2.6.39/arch/mips/ar71xx/gpio.c ---- linux-2.6.39.orig/arch/mips/ar71xx/gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/gpio.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,182 @@ ++#ifndef _AR71XX_DEV_PB9X_PCI_H ++#define _AR71XX_DEV_PB9X_PCI_H ++ ++#if defined(CONFIG_AR71XX_DEV_PB9X_PCI) ++void pb9x_pci_init(void) __init; ++#else ++static inline void pb9x_pci_init(void) { } ++#endif ++ ++#endif /* _AR71XX_DEV_PB9X_PCI_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c linux-2.6.39/arch/mips/ar71xx/dev-usb.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-usb.c 2011-08-24 02:41:55.417990329 +0200 +@@ -0,0 +1,199 @@ +/* -+ * Atheros AR71xx SoC GPIO API support ++ * Atheros AR71xx USB host device support + * -+ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. @@ -2420,36 +2008,358 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/gpio.c linux-2.6.39/arch/mips/ar71x + +#include +#include -+#include -+#include -+#include -+#include -+#include -+#include ++#include ++#include ++#include + +#include ++#include + -+static DEFINE_SPINLOCK(ar71xx_gpio_lock); ++#include "dev-usb.h" + -+unsigned long ar71xx_gpio_count; -+EXPORT_SYMBOL(ar71xx_gpio_count); ++/* ++ * OHCI (USB full speed host controller) ++ */ ++static struct resource ar71xx_ohci_resources[] = { ++ [0] = { ++ .start = AR71XX_OHCI_BASE, ++ .end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = AR71XX_MISC_IRQ_OHCI, ++ .end = AR71XX_MISC_IRQ_OHCI, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; + -+void __ar71xx_gpio_set_value(unsigned gpio, int value) -+{ -+ void __iomem *base = ar71xx_gpio_base; ++static struct resource ar7240_ohci_resources[] = { ++ [0] = { ++ .start = AR7240_OHCI_BASE, ++ .end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = AR71XX_CPU_IRQ_USB, ++ .end = AR71XX_CPU_IRQ_USB, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; + -+ if (value) -+ __raw_writel(1 << gpio, base + GPIO_REG_SET); -+ else -+ __raw_writel(1 << gpio, base + GPIO_REG_CLEAR); -+} -+EXPORT_SYMBOL(__ar71xx_gpio_set_value); ++static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32); ++static struct platform_device ar71xx_ohci_device = { ++ .name = "ar71xx-ohci", ++ .id = -1, ++ .resource = ar71xx_ohci_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_ohci_resources), ++ .dev = { ++ .dma_mask = &ar71xx_ohci_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(32), ++ }, ++}; + -+int __ar71xx_gpio_get_value(unsigned gpio) -+{ -+ return (__raw_readl(ar71xx_gpio_base + GPIO_REG_IN) >> gpio) & 1; -+} -+EXPORT_SYMBOL(__ar71xx_gpio_get_value); ++/* ++ * EHCI (USB high/full speed host controller) ++ */ ++static struct resource ar71xx_ehci_resources[] = { ++ [0] = { ++ .start = AR71XX_EHCI_BASE, ++ .end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = AR71XX_CPU_IRQ_USB, ++ .end = AR71XX_CPU_IRQ_USB, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 ar71xx_ehci_dmamask = DMA_BIT_MASK(32); ++static struct ar71xx_ehci_platform_data ar71xx_ehci_data; ++ ++static struct platform_device ar71xx_ehci_device = { ++ .name = "ar71xx-ehci", ++ .id = -1, ++ .resource = ar71xx_ehci_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_ehci_resources), ++ .dev = { ++ .dma_mask = &ar71xx_ehci_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(32), ++ .platform_data = &ar71xx_ehci_data, ++ }, ++}; ++ ++#define AR71XX_USB_RESET_MASK \ ++ (RESET_MODULE_USB_HOST | RESET_MODULE_USB_PHY \ ++ | RESET_MODULE_USB_OHCI_DLL) ++ ++#define AR7240_USB_RESET_MASK \ ++ (RESET_MODULE_USB_HOST | RESET_MODULE_USB_OHCI_DLL_7240) ++ ++static void __init ar71xx_usb_setup(void) ++{ ++ ar71xx_device_stop(AR71XX_USB_RESET_MASK); ++ mdelay(1000); ++ ar71xx_device_start(AR71XX_USB_RESET_MASK); ++ ++ /* Turning on the Buff and Desc swap bits */ ++ ar71xx_usb_ctrl_wr(USB_CTRL_REG_CONFIG, 0xf0000); ++ ++ /* WAR for HW bug. Here it adjusts the duration between two SOFS */ ++ ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x20c00); ++ ++ mdelay(900); ++ ++ platform_device_register(&ar71xx_ohci_device); ++ platform_device_register(&ar71xx_ehci_device); ++} ++ ++static void __init ar7240_usb_setup(void) ++{ ++ ar71xx_device_stop(AR7240_USB_RESET_MASK); ++ mdelay(1000); ++ ar71xx_device_start(AR7240_USB_RESET_MASK); ++ ++ /* WAR for HW bug. Here it adjusts the duration between two SOFS */ ++ ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x3); ++ ++ ar71xx_ohci_device.resource = ar7240_ohci_resources; ++ ar71xx_ohci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources); ++ platform_device_register(&ar71xx_ohci_device); ++} ++ ++static void __init ar7241_usb_setup(void) ++{ ++ ar71xx_device_start(AR724X_RESET_USBSUS_OVERRIDE); ++ mdelay(10); ++ ++ ar71xx_device_start(AR724X_RESET_USB_HOST); ++ mdelay(10); ++ ++ ar71xx_device_start(AR724X_RESET_USB_PHY); ++ mdelay(10); ++ ++ ar71xx_ehci_data.is_ar91xx = 1; ++ ar71xx_ehci_device.resource = ar7240_ohci_resources; ++ ar71xx_ehci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources); ++ platform_device_register(&ar71xx_ehci_device); ++} ++ ++static void __init ar91xx_usb_setup(void) ++{ ++ ar71xx_device_stop(RESET_MODULE_USBSUS_OVERRIDE); ++ mdelay(10); ++ ++ ar71xx_device_start(RESET_MODULE_USB_HOST); ++ mdelay(10); ++ ++ ar71xx_device_start(RESET_MODULE_USB_PHY); ++ mdelay(10); ++ ++ ar71xx_ehci_data.is_ar91xx = 1; ++ platform_device_register(&ar71xx_ehci_device); ++} ++ ++void __init ar71xx_add_device_usb(void) ++{ ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7240: ++ ar7240_usb_setup(); ++ break; ++ ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ ar7241_usb_setup(); ++ break; ++ ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ ar71xx_usb_setup(); ++ break; ++ ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ar91xx_usb_setup(); ++ break; ++ ++ default: ++ BUG(); ++ } ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.h linux-2.6.39/arch/mips/ar71xx/dev-usb.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-usb.h 2011-08-24 02:41:55.427989786 +0200 +@@ -0,0 +1,17 @@ ++/* ++ * Atheros AR71xx USB host device support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#ifndef _AR71XX_DEV_USB_H ++#define _AR71XX_DEV_USB_H ++ ++void ar71xx_add_device_usb(void) __init; ++ ++#endif /* _AR71XX_DEV_USB_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c linux-2.6.39/arch/mips/ar71xx/early_printk.c +--- linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/early_printk.c 2011-08-24 02:41:55.427989786 +0200 +@@ -0,0 +1,96 @@ ++/* ++ * Atheros AR7xxx/AR9xxx SoC early printk support ++ * ++ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++static void (*_prom_putchar) (unsigned char); ++ ++static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val) ++{ ++ u32 t; ++ ++ do { ++ t = __raw_readl(reg); ++ if ((t & mask) == val) ++ break; ++ } while (1); ++} ++ ++static void prom_putchar_ar71xx(unsigned char ch) ++{ ++ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); ++ ++ prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); ++ __raw_writel(ch, base + UART_TX * 4); ++ prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); ++} ++ ++static void prom_putchar_ar933x(unsigned char ch) ++{ ++ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE)); ++ ++ prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, ++ AR933X_UART_DATA_TX_CSR); ++ __raw_writel(AR933X_UART_DATA_TX_CSR | ch, base + AR933X_UART_DATA_REG); ++ prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, ++ AR933X_UART_DATA_TX_CSR); ++} ++ ++static void prom_putchar_dummy(unsigned char ch) ++{ ++ /* nothing to do */ ++} ++ ++static void prom_putchar_init(void) ++{ ++ void __iomem *base; ++ u32 id; ++ ++ base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE)); ++ id = __raw_readl(base + AR71XX_RESET_REG_REV_ID); ++ id &= REV_ID_MAJOR_MASK; ++ ++ switch (id) { ++ case REV_ID_MAJOR_AR71XX: ++ case REV_ID_MAJOR_AR7240: ++ case REV_ID_MAJOR_AR7241: ++ case REV_ID_MAJOR_AR7242: ++ case REV_ID_MAJOR_AR913X: ++ case REV_ID_MAJOR_AR9341: ++ case REV_ID_MAJOR_AR9342: ++ case REV_ID_MAJOR_AR9344: ++ _prom_putchar = prom_putchar_ar71xx; ++ break; ++ ++ case REV_ID_MAJOR_AR9330: ++ case REV_ID_MAJOR_AR9331: ++ _prom_putchar = prom_putchar_ar933x; ++ break; ++ ++ default: ++ _prom_putchar = prom_putchar_dummy; ++ break; ++ } ++} ++ ++void prom_putchar(unsigned char ch) ++{ ++ if (!_prom_putchar) ++ prom_putchar_init(); ++ ++ _prom_putchar(ch); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/gpio.c linux-2.6.39/arch/mips/ar71xx/gpio.c +--- linux-2.6.39.orig/arch/mips/ar71xx/gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/gpio.c 2011-08-24 02:41:55.457989607 +0200 +@@ -0,0 +1,193 @@ ++/* ++ * Atheros AR7XXX/AR9XXX SoC GPIO API support ++ * ++ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++static DEFINE_SPINLOCK(ar71xx_gpio_lock); ++ ++unsigned long ar71xx_gpio_count; ++EXPORT_SYMBOL(ar71xx_gpio_count); ++ ++void __ar71xx_gpio_set_value(unsigned gpio, int value) ++{ ++ void __iomem *base = ar71xx_gpio_base; ++ ++ if (value) ++ __raw_writel(1 << gpio, base + GPIO_REG_SET); ++ else ++ __raw_writel(1 << gpio, base + GPIO_REG_CLEAR); ++} ++EXPORT_SYMBOL(__ar71xx_gpio_set_value); ++ ++int __ar71xx_gpio_get_value(unsigned gpio) ++{ ++ return (__raw_readl(ar71xx_gpio_base + GPIO_REG_IN) >> gpio) & 1; ++} ++EXPORT_SYMBOL(__ar71xx_gpio_get_value); + +static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset) +{ @@ -2581,6 +2491,17 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/gpio.c linux-2.6.39/arch/mips/ar71x + ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT; + break; + ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ ar71xx_gpio_chip.ngpio = AR933X_GPIO_COUNT; ++ break; ++ ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ar71xx_gpio_chip.ngpio = AR934X_GPIO_COUNT; ++ break; ++ + default: + BUG(); + } @@ -2591,15 +2512,17 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/gpio.c linux-2.6.39/arch/mips/ar71x +} diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx/irq.c --- linux-2.6.39.orig/arch/mips/ar71xx/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/irq.c 2011-06-01 13:50:58.000000000 +0200 -@@ -0,0 +1,293 @@ ++++ linux-2.6.39/arch/mips/ar71xx/irq.c 2011-08-24 02:41:55.457989607 +0200 +@@ -0,0 +1,377 @@ +/* + * Atheros AR71xx SoC specific interrupt handling + * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.31 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -2616,8 +2539,6 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + +#include + -+static int ip2_flush_reg; -+ +static void ar71xx_gpio_irq_dispatch(void) +{ + void __iomem *base = ar71xx_gpio_base; @@ -2634,13 +2555,12 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + +static void ar71xx_gpio_irq_unmask(struct irq_data *d) +{ ++ unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE; + void __iomem *base = ar71xx_gpio_base; + u32 t; + -+ d->irq -= AR71XX_GPIO_IRQ_BASE; -+ + t = __raw_readl(base + GPIO_REG_INT_ENABLE); -+ __raw_writel(t | (1 << d->irq), base + GPIO_REG_INT_ENABLE); ++ __raw_writel(t | (1 << irq), base + GPIO_REG_INT_ENABLE); + + /* flush write */ + (void) __raw_readl(base + GPIO_REG_INT_ENABLE); @@ -2648,34 +2568,22 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + +static void ar71xx_gpio_irq_mask(struct irq_data *d) +{ ++ unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE; + void __iomem *base = ar71xx_gpio_base; + u32 t; + -+ d->irq -= AR71XX_GPIO_IRQ_BASE; -+ + t = __raw_readl(base + GPIO_REG_INT_ENABLE); -+ __raw_writel(t & ~(1 << d->irq), base + GPIO_REG_INT_ENABLE); ++ __raw_writel(t & ~(1 << irq), base + GPIO_REG_INT_ENABLE); + + /* flush write */ + (void) __raw_readl(base + GPIO_REG_INT_ENABLE); +} + -+#if 0 -+static int ar71xx_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) -+{ -+ /* TODO: implement */ -+ return 0; -+} -+#else -+#define ar71xx_gpio_irq_set_type NULL -+#endif -+ +static struct irq_chip ar71xx_gpio_irq_chip = { + .name = "AR71XX GPIO", -+ .irq_unmask = ar71xx_gpio_irq_unmask, -+ .irq_mask = ar71xx_gpio_irq_mask, ++ .irq_unmask = ar71xx_gpio_irq_unmask, ++ .irq_mask = ar71xx_gpio_irq_mask, + .irq_mask_ack = ar71xx_gpio_irq_mask, -+ .irq_set_type = ar71xx_gpio_irq_set_type, +}; + +static struct irqaction ar71xx_gpio_irqaction = { @@ -2683,7 +2591,6 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + .name = "cascade [AR71XX GPIO]", +}; + -+#define GPIO_IRQ_INIT_STATUS (IRQ_LEVEL | IRQ_TYPE_LEVEL_HIGH) +#define GPIO_INT_ALL 0xffff + +static void __init ar71xx_gpio_irq_init(void) @@ -2701,10 +2608,9 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_POLARITY); + + for (i = AR71XX_GPIO_IRQ_BASE; -+ i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++) { ++ i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++) + irq_set_chip_and_handler(i, &ar71xx_gpio_irq_chip, + handle_level_irq); -+ } + + setup_irq(AR71XX_MISC_IRQ_GPIO, &ar71xx_gpio_irqaction); +} @@ -2740,19 +2646,33 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + else if (pending & MISC_INT_WDOG) + do_IRQ(AR71XX_MISC_IRQ_WDOG); + ++ else if (pending & MISC_INT_TIMER2) ++ do_IRQ(AR71XX_MISC_IRQ_TIMER2); ++ ++ else if (pending & MISC_INT_TIMER3) ++ do_IRQ(AR71XX_MISC_IRQ_TIMER3); ++ ++ else if (pending & MISC_INT_TIMER4) ++ do_IRQ(AR71XX_MISC_IRQ_TIMER4); ++ ++ else if (pending & MISC_INT_DDR_PERF) ++ do_IRQ(AR71XX_MISC_IRQ_DDR_PERF); ++ ++ else if (pending & MISC_INT_ENET_LINK) ++ do_IRQ(AR71XX_MISC_IRQ_ENET_LINK); ++ + else + spurious_interrupt(); +} + +static void ar71xx_misc_irq_unmask(struct irq_data *d) +{ ++ unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; + void __iomem *base = ar71xx_reset_base; + u32 t; + -+ d->irq -= AR71XX_MISC_IRQ_BASE; -+ + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); -+ __raw_writel(t | (1 << d->irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); ++ __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); + + /* flush write */ + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); @@ -2760,25 +2680,23 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + +static void ar71xx_misc_irq_mask(struct irq_data *d) +{ ++ unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; + void __iomem *base = ar71xx_reset_base; + u32 t; + -+ d->irq -= AR71XX_MISC_IRQ_BASE; -+ + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); -+ __raw_writel(t & ~(1 << d->irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); ++ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); + + /* flush write */ + (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); +} + -+static void ar724x_misc_irq_ack(unsigned int irq) ++static void ar724x_misc_irq_ack(struct irq_data *d) +{ ++ unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; + void __iomem *base = ar71xx_reset_base; + u32 t; + -+ irq -= AR71XX_MISC_IRQ_BASE; -+ + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); + __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS); + @@ -2788,8 +2706,8 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + +static struct irq_chip ar71xx_misc_irq_chip = { + .name = "AR71XX MISC", -+ .irq_unmask = ar71xx_misc_irq_unmask, -+ .irq_mask = ar71xx_misc_irq_mask, ++ .irq_unmask = ar71xx_misc_irq_unmask, ++ .irq_mask = ar71xx_misc_irq_mask, +}; + +static struct irqaction ar71xx_misc_irqaction = { @@ -2809,6 +2727,11 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + case AR71XX_SOC_AR7240: + case AR71XX_SOC_AR7241: + case AR71XX_SOC_AR7242: ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: + ar71xx_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; + break; + default: @@ -2817,14 +2740,82 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + } + + for (i = AR71XX_MISC_IRQ_BASE; -+ i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++) { ++ i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++) + irq_set_chip_and_handler(i, &ar71xx_misc_irq_chip, + handle_level_irq); -+ } + + setup_irq(AR71XX_CPU_IRQ_MISC, &ar71xx_misc_irqaction); +} + ++/* ++ * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for ++ * these devices typically allocate coherent DMA memory, however the ++ * DMA controller may still have some unsynchronized data in the FIFO. ++ * Issue a flush in the handlers to ensure that the driver sees ++ * the update. ++ */ ++static void ar71xx_ip2_handler(void) ++{ ++ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_PCI); ++ do_IRQ(AR71XX_CPU_IRQ_IP2); ++} ++ ++static void ar724x_ip2_handler(void) ++{ ++ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_PCIE); ++ do_IRQ(AR71XX_CPU_IRQ_IP2); ++} ++ ++static void ar913x_ip2_handler(void) ++{ ++ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_WMAC); ++ do_IRQ(AR71XX_CPU_IRQ_IP2); ++} ++ ++static void ar933x_ip2_handler(void) ++{ ++ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_WMAC); ++ do_IRQ(AR71XX_CPU_IRQ_IP2); ++} ++ ++static void ar934x_ip2_handler(void) ++{ ++ ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_PCIE); ++ do_IRQ(AR71XX_CPU_IRQ_IP2); ++} ++ ++static void ar71xx_ip3_handler(void) ++{ ++ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_USB); ++ do_IRQ(AR71XX_CPU_IRQ_USB); ++} ++ ++static void ar724x_ip3_handler(void) ++{ ++ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_USB); ++ do_IRQ(AR71XX_CPU_IRQ_USB); ++} ++ ++static void ar913x_ip3_handler(void) ++{ ++ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_USB); ++ do_IRQ(AR71XX_CPU_IRQ_USB); ++} ++ ++static void ar933x_ip3_handler(void) ++{ ++ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_USB); ++ do_IRQ(AR71XX_CPU_IRQ_USB); ++} ++ ++static void ar934x_ip3_handler(void) ++{ ++ do_IRQ(AR71XX_CPU_IRQ_USB); ++} ++ ++static void (*ip2_handler)(void); ++static void (*ip3_handler)(void); ++ +asmlinkage void plat_irq_dispatch(void) +{ + unsigned long pending; @@ -2834,17 +2825,8 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + if (pending & STATUSF_IP7) + do_IRQ(AR71XX_CPU_IRQ_TIMER); + -+ else if (pending & STATUSF_IP2) { -+ /* -+ * This IRQ is meant for a PCI device. Drivers for PCI devices -+ * typically allocate coherent DMA memory for the descriptor -+ * ring, however the DMA controller may still have some -+ * unsynchronized data in the FIFO. -+ * Issue a flush here to ensure that the driver sees the update. -+ */ -+ ar71xx_ddr_flush(ip2_flush_reg); -+ do_IRQ(AR71XX_CPU_IRQ_IP2); -+ } ++ else if (pending & STATUSF_IP2) ++ ip2_handler(); + + else if (pending & STATUSF_IP4) + do_IRQ(AR71XX_CPU_IRQ_GE0); @@ -2853,31 +2835,54 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + do_IRQ(AR71XX_CPU_IRQ_GE1); + + else if (pending & STATUSF_IP3) -+ do_IRQ(AR71XX_CPU_IRQ_USB); ++ ip3_handler(); + + else if (pending & STATUSF_IP6) + ar71xx_misc_irq_dispatch(); + -+ else -+ spurious_interrupt(); ++ spurious_interrupt(); +} + +void __init arch_init_irq(void) +{ -+ switch(ar71xx_soc) { ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ ip2_handler = ar71xx_ip2_handler; ++ ip3_handler = ar71xx_ip3_handler; ++ break; ++ + case AR71XX_SOC_AR7240: + case AR71XX_SOC_AR7241: + case AR71XX_SOC_AR7242: -+ ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE; ++ ip2_handler = ar724x_ip2_handler; ++ ip3_handler = ar724x_ip3_handler; + break; ++ + case AR71XX_SOC_AR9130: + case AR71XX_SOC_AR9132: -+ ip2_flush_reg = AR91XX_DDR_REG_FLUSH_WMAC; ++ ip2_handler = ar913x_ip2_handler; ++ ip3_handler = ar913x_ip3_handler; + break; -+ default: -+ ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI; ++ ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ ip2_handler = ar933x_ip2_handler; ++ ip3_handler = ar933x_ip3_handler; ++ break; ++ ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ip2_handler = ar934x_ip2_handler; ++ ip3_handler = ar934x_ip3_handler; + break; ++ ++ default: ++ BUG(); + } ++ + mips_cpu_irq_init(); + + ar71xx_misc_irq_init(); @@ -2886,429 +2891,688 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx + + ar71xx_gpio_irq_init(); +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c linux-2.6.39/arch/mips/ar71xx/mach-ap81.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-ap81.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,140 @@ -+/* -+ * Atheros AP81 board support -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * Copyright (C) 2009 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Kconfig linux-2.6.39/arch/mips/ar71xx/Kconfig +--- linux-2.6.39.orig/arch/mips/ar71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/Kconfig 2011-08-24 04:20:27.209240389 +0200 +@@ -0,0 +1,420 @@ ++if ATHEROS_AR71XX + -+#include ++menu "Atheros AR71xx machine selection" + -+#include "machtype.h" -+#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ar913x-wmac.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-usb.h" ++config AR71XX_MACH_AP81 ++ bool "Atheros AP81 board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+#define AP81_GPIO_LED_STATUS 1 -+#define AP81_GPIO_LED_AOSS 3 -+#define AP81_GPIO_LED_WLAN 6 -+#define AP81_GPIO_LED_POWER 14 ++config AR71XX_MACH_AP83 ++ bool "Atheros AP83 board support" ++ select SOC_AR913X ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+#define AP81_GPIO_BTN_SW4 12 -+#define AP81_GPIO_BTN_SW1 21 ++config AR71XX_MACH_AP96 ++ bool "Atheros AP96 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP94_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+#define AP81_BUTTONS_POLL_INTERVAL 20 ++config AR71XX_MACH_AP121 ++ bool "Atheros AP121 board support" ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ select AR71XX_DEV_AR9XXX_WMAC ++ select SOC_AR933X ++ default n + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition ap81_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x040000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "u-boot-env", -+ .offset = 0x040000, -+ .size = 0x010000, -+ } , { -+ .name = "rootfs", -+ .offset = 0x050000, -+ .size = 0x500000, -+ } , { -+ .name = "uImage", -+ .offset = 0x550000, -+ .size = 0x100000, -+ } , { -+ .name = "ART", -+ .offset = 0x650000, -+ .size = 0x1b0000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ ++config AR71XX_MACH_DB120 ++ bool "Atheros DB120 board support" ++ select SOC_AR934X ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_DB120_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+static struct flash_platform_data ap81_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = ap81_partitions, -+ .nr_parts = ARRAY_SIZE(ap81_partitions), -+#endif -+}; ++config AR71XX_MACH_DIR_600_A1 ++ bool "D-Link DIR-600 rev. A1 support" ++ select SOC_AR724X ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_NVRAM ++ default n + -+static struct gpio_led ap81_leds_gpio[] __initdata = { -+ { -+ .name = "ap81:green:status", -+ .gpio = AP81_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "ap81:amber:aoss", -+ .gpio = AP81_GPIO_LED_AOSS, -+ .active_low = 1, -+ }, { -+ .name = "ap81:green:wlan", -+ .gpio = AP81_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "ap81:green:power", -+ .gpio = AP81_GPIO_LED_POWER, -+ .active_low = 1, -+ } -+}; ++config AR71XX_MACH_DIR_615_C1 ++ bool "D-Link DIR-615 rev. C1 support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_NVRAM ++ default n + -+static struct gpio_button ap81_gpio_buttons[] __initdata = { -+ { -+ .desc = "sw1", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .threshold = 3, -+ .gpio = AP81_GPIO_BTN_SW1, -+ .active_low = 1, -+ } , { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .threshold = 3, -+ .gpio = AP81_GPIO_BTN_SW4, -+ .active_low = 1, -+ } -+}; ++config AR71XX_MACH_DIR_825_B1 ++ bool "D-Link DIR-825 rev. B1 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP94_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+static void __init ap81_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++config AR71XX_MACH_JA76PF ++ bool "jjPlus JA76PF board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ ar71xx_set_mac_base(eeprom); -+ ar71xx_add_device_mdio(0x0); ++config AR71XX_MACH_JWAP003 ++ bool "jjPlus JWAP003 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_USB ++ default n + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.has_ar8216 = 1; ++config AR71XX_MACH_PB42 ++ bool "Atheros PB42 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ default n + -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++config AR71XX_MACH_PB44 ++ bool "Atheros PB44 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); ++config AR71XX_MACH_PB92 ++ bool "Atheros PB92 board support" ++ select SOC_AR724X ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB9X_PCI if PCI ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ ar71xx_add_device_usb(); ++config AR71XX_MACH_AW_NR580 ++ bool "AzureWave AW-NR580 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+ ar71xx_add_device_m25p80(&ap81_flash_data); ++config AR71XX_MACH_WZR_HP_AG300H ++ bool "Buffalo WZR-HP-AG300H board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio), -+ ap81_leds_gpio); ++config AR71XX_MACH_WZR_HP_G300NH ++ bool "Buffalo WZR-HP-G300NH board support" ++ select SOC_AR913X ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ select RTL8366_SMI ++ default n + -+ ar71xx_add_device_gpio_buttons(-1, AP81_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(ap81_gpio_buttons), -+ ap81_gpio_buttons); ++config AR71XX_MACH_WP543 ++ bool "Compex WP543/WPJ543 board support" ++ select SOC_AR71XX ++ select MYLOADER ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ ar913x_add_device_wmac(eeprom, NULL); -+} ++config AR71XX_MACH_WRT160NL ++ bool "Linksys WRT160NL board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ select AR71XX_NVRAM ++ default n + -+MIPS_MACHINE(AR71XX_MACH_AP81, "AP81", "Atheros AP81", ap81_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c linux-2.6.39/arch/mips/ar71xx/mach-ap83.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-ap83.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,266 @@ ++config AR71XX_MACH_WRT400N ++ bool "Linksys WRT400N board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_AP94_PCI if PCI ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n ++ ++config AR71XX_MACH_RB4XX ++ bool "MikroTik RouterBOARD 4xx series support" ++ select SOC_AR71XX ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n ++ ++config AR71XX_MACH_RB750 ++ bool "MikroTik RouterBOARD 750 support" ++ select SOC_AR724X ++ default n ++ ++config AR71XX_MACH_WNDR3700 ++ bool "NETGEAR WNDR3700 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP94_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n ++ ++config AR71XX_MACH_WNR2000 ++ bool "NETGEAR WNR2000 board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n ++ ++config AR71XX_MACH_MZK_W04NU ++ bool "Planex MZK-W04NU board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n ++ ++config AR71XX_MACH_MZK_W300NH ++ bool "Planex MZK-W300NH board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n ++ ++config AR71XX_MACH_NBG460N ++ bool "Zyxel NBG460N/550N/550NH board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n ++ ++config AR71XX_MACH_TL_MR3X20 ++ bool "TP-LINK TL-MR3220/3420 support" ++ select SOC_AR724X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n ++ ++config AR71XX_MACH_TL_WA901ND ++ bool "TP-LINK TL-WA901ND support" ++ select SOC_AR724X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n ++ ++config AR71XX_MACH_TL_WA901ND_V2 ++ bool "TP-LINK TL-WA901ND v2 support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n ++ ++config AR71XX_MACH_TL_WR741ND ++ bool "TP-LINK TL-WR741ND support" ++ select SOC_AR724X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n ++ ++config AR71XX_MACH_TL_WR841N_V1 ++ bool "TP-LINK TL-WR841N v1 support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_DSA ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n ++ ++config AR71XX_MACH_TL_WR941ND ++ bool "TP-LINK TL-WR941ND support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_DSA ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n ++ ++config AR71XX_MACH_TL_WR1043ND ++ bool "TP-LINK TL-WR1043ND support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n ++ ++config AR71XX_MACH_TEW_632BRP ++ bool "TRENDnet TEW-632BRP support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_NVRAM ++ default n ++ ++config AR71XX_MACH_UBNT ++ bool "Ubiquiti AR71xx based boards support" ++ select SOC_AR71XX ++ select SOC_AR724X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_USB ++ default n ++ ++config AR71XX_MACH_EAP7660D ++ bool "Senao EAP7660D support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n ++ ++config AR71XX_MACH_ZCN_1523H ++ bool "Zcomax ZCN-1523H support" ++ select SOC_AR724X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n ++ ++endmenu ++ ++config SOC_AR71XX ++ bool ++ select USB_ARCH_HAS_EHCI ++ select USB_ARCH_HAS_OHCI ++ ++config SOC_AR724X ++ bool ++ select USB_ARCH_HAS_EHCI ++ select USB_ARCH_HAS_OHCI ++ ++config SOC_AR913X ++ bool ++ select USB_ARCH_HAS_EHCI ++ ++config SOC_AR934X ++ bool ++ select USB_ARCH_HAS_EHCI ++ ++config AR71XX_DEV_M25P80 ++ def_bool n ++ ++config AR71XX_DEV_AP91_PCI ++ select AR71XX_PCI_ATH9K_FIXUP ++ def_bool n ++ ++config AR71XX_DEV_AP94_PCI ++ select AR71XX_PCI_ATH9K_FIXUP ++ def_bool n ++ ++config AR71XX_DEV_AR9XXX_WMAC ++ def_bool n ++ ++config AR71XX_DEV_DB120_PCI ++ select AR71XX_PCI_ATH9K_FIXUP ++ def_bool n ++ ++config AR71XX_DEV_DSA ++ def_bool n ++ ++config AR71XX_DEV_GPIO_BUTTONS ++ def_bool n ++ ++config AR71XX_DEV_LEDS_GPIO ++ def_bool n ++ ++config AR71XX_DEV_PB42_PCI ++ def_bool n ++ ++config AR71XX_DEV_PB9X_PCI ++ def_bool n ++ ++config AR71XX_DEV_USB ++ def_bool n ++ ++config AR71XX_NVRAM ++ def_bool n ++ ++config AR71XX_PCI_ATH9K_FIXUP ++ def_bool n ++ ++config SOC_AR933X ++ bool ++ select USB_ARCH_HAS_EHCI ++ ++endif +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap121.c linux-2.6.39/arch/mips/ar71xx/mach-ap121.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap121.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ap121.c 2011-08-24 02:41:55.477989660 +0200 +@@ -0,0 +1,245 @@ +/* -+ * Atheros AP83 board support ++ * Atheros AP121 board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2011 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include +#include +#include -+#include -+#include -+#include -+ -+#include -+#include ++#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-ar913x-wmac.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "dev-m25p80.h" +#include "dev-usb.h" + -+#define AP83_GPIO_LED_WLAN 6 -+#define AP83_GPIO_LED_POWER 14 -+#define AP83_GPIO_LED_JUMPSTART 15 -+#define AP83_GPIO_BTN_JUMPSTART 12 -+#define AP83_GPIO_BTN_RESET 21 ++#define AP121_GPIO_LED_WLAN 0 ++#define AP121_GPIO_LED_USB 1 + -+#define AP83_050_GPIO_VSC7385_CS 1 -+#define AP83_050_GPIO_VSC7385_MISO 3 -+#define AP83_050_GPIO_VSC7385_MOSI 16 -+#define AP83_050_GPIO_VSC7385_SCK 17 ++#define AP121_GPIO_BTN_JUMPSTART 11 ++#define AP121_GPIO_BTN_RESET 12 ++ ++#define AP121_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL) ++ ++#define AP121_MAC0_OFFSET 0x0000 ++#define AP121_MAC1_OFFSET 0x0006 ++#define AP121_CALDATA_OFFSET 0x1000 ++#define AP121_WMAC_MAC_OFFSET 0x1002 + -+#define AP83_BUTTONS_POLL_INTERVAL 20 ++#define AP121_MINI_GPIO_LED_WLAN 0 ++#define AP121_MINI_GPIO_BTN_JUMPSTART 12 ++#define AP121_MINI_GPIO_BTN_RESET 11 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition ap83_flash_partitions[] = { ++static struct mtd_partition ap121_parts[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x040000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "u-boot-env", -+ .offset = 0x040000, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "kernel", -+ .offset = 0x060000, -+ .size = 0x140000, -+ } , { -+ .name = "rootfs", -+ .offset = 0x1a0000, -+ .size = 0x650000, -+ } , { -+ .name = "art", -+ .offset = 0x7f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "firmware", -+ .offset = 0x060000, -+ .size = 0x790000, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ -+ -+static struct ar91xx_flash_platform_data ap83_flash_data = { -+ .width = 2, -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = ap83_flash_partitions, -+ .nr_parts = ARRAY_SIZE(ap83_flash_partitions), -+#endif ++ }, ++ { ++ .name = "rootfs", ++ .offset = 0x010000, ++ .size = 0x130000, ++ }, ++ { ++ .name = "uImage", ++ .offset = 0x140000, ++ .size = 0x0a0000, ++ }, ++ { ++ .name = "NVRAM", ++ .offset = 0x1e0000, ++ .size = 0x010000, ++ }, ++ { ++ .name = "ART", ++ .offset = 0x1f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, +}; ++#define ap121_nr_parts ARRAY_SIZE(ap121_parts) + -+static struct resource ap83_flash_resources[] = { -+ [0] = { -+ .start = AR71XX_SPI_BASE, -+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, -+ .flags = IORESOURCE_MEM, ++static struct mtd_partition ap121_mini_parts[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, ++ { ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, ++ { ++ .name = "rootfs", ++ .offset = 0x050000, ++ .size = 0x2b0000, ++ }, ++ { ++ .name = "uImage", ++ .offset = 0x300000, ++ .size = 0x0e0000, ++ }, ++ { ++ .name = "NVRAM", ++ .offset = 0x3e0000, ++ .size = 0x010000, ++ }, ++ { ++ .name = "ART", ++ .offset = 0x3f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, + }, +}; + -+static struct platform_device ap83_flash_device = { -+ .name = "ar91xx-flash", -+ .id = -1, -+ .resource = ap83_flash_resources, -+ .num_resources = ARRAY_SIZE(ap83_flash_resources), -+ .dev = { -+ .platform_data = &ap83_flash_data, -+ } ++#define ap121_mini_nr_parts ARRAY_SIZE(ap121_parts) ++ ++#else ++#define ap121_parts NULL ++#define ap121_nr_parts 0 ++#define ap121_mini_parts NULL ++#define ap121_mini_nr_parts 0 ++#endif /* CONFIG_MTD_PARTITIONS */ ++ ++static struct flash_platform_data ap121_flash_data = { ++ .parts = ap121_parts, ++ .nr_parts = ap121_nr_parts, +}; + -+static struct gpio_led ap83_leds_gpio[] __initdata = { ++static struct gpio_led ap121_leds_gpio[] __initdata = { + { -+ .name = "ap83:green:jumpstart", -+ .gpio = AP83_GPIO_LED_JUMPSTART, -+ .active_low = 0, -+ }, { -+ .name = "ap83:green:power", -+ .gpio = AP83_GPIO_LED_POWER, ++ .name = "ap121:green:usb", ++ .gpio = AP121_GPIO_LED_USB, + .active_low = 0, -+ }, { -+ .name = "ap83:green:wlan", -+ .gpio = AP83_GPIO_LED_WLAN, ++ }, ++ { ++ .name = "ap121:green:wlan", ++ .gpio = AP121_GPIO_LED_WLAN, + .active_low = 0, + }, +}; + -+static struct gpio_button ap83_gpio_buttons[] __initdata = { ++static struct gpio_keys_button ap121_gpio_keys[] __initdata = { + { -+ .desc = "soft_reset", ++ .desc = "jumpstart button", + .type = EV_KEY, -+ .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = AP83_GPIO_BTN_RESET, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP121_GPIO_BTN_JUMPSTART, + .active_low = 1, -+ } , { -+ .desc = "jumpstart", ++ }, ++ { ++ .desc = "reset button", + .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = AP83_GPIO_BTN_JUMPSTART, ++ .code = KEY_RESTART, ++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP121_GPIO_BTN_RESET, + .active_low = 1, + } +}; + -+static struct resource ap83_040_spi_resources[] = { -+ [0] = { -+ .start = AR71XX_SPI_BASE, -+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, -+ .flags = IORESOURCE_MEM, ++static struct gpio_led ap121_mini_leds_gpio[] __initdata = { ++ { ++ .name = "ap121:green:wlan", ++ .gpio = AP121_MINI_GPIO_LED_WLAN, ++ .active_low = 0, + }, +}; + -+static struct platform_device ap83_040_spi_device = { -+ .name = "ap83-spi", -+ .id = 0, -+ .resource = ap83_040_spi_resources, -+ .num_resources = ARRAY_SIZE(ap83_040_spi_resources), -+}; -+ -+static struct spi_gpio_platform_data ap83_050_spi_data = { -+ .miso = AP83_050_GPIO_VSC7385_MISO, -+ .mosi = AP83_050_GPIO_VSC7385_MOSI, -+ .sck = AP83_050_GPIO_VSC7385_SCK, -+ .num_chipselect = 1, -+}; -+ -+static struct platform_device ap83_050_spi_device = { -+ .name = "spi_gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &ap83_050_spi_data, -+ } -+}; -+ -+static void ap83_vsc7385_reset(void) -+{ -+ ar71xx_device_stop(RESET_MODULE_GE1_PHY); -+ udelay(10); -+ ar71xx_device_start(RESET_MODULE_GE1_PHY); -+ mdelay(50); -+} -+ -+static struct vsc7385_platform_data ap83_vsc7385_data = { -+ .reset = ap83_vsc7385_reset, -+ .ucode_name = "vsc7385_ucode_ap83.bin", -+ .mac_cfg = { -+ .tx_ipg = 6, -+ .bit2 = 0, -+ .clk_sel = 3, ++static struct gpio_keys_button ap121_mini_gpio_keys[] __initdata = { ++ { ++ .desc = "jumpstart button", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP121_MINI_GPIO_BTN_JUMPSTART, ++ .active_low = 1, + }, -+}; -+ -+static struct spi_board_info ap83_spi_info[] = { + { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "spi-vsc7385", -+ .platform_data = &ap83_vsc7385_data, -+ .controller_data = (void *) AP83_050_GPIO_VSC7385_CS, ++ .desc = "reset button", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP121_MINI_GPIO_BTN_RESET, ++ .active_low = 1, + } +}; + -+static void __init ap83_generic_setup(void) ++static void __init ap121_common_setup(void) +{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ar71xx_set_mac_base(eeprom); ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + -+ ar71xx_add_device_mdio(0xfffffffe); ++ ar71xx_add_device_m25p80(&ap121_flash_data); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.phy_mask = 0x1; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, art + AP121_MAC0_OFFSET, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, art + AP121_MAC1_OFFSET, 0); + -+ ar71xx_add_device_eth(0); ++ /* WAN port */ ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = BIT(4); + -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ /* LAN ports */ ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ar71xx_eth1_data.speed = SPEED_1000; + ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_eth1_data.has_ar7240_switch = 1; + -+ ar71xx_eth1_pll_data.pll_1000 = 0x1f000000; -+ ++ ar71xx_add_device_mdio(0x0); + ar71xx_add_device_eth(1); ++ ar71xx_add_device_eth(0); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio), -+ ap83_leds_gpio); -+ -+ ar71xx_add_device_gpio_buttons(-1, AP83_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(ap83_gpio_buttons), -+ ap83_gpio_buttons); -+ -+ ar71xx_add_device_usb(); -+ -+ ar913x_add_device_wmac(eeprom, NULL); -+ -+ platform_device_register(&ap83_flash_device); -+ -+ spi_register_board_info(ap83_spi_info, ARRAY_SIZE(ap83_spi_info)); ++ ar9xxx_add_device_wmac(art + AP121_CALDATA_OFFSET, ++ art + AP121_WMAC_MAC_OFFSET); +} + -+static void __init ap83_040_setup(void) ++static void __init ap121_setup(void) +{ -+ ap83_flash_data.is_shared=1; -+ ap83_generic_setup(); -+ platform_device_register(&ap83_040_spi_device); -+} ++ ap121_flash_data.parts = ap121_parts; ++ ap121_flash_data.nr_parts = ap121_nr_parts; + -+static void __init ap83_050_setup(void) -+{ -+ ap83_generic_setup(); -+ platform_device_register(&ap83_050_spi_device); ++ ap121_common_setup(); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio), ++ ap121_leds_gpio); ++ ar71xx_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap121_gpio_keys), ++ ap121_gpio_keys); ++ ++ ar71xx_add_device_usb(); +} + -+static void __init ap83_setup(void) ++static void __init ap121_mini_setup(void) +{ -+ u8 *board_id = (u8 *) KSEG1ADDR(0x1fff1244); -+ unsigned int board_version; ++ ap121_flash_data.parts = ap121_mini_parts; ++ ap121_flash_data.nr_parts = ap121_mini_nr_parts; + -+ board_version = (unsigned int)(board_id[0] - '0'); -+ board_version += ((unsigned int)(board_id[1] - '0')) * 10; ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap121_mini_leds_gpio), ++ ap121_mini_leds_gpio); ++ ar71xx_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap121_mini_gpio_keys), ++ ap121_mini_gpio_keys); + -+ switch (board_version) { -+ case 40: -+ ap83_040_setup(); -+ break; -+ case 50: -+ ap83_050_setup(); -+ break; -+ default: -+ printk(KERN_WARNING "AP83-%03u board is not yet supported\n", -+ board_version); -+ } ++ ap121_common_setup(); +} + -+MIPS_MACHINE(AR71XX_MACH_AP83, "AP83", "Atheros AP83", ap83_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,101 @@ ++MIPS_MACHINE(AR71XX_MACH_AP121, "AP121", "Atheros AP121", ++ ap121_setup); ++ ++MIPS_MACHINE(AR71XX_MACH_AP121_MINI, "AP121-MINI", "Atheros AP121-MINI", ++ ap121_mini_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c linux-2.6.39/arch/mips/ar71xx/mach-ap81.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ap81.c 2011-08-24 02:41:55.477989660 +0200 +@@ -0,0 +1,142 @@ +/* -+ * AzureWave AW-NR580 board support ++ * Atheros AP81 board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2009 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -3318,616 +3582,703 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c linux-2.6.39/arch/m +#include +#include + -+#include +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" -+#include "dev-pb42-pci.h" +#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+#define AW_NR580_GPIO_LED_READY_RED 0 -+#define AW_NR580_GPIO_LED_WLAN 1 -+#define AW_NR580_GPIO_LED_READY_GREEN 2 -+#define AW_NR580_GPIO_LED_WPS_GREEN 4 -+#define AW_NR580_GPIO_LED_WPS_AMBER 5 ++#define AP81_GPIO_LED_STATUS 1 ++#define AP81_GPIO_LED_AOSS 3 ++#define AP81_GPIO_LED_WLAN 6 ++#define AP81_GPIO_LED_POWER 14 + -+#define AW_NR580_GPIO_BTN_WPS 3 -+#define AW_NR580_GPIO_BTN_RESET 11 ++#define AP81_GPIO_BTN_SW4 12 ++#define AP81_GPIO_BTN_SW1 21 + -+#define AW_NR580_BUTTONS_POLL_INTERVAL 20 ++#define AP81_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL) + -+static struct gpio_led aw_nr580_leds_gpio[] __initdata = { ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition ap81_partitions[] = { + { -+ .name = "aw-nr580:red:ready", -+ .gpio = AW_NR580_GPIO_LED_READY_RED, -+ .active_low = 0, -+ }, { -+ .name = "aw-nr580:green:ready", -+ .gpio = AW_NR580_GPIO_LED_READY_GREEN, -+ .active_low = 0, ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "aw-nr580:green:wps", -+ .gpio = AW_NR580_GPIO_LED_WPS_GREEN, -+ .active_low = 0, ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, + }, { -+ .name = "aw-nr580:amber:wps", -+ .gpio = AW_NR580_GPIO_LED_WPS_AMBER, -+ .active_low = 0, ++ .name = "rootfs", ++ .offset = 0x050000, ++ .size = 0x500000, + }, { -+ .name = "aw-nr580:green:wlan", -+ .gpio = AW_NR580_GPIO_LED_WLAN, -+ .active_low = 0, ++ .name = "uImage", ++ .offset = 0x550000, ++ .size = 0x100000, ++ }, { ++ .name = "ART", ++ .offset = 0x650000, ++ .size = 0x1b0000, ++ .mask_flags = MTD_WRITEABLE, + } +}; ++#endif /* CONFIG_MTD_PARTITIONS */ ++ ++static struct flash_platform_data ap81_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = ap81_partitions, ++ .nr_parts = ARRAY_SIZE(ap81_partitions), ++#endif ++}; + -+static struct gpio_button aw_nr580_gpio_buttons[] __initdata = { ++static struct gpio_led ap81_leds_gpio[] __initdata = { + { -+ .desc = "reset", ++ .name = "ap81:green:status", ++ .gpio = AP81_GPIO_LED_STATUS, ++ .active_low = 1, ++ }, { ++ .name = "ap81:amber:aoss", ++ .gpio = AP81_GPIO_LED_AOSS, ++ .active_low = 1, ++ }, { ++ .name = "ap81:green:wlan", ++ .gpio = AP81_GPIO_LED_WLAN, ++ .active_low = 1, ++ }, { ++ .name = "ap81:green:power", ++ .gpio = AP81_GPIO_LED_POWER, ++ .active_low = 1, ++ } ++}; ++ ++static struct gpio_keys_button ap81_gpio_keys[] __initdata = { ++ { ++ .desc = "sw1", + .type = EV_KEY, -+ .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = AW_NR580_GPIO_BTN_RESET, ++ .code = BTN_0, ++ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP81_GPIO_BTN_SW1, + .active_low = 1, + }, { -+ .desc = "wps", ++ .desc = "sw4", + .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = AW_NR580_GPIO_BTN_WPS, ++ .code = BTN_1, ++ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP81_GPIO_BTN_SW4, + .active_low = 1, + } +}; + -+static void __init aw_nr580_setup(void) ++static void __init ap81_setup(void) +{ ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ + ar71xx_add_device_mdio(0x0); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.has_ar8216 = 1; ++ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = 0x10; + + ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ pb42_pci_init(); ++ ar71xx_add_device_usb(); + -+ ar71xx_add_device_m25p80(NULL); ++ ar71xx_add_device_m25p80(&ap81_flash_data); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio), -+ aw_nr580_leds_gpio); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio), ++ ap81_leds_gpio); + -+ ar71xx_add_device_gpio_buttons(-1, AW_NR580_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(aw_nr580_gpio_buttons), -+ aw_nr580_gpio_buttons); ++ ar71xx_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap81_gpio_keys), ++ ap81_gpio_keys); ++ ++ ar9xxx_add_device_wmac(eeprom, NULL); +} + -+MIPS_MACHINE(AR71XX_MACH_AW_NR580, "AW-NR580", "AzureWave AW-NR580", -+ aw_nr580_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,138 @@ ++MIPS_MACHINE(AR71XX_MACH_AP81, "AP81", "Atheros AP81", ap81_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c linux-2.6.39/arch/mips/ar71xx/mach-ap83.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ap83.c 2011-08-24 02:41:55.477989660 +0200 +@@ -0,0 +1,267 @@ +/* -+ * D-Link DIR-600 rev. A1 board support ++ * Atheros AP83 board support + * -+ * Copyright (C) 2010 Gabor Juhos ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include ++#include +#include +#include ++#include ++#include ++#include + +#include ++#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ap91-eth.h" -+#include "dev-ap91-pci.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "nvram.h" -+ -+#define DIR_600_A1_GPIO_LED_WPS 0 -+#define DIR_600_A1_GPIO_LED_POWER_AMBER 1 -+#define DIR_600_A1_GPIO_LED_POWER_GREEN 6 ++#include "dev-usb.h" + -+#define DIR_600_A1_GPIO_BTN_RESET 8 -+#define DIR_600_A1_GPIO_BTN_WPS 12 ++#define AP83_GPIO_LED_WLAN 6 ++#define AP83_GPIO_LED_POWER 14 ++#define AP83_GPIO_LED_JUMPSTART 15 ++#define AP83_GPIO_BTN_JUMPSTART 12 ++#define AP83_GPIO_BTN_RESET 21 + -+#define DIR_600_A1_BUTTONS_POLL_INTERVAL 20 ++#define AP83_050_GPIO_VSC7385_CS 1 ++#define AP83_050_GPIO_VSC7385_MISO 3 ++#define AP83_050_GPIO_VSC7385_MOSI 16 ++#define AP83_050_GPIO_VSC7385_SCK 17 + -+#define DIR_600_A1_NVRAM_ADDR 0x1f030000 -+#define DIR_600_A1_NVRAM_SIZE 0x10000 ++#define AP83_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define AP83_KEYS_DEBOUNCE_INTERVAL (3 * AP83_KEYS_POLL_INTERVAL) + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition dir_600_a1_partitions[] = { ++static struct mtd_partition ap83_flash_partitions[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x030000, ++ .size = 0x040000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "nvram", -+ .offset = 0x030000, -+ .size = 0x010000, ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", -+ .offset = 0x040000, -+ .size = 0x0e0000, ++ .offset = 0x060000, ++ .size = 0x140000, + }, { + .name = "rootfs", -+ .offset = 0x120000, -+ .size = 0x2c0000, -+ }, { -+ .name = "mac", -+ .offset = 0x3e0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .offset = 0x1a0000, ++ .size = 0x650000, + }, { + .name = "art", -+ .offset = 0x3f0000, ++ .offset = 0x7f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", -+ .offset = 0x040000, -+ .size = 0x3a0000, ++ .offset = 0x060000, ++ .size = 0x790000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data dir_600_a1_flash_data = { ++static struct ar91xx_flash_platform_data ap83_flash_data = { ++ .width = 2, +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = dir_600_a1_partitions, -+ .nr_parts = ARRAY_SIZE(dir_600_a1_partitions), ++ .parts = ap83_flash_partitions, ++ .nr_parts = ARRAY_SIZE(ap83_flash_partitions), +#endif +}; + -+static struct gpio_led dir_600_a1_leds_gpio[] __initdata = { ++static struct resource ap83_flash_resources[] = { ++ [0] = { ++ .start = AR71XX_SPI_BASE, ++ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static struct platform_device ap83_flash_device = { ++ .name = "ar91xx-flash", ++ .id = -1, ++ .resource = ap83_flash_resources, ++ .num_resources = ARRAY_SIZE(ap83_flash_resources), ++ .dev = { ++ .platform_data = &ap83_flash_data, ++ } ++}; ++ ++static struct gpio_led ap83_leds_gpio[] __initdata = { + { -+ .name = "dir-600-a1:green:power", -+ .gpio = DIR_600_A1_GPIO_LED_POWER_GREEN, ++ .name = "ap83:green:jumpstart", ++ .gpio = AP83_GPIO_LED_JUMPSTART, ++ .active_low = 0, + }, { -+ .name = "dir-600-a1:amber:power", -+ .gpio = DIR_600_A1_GPIO_LED_POWER_AMBER, ++ .name = "ap83:green:power", ++ .gpio = AP83_GPIO_LED_POWER, ++ .active_low = 0, + }, { -+ .name = "dir-600-a1:blue:wps", -+ .gpio = DIR_600_A1_GPIO_LED_WPS, -+ .active_low = 1, -+ } ++ .name = "ap83:green:wlan", ++ .gpio = AP83_GPIO_LED_WLAN, ++ .active_low = 0, ++ }, +}; + -+static struct gpio_button dir_600_a1_gpio_buttons[] __initdata = { ++static struct gpio_keys_button ap83_gpio_keys[] __initdata = { + { -+ .desc = "reset", ++ .desc = "soft_reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = DIR_600_A1_GPIO_BTN_RESET, ++ .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP83_GPIO_BTN_RESET, + .active_low = 1, + }, { -+ .desc = "wps", ++ .desc = "jumpstart", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = DIR_600_A1_GPIO_BTN_WPS, ++ .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP83_GPIO_BTN_JUMPSTART, + .active_low = 1, + } +}; + -+static void __init dir_600_a1_setup(void) -+{ -+ const char *nvram = (char *) KSEG1ADDR(DIR_600_A1_NVRAM_ADDR); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac_buff[6]; -+ u8 *mac = NULL; -+ -+ if (nvram_parse_mac_addr(nvram, DIR_600_A1_NVRAM_SIZE, -+ "lan_mac=", mac_buff) == 0) -+ mac = mac_buff; ++static struct resource ap83_040_spi_resources[] = { ++ [0] = { ++ .start = AR71XX_SPI_BASE, ++ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; + -+ ar71xx_add_device_m25p80(&dir_600_a1_flash_data); ++static struct platform_device ap83_040_spi_device = { ++ .name = "ap83-spi", ++ .id = 0, ++ .resource = ap83_040_spi_resources, ++ .num_resources = ARRAY_SIZE(ap83_040_spi_resources), ++}; + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_600_a1_leds_gpio), -+ dir_600_a1_leds_gpio); ++static struct spi_gpio_platform_data ap83_050_spi_data = { ++ .miso = AP83_050_GPIO_VSC7385_MISO, ++ .mosi = AP83_050_GPIO_VSC7385_MOSI, ++ .sck = AP83_050_GPIO_VSC7385_SCK, ++ .num_chipselect = 1, ++}; + -+ ar71xx_add_device_gpio_buttons(-1, DIR_600_A1_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(dir_600_a1_gpio_buttons), -+ dir_600_a1_gpio_buttons); ++static struct platform_device ap83_050_spi_device = { ++ .name = "spi_gpio", ++ .id = 0, ++ .dev = { ++ .platform_data = &ap83_050_spi_data, ++ } ++}; + -+ ap91_eth_init(mac, NULL); -+ ap91_pci_init(ee, mac); ++static void ap83_vsc7385_reset(void) ++{ ++ ar71xx_device_stop(RESET_MODULE_GE1_PHY); ++ udelay(10); ++ ar71xx_device_start(RESET_MODULE_GE1_PHY); ++ mdelay(50); +} + -+MIPS_MACHINE(AR71XX_MACH_DIR_600_A1, "DIR-600-A1", "D-Link DIR-600 rev. A1", -+ dir_600_a1_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,173 @@ -+/* -+ * D-Link DIR-615 rev C1 board support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published ++static struct vsc7385_platform_data ap83_vsc7385_data = { ++ .reset = ap83_vsc7385_reset, ++ .ucode_name = "vsc7385_ucode_ap83.bin", ++ .mac_cfg = { ++ .tx_ipg = 6, ++ .bit2 = 0, ++ .clk_sel = 3, ++ }, ++}; ++ ++static struct spi_board_info ap83_spi_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "spi-vsc7385", ++ .platform_data = &ap83_vsc7385_data, ++ .controller_data = (void *) AP83_050_GPIO_VSC7385_CS, ++ } ++}; ++ ++static void __init ap83_generic_setup(void) ++{ ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ ++ ar71xx_add_device_mdio(0xfffffffe); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = 0x1; ++ ++ ar71xx_add_device_eth(0); ++ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ++ ar71xx_eth1_pll_data.pll_1000 = 0x1f000000; ++ ++ ar71xx_add_device_eth(1); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio), ++ ap83_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, AP83_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap83_gpio_keys), ++ ap83_gpio_keys); ++ ++ ar71xx_add_device_usb(); ++ ++ ar9xxx_add_device_wmac(eeprom, NULL); ++ ++ platform_device_register(&ap83_flash_device); ++ ++ spi_register_board_info(ap83_spi_info, ARRAY_SIZE(ap83_spi_info)); ++} ++ ++static void __init ap83_040_setup(void) ++{ ++ ap83_flash_data.is_shared = 1; ++ ap83_generic_setup(); ++ platform_device_register(&ap83_040_spi_device); ++} ++ ++static void __init ap83_050_setup(void) ++{ ++ ap83_generic_setup(); ++ platform_device_register(&ap83_050_spi_device); ++} ++ ++static void __init ap83_setup(void) ++{ ++ u8 *board_id = (u8 *) KSEG1ADDR(0x1fff1244); ++ unsigned int board_version; ++ ++ board_version = (unsigned int)(board_id[0] - '0'); ++ board_version += ((unsigned int)(board_id[1] - '0')) * 10; ++ ++ switch (board_version) { ++ case 40: ++ ap83_040_setup(); ++ break; ++ case 50: ++ ap83_050_setup(); ++ break; ++ default: ++ printk(KERN_WARNING "AP83-%03u board is not yet supported\n", ++ board_version); ++ } ++} ++ ++MIPS_MACHINE(AR71XX_MACH_AP83, "AP83", "Atheros AP83", ap83_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap96.c linux-2.6.39/arch/mips/ar71xx/mach-ap96.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap96.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ap96.c 2011-08-24 02:41:55.477989660 +0200 +@@ -0,0 +1,180 @@ ++/* ++ * Atheros AP96 board support ++ * ++ * Copyright (C) 2009 Marco Porsch ++ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2010 Atheros Communications ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include +#include +#include ++#include + +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ar913x-wmac.h" ++#include "dev-ap94-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "nvram.h" -+ -+#define DIR_615C1_GPIO_LED_ORANGE_STATUS 1 /* ORANGE:STATUS:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_BLUE_WPS 3 /* BLUE:WPS */ -+#define DIR_615C1_GPIO_LED_GREEN_WAN 4 /* GREEN:WAN:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_GREEN_WANCPU 5 /* GREEN:WAN:CPU:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_GREEN_WLAN 6 /* GREEN:WLAN */ -+#define DIR_615C1_GPIO_LED_GREEN_STATUS 14 /* GREEN:STATUS:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_ORANGE_WAN 15 /* ORANGE:WAN:TRICOLOR */ ++#include "dev-usb.h" + -+/* buttons may need refinement */ ++#define AP96_GPIO_LED_12_GREEN 0 ++#define AP96_GPIO_LED_3_GREEN 1 ++#define AP96_GPIO_LED_2_GREEN 2 ++#define AP96_GPIO_LED_WPS_GREEN 4 ++#define AP96_GPIO_LED_5_GREEN 5 ++#define AP96_GPIO_LED_4_ORANGE 6 + -+#define DIR_615C1_GPIO_BTN_WPS 12 -+#define DIR_615C1_GPIO_BTN_RESET 21 ++/* Reset button - next to the power connector */ ++#define AP96_GPIO_BTN_RESET 3 ++/* WPS button - next to a led on right */ ++#define AP96_GPIO_BTN_WPS 8 + -+#define DIR_615C1_BUTTONS_POLL_INTERVAL 20 ++#define AP96_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define AP96_KEYS_DEBOUNCE_INTERVAL (3 * AP96_KEYS_POLL_INTERVAL) + -+#define DIR_615C1_CONFIG_ADDR 0x1f020000 -+#define DIR_615C1_CONFIG_SIZE 0x10000 ++#define AP96_WMAC0_MAC_OFFSET 0x120c ++#define AP96_WMAC1_MAC_OFFSET 0x520c ++#define AP96_CALDATA0_OFFSET 0x1000 ++#define AP96_CALDATA1_OFFSET 0x5000 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition dir_615c1_partitions[] = { ++static struct mtd_partition ap96_partitions[] = { + { -+ .name = "u-boot", ++ .name = "uboot", + .offset = 0, -+ .size = 0x020000, ++ .size = 0x030000, + .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "config", -+ .offset = 0x020000, -+ .size = 0x010000, -+ } , { -+ .name = "kernel", ++ }, { ++ .name = "env", + .offset = 0x030000, -+ .size = 0x0d0000, -+ } , { ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { + .name = "rootfs", -+ .offset = 0x100000, -+ .size = 0x2f0000, -+ } , { -+ .name = "art", -+ .offset = 0x3f0000, ++ .offset = 0x040000, ++ .size = 0x600000, ++ }, { ++ .name = "uImage", ++ .offset = 0x640000, ++ .size = 0x1b0000, ++ }, { ++ .name = "caldata", ++ .offset = 0x7f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "firmware", -+ .offset = 0x030000, -+ .size = 0x3c0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data dir_615c1_flash_data = { ++static struct flash_platform_data ap96_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = dir_615c1_partitions, -+ .nr_parts = ARRAY_SIZE(dir_615c1_partitions), ++ .parts = ap96_partitions, ++ .nr_parts = ARRAY_SIZE(ap96_partitions), +#endif +}; + -+static struct gpio_led dir_615c1_leds_gpio[] __initdata = { ++/* ++ * AP96 has 12 unlabeled leds in the front; these are numbered from 1 to 12 ++ * below (from left to right on the board). Led 1 seems to be on whenever the ++ * board is powered. Led 11 shows LAN link activity actity. Led 3 is orange; ++ * others are green. ++ * ++ * In addition, there is one led next to a button on the right side for WPS. ++ */ ++static struct gpio_led ap96_leds_gpio[] __initdata = { + { -+ .name = "dir-615c1:orange:status", -+ .gpio = DIR_615C1_GPIO_LED_ORANGE_STATUS, ++ .name = "ap96:green:led2", ++ .gpio = AP96_GPIO_LED_2_GREEN, + .active_low = 1, + }, { -+ .name = "dir-615c1:blue:wps", -+ .gpio = DIR_615C1_GPIO_LED_BLUE_WPS, ++ .name = "ap96:green:led3", ++ .gpio = AP96_GPIO_LED_3_GREEN, + .active_low = 1, + }, { -+ .name = "dir-615c1:green:wan", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_WAN, ++ .name = "ap96:orange:led4", ++ .gpio = AP96_GPIO_LED_4_ORANGE, + .active_low = 1, + }, { -+ .name = "dir-615c1:green:wancpu", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_WANCPU, -+ .active_low = 1, -+ }, { -+ .name = "dir-615c1:green:wlan", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_WLAN, ++ .name = "ap96:green:led5", ++ .gpio = AP96_GPIO_LED_5_GREEN, + .active_low = 1, -+ }, { -+ .name = "dir-615c1:green:status", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_STATUS, -+ .active_low = 1, + }, { -+ .name = "dir-615c1:orange:wan", -+ .gpio = DIR_615C1_GPIO_LED_ORANGE_WAN, ++ .name = "ap96:green:led12", ++ .gpio = AP96_GPIO_LED_12_GREEN, ++ .active_low = 1, ++ }, { /* next to a button on right */ ++ .name = "ap96:green:wps", ++ .gpio = AP96_GPIO_LED_WPS_GREEN, + .active_low = 1, + } -+ +}; + -+static struct gpio_button dir_615c1_gpio_buttons[] __initdata = { ++static struct gpio_keys_button ap96_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = DIR_615C1_GPIO_BTN_RESET, ++ .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP96_GPIO_BTN_RESET, ++ .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = DIR_615C1_GPIO_BTN_WPS, ++ .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP96_GPIO_BTN_WPS, ++ .active_low = 1, + } +}; + -+#define DIR_615C1_LAN_PHYMASK BIT(0) -+#define DIR_615C1_WAN_PHYMASK BIT(4) -+#define DIR_615C1_MDIO_MASK (~(DIR_615C1_LAN_PHYMASK | \ -+ DIR_615C1_WAN_PHYMASK)) ++#define AP96_WAN_PHYMASK 0x10 ++#define AP96_LAN_PHYMASK 0x0f + -+static void __init dir_615c1_setup(void) ++static void __init ap96_setup(void) +{ -+ const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[6]; -+ u8 *wlan_mac = NULL; ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + -+ if (nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE, -+ "lan_mac=", mac) == 0) { -+ ar71xx_set_mac_base(mac); -+ wlan_mac = mac; -+ } ++ ar71xx_add_device_mdio(~(AP96_WAN_PHYMASK | AP96_LAN_PHYMASK)); + -+ ar71xx_add_device_mdio(DIR_615C1_MDIO_MASK); ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, art, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = AP96_LAN_PHYMASK; ++ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.phy_mask = DIR_615C1_LAN_PHYMASK; ++ ar71xx_add_device_eth(0); + -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = DIR_615C1_WAN_PHYMASK; ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, art, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = AP96_WAN_PHYMASK; ++ ++ ar71xx_eth1_pll_data.pll_1000 = 0x1f000000; + -+ ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_m25p80(&dir_615c1_flash_data); ++ ar71xx_add_device_usb(); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_615c1_leds_gpio), -+ dir_615c1_leds_gpio); ++ ar71xx_add_device_m25p80(&ap96_flash_data); + -+ ar71xx_add_device_gpio_buttons(-1, DIR_615C1_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(dir_615c1_gpio_buttons), -+ dir_615c1_gpio_buttons); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap96_leds_gpio), ++ ap96_leds_gpio); + -+ ar913x_add_device_wmac(eeprom, wlan_mac); ++ ar71xx_register_gpio_keys_polled(-1, AP96_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap96_gpio_keys), ++ ap96_gpio_keys); ++ ++ ap94_pci_init(art + AP96_CALDATA0_OFFSET, ++ art + AP96_WMAC0_MAC_OFFSET, ++ art + AP96_CALDATA1_OFFSET, ++ art + AP96_WMAC1_MAC_OFFSET); +} + -+MIPS_MACHINE(AR71XX_MACH_DIR_615_C1, "DIR-615-C1", "D-Link DIR-615 rev. C1", -+ dir_615c1_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,192 @@ ++MIPS_MACHINE(AR71XX_MACH_AP96, "AP96", "Atheros AP96", ap96_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c 2011-08-24 02:41:55.487989871 +0200 +@@ -0,0 +1,102 @@ +/* -+ * D-Link DIR-825 rev. B1 board support -+ * -+ * Copyright (C) 2009 Lukas Kuna, Evkanet, s.r.o. ++ * AzureWave AW-NR580 board support + * -+ * based on mach-wndr3700.c ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include +#include +#include -+#include -+#include + ++#include +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ap94-pci.h" +#include "dev-gpio-buttons.h" ++#include "dev-pb42-pci.h" +#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+ -+#define DIR825B1_GPIO_LED_BLUE_USB 0 -+#define DIR825B1_GPIO_LED_ORANGE_POWER 1 -+#define DIR825B1_GPIO_LED_BLUE_POWER 2 -+#define DIR825B1_GPIO_LED_BLUE_POWERSAVE 4 -+#define DIR825B1_GPIO_LED_ORANGE_PLANET 6 -+#define DIR825B1_GPIO_LED_BLUE_PLANET 11 -+ -+#define DIR825B1_GPIO_BTN_RESET 3 -+#define DIR825B1_GPIO_BTN_POWERSAVE 8 + -+#define DIR825B1_GPIO_RTL8366_SDA 5 -+#define DIR825B1_GPIO_RTL8366_SCK 7 -+ -+#define DIR825B1_BUTTONS_POLL_INTERVAL 20 ++#define AW_NR580_GPIO_LED_READY_RED 0 ++#define AW_NR580_GPIO_LED_WLAN 1 ++#define AW_NR580_GPIO_LED_READY_GREEN 2 ++#define AW_NR580_GPIO_LED_WPS_GREEN 4 ++#define AW_NR580_GPIO_LED_WPS_AMBER 5 + -+#define DIR825B1_CAL_LOCATION_0 0x1f661000 -+#define DIR825B1_CAL_LOCATION_1 0x1f665000 ++#define AW_NR580_GPIO_BTN_WPS 3 ++#define AW_NR580_GPIO_BTN_RESET 11 + -+#define DIR825B1_MAC_LOCATION_0 0x2ffa81b8 -+#define DIR825B1_MAC_LOCATION_1 0x2ffa8370 ++#define AW_NR580_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define AW_NR580_KEYS_DEBOUNCE_INTERVAL (3 * AW_NR580_KEYS_POLL_INTERVAL) + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition dir825b1_partitions[] = { ++static struct gpio_led aw_nr580_leds_gpio[] __initdata = { + { -+ .name = "uboot", -+ .offset = 0, -+ .size = 0x040000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "config", -+ .offset = 0x040000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "firmware", -+ .offset = 0x050000, -+ .size = 0x610000, -+ } , { -+ .name = "caldata", -+ .offset = 0x660000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "unknown", -+ .offset = 0x670000, -+ .size = 0x190000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ -+ -+static struct flash_platform_data dir825b1_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = dir825b1_partitions, -+ .nr_parts = ARRAY_SIZE(dir825b1_partitions), -+#endif -+}; -+ -+static struct gpio_led dir825b1_leds_gpio[] __initdata = { -+ { -+ .name = "dir825b1:blue:usb", -+ .gpio = DIR825B1_GPIO_LED_BLUE_USB, -+ .active_low = 1, -+ }, { -+ .name = "dir825b1:orange:power", -+ .gpio = DIR825B1_GPIO_LED_ORANGE_POWER, -+ .active_low = 1, ++ .name = "aw-nr580:red:ready", ++ .gpio = AW_NR580_GPIO_LED_READY_RED, ++ .active_low = 0, + }, { -+ .name = "dir825b1:blue:power", -+ .gpio = DIR825B1_GPIO_LED_BLUE_POWER, -+ .active_low = 1, ++ .name = "aw-nr580:green:ready", ++ .gpio = AW_NR580_GPIO_LED_READY_GREEN, ++ .active_low = 0, + }, { -+ .name = "dir825b1:blue:powersave", -+ .gpio = DIR825B1_GPIO_LED_BLUE_POWERSAVE, -+ .active_low = 1, ++ .name = "aw-nr580:green:wps", ++ .gpio = AW_NR580_GPIO_LED_WPS_GREEN, ++ .active_low = 0, + }, { -+ .name = "dir825b1:orange:planet", -+ .gpio = DIR825B1_GPIO_LED_ORANGE_PLANET, -+ .active_low = 1, ++ .name = "aw-nr580:amber:wps", ++ .gpio = AW_NR580_GPIO_LED_WPS_AMBER, ++ .active_low = 0, + }, { -+ .name = "dir825b1:blue:planet", -+ .gpio = DIR825B1_GPIO_LED_BLUE_PLANET, -+ .active_low = 1, ++ .name = "aw-nr580:green:wlan", ++ .gpio = AW_NR580_GPIO_LED_WLAN, ++ .active_low = 0, + } +}; + -+static struct gpio_button dir825b1_gpio_buttons[] __initdata = { ++static struct gpio_keys_button aw_nr580_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = DIR825B1_GPIO_BTN_RESET, ++ .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AW_NR580_GPIO_BTN_RESET, + .active_low = 1, -+ } , { -+ .desc = "powersave", ++ }, { ++ .desc = "wps", + .type = EV_KEY, -+ .code = BTN_1, -+ .threshold = 3, -+ .gpio = DIR825B1_GPIO_BTN_POWERSAVE, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AW_NR580_GPIO_BTN_WPS, + .active_low = 1, + } +}; + -+static struct rtl8366s_platform_data dir825b1_rtl8366s_data = { -+ .gpio_sda = DIR825B1_GPIO_RTL8366_SDA, -+ .gpio_sck = DIR825B1_GPIO_RTL8366_SCK, -+}; -+ -+static struct platform_device dir825b1_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &dir825b1_rtl8366s_data, -+ } -+}; -+ -+static void __init dir825b1_setup(void) ++static void __init aw_nr580_setup(void) +{ -+ u8 mac[6], i; -+ -+ memcpy(mac, (u8*)KSEG1ADDR(DIR825B1_MAC_LOCATION_1), 6); -+ for(i = 5; i >= 3; i--) -+ if(++mac[i] != 0x00) break; -+ -+ ar71xx_set_mac_base(mac); -+ + ar71xx_add_device_mdio(0x0); + -+ ar71xx_eth0_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_pll_data.pll_1000 = 0x11110000; -+ -+ ar71xx_eth1_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = 0x10; -+ ar71xx_eth1_pll_data.pll_1000 = 0x11110000; + + ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); -+ -+ ar71xx_add_device_m25p80(&dir825b1_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir825b1_leds_gpio), -+ dir825b1_leds_gpio); + -+ ar71xx_add_device_gpio_buttons(-1, DIR825B1_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(dir825b1_gpio_buttons), -+ dir825b1_gpio_buttons); ++ pb42_pci_init(); + -+ ar71xx_add_device_usb(); ++ ar71xx_add_device_m25p80(NULL); + -+ platform_device_register(&dir825b1_rtl8366s_device); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio), ++ aw_nr580_leds_gpio); + -+ ap94_pci_init((u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_0), -+ (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_0), -+ (u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_1), -+ (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1)); ++ ar71xx_register_gpio_keys_polled(-1, AW_NR580_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(aw_nr580_gpio_keys), ++ aw_nr580_gpio_keys); +} + -+MIPS_MACHINE(AR71XX_MACH_DIR_825_B1, "DIR-825-B1", "D-Link DIR-825 rev. B1", -+ dir825b1_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,165 @@ ++MIPS_MACHINE(AR71XX_MACH_AW_NR580, "AW-NR580", "AzureWave AW-NR580", ++ aw_nr580_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-db120.c linux-2.6.39/arch/mips/ar71xx/mach-db120.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-db120.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-db120.c 2011-08-24 02:41:55.487989871 +0200 +@@ -0,0 +1,134 @@ +/* -+ * Planex MZK-W04NU board support ++ * Atheros DB120 board (WASP SoC) support + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -3941,163 +4292,131 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.39/arch/ + +#include "machtype.h" +#include "devices.h" -+#include "dev-ar913x-wmac.h" ++#include "dev-m25p80.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" +#include "dev-usb.h" ++#include "dev-ar9xxx-wmac.h" ++#include "dev-db120-pci.h" + -+#define MZK_W04NU_GPIO_LED_USB 0 -+#define MZK_W04NU_GPIO_LED_STATUS 1 -+#define MZK_W04NU_GPIO_LED_WPS 3 -+#define MZK_W04NU_GPIO_LED_WLAN 6 -+#define MZK_W04NU_GPIO_LED_AP 15 -+#define MZK_W04NU_GPIO_LED_ROUTER 16 ++#define DB120_GPIO_LED_USB 11 ++#define DB120_GPIO_LED_WLAN_5G 12 ++#define DB120_GPIO_LED_WLAN_2G 13 ++#define DB120_GPIO_LED_STATUS 14 ++#define DB120_GPIO_LED_WPS 15 + -+#define MZK_W04NU_GPIO_BTN_APROUTER 5 -+#define MZK_W04NU_GPIO_BTN_WPS 12 -+#define MZK_W04NU_GPIO_BTN_RESET 21 ++#define DB120_GPIO_BTN_SW1 16 + -+#define MZK_W04NU_BUTTONS_POLL_INTERVAL 20 ++#define DB120_CALDATA_OFFSET 0x1000 ++#define DB120_WMAC_MAC_OFFSET 0x1002 ++ ++#define DB120_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL) + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition mzk_w04nu_partitions[] = { ++static struct mtd_partition db120_partitions[] = { + { + .name = "u-boot", + .offset = 0, + .size = 0x040000, + .mask_flags = MTD_WRITEABLE, -+ } , { ++ }, { + .name = "u-boot-env", + .offset = 0x040000, + .size = 0x010000, -+ } , { -+ .name = "kernel", -+ .offset = 0x050000, -+ .size = 0x160000, -+ } , { ++ }, { + .name = "rootfs", -+ .offset = 0x1b0000, ++ .offset = 0x050000, + .size = 0x630000, -+ } , { -+ .name = "art", -+ .offset = 0x7e0000, -+ .size = 0x020000, ++ }, { ++ .name = "uImage", ++ .offset = 0x680000, ++ .size = 0x160000, ++ }, { ++ .name = "NVRAM", ++ .offset = 0x7E0000, ++ .size = 0x010000, ++ }, { ++ .name = "ART", ++ .offset = 0x7F0000, ++ .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "firmware", -+ .offset = 0x050000, -+ .size = 0x790000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data mzk_w04nu_flash_data = { ++static struct flash_platform_data db120_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = mzk_w04nu_partitions, -+ .nr_parts = ARRAY_SIZE(mzk_w04nu_partitions), ++ .parts = db120_partitions, ++ .nr_parts = ARRAY_SIZE(db120_partitions), +#endif +}; + -+static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = { ++static struct gpio_led db120_leds_gpio[] __initdata = { + { -+ .name = "mzk-w04nu:green:status", -+ .gpio = MZK_W04NU_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "mzk-w04nu:blue:wps", -+ .gpio = MZK_W04NU_GPIO_LED_WPS, ++ .name = "db120:green:status", ++ .gpio = DB120_GPIO_LED_STATUS, + .active_low = 1, + }, { -+ .name = "mzk-w04nu:green:wlan", -+ .gpio = MZK_W04NU_GPIO_LED_WLAN, ++ .name = "db120:green:wps", ++ .gpio = DB120_GPIO_LED_WPS, + .active_low = 1, + }, { -+ .name = "mzk-w04nu:green:usb", -+ .gpio = MZK_W04NU_GPIO_LED_USB, ++ .name = "db120:green:wlan-5g", ++ .gpio = DB120_GPIO_LED_WLAN_5G, + .active_low = 1, + }, { -+ .name = "mzk-w04nu:green:ap", -+ .gpio = MZK_W04NU_GPIO_LED_AP, ++ .name = "db120:green:wlan-2g", ++ .gpio = DB120_GPIO_LED_WLAN_2G, + .active_low = 1, + }, { -+ .name = "mzk-w04nu:green:router", -+ .gpio = MZK_W04NU_GPIO_LED_ROUTER, ++ .name = "db120:green:usb", ++ .gpio = DB120_GPIO_LED_USB, + .active_low = 1, + } +}; + -+static struct gpio_button mzk_w04nu_gpio_buttons[] __initdata = { ++static struct gpio_keys_button db120_gpio_keys[] __initdata = { + { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = MZK_W04NU_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", ++ .desc = "sw1", + .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = MZK_W04NU_GPIO_BTN_WPS, ++ .code = BTN_0, ++ .debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DB120_GPIO_BTN_SW1, + .active_low = 1, -+ }, { -+ .desc = "aprouter", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .threshold = 3, -+ .gpio = MZK_W04NU_GPIO_BTN_APROUTER, -+ .active_low = 0, + } +}; + -+#define MZK_W04NU_WAN_PHYMASK BIT(4) -+#define MZK_W04NU_MDIO_MASK (~MZK_W04NU_WAN_PHYMASK) -+ -+static void __init mzk_w04nu_setup(void) ++static void __init db120_setup(void) +{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ar71xx_set_mac_base(eeprom); -+ -+ ar71xx_add_device_mdio(MZK_W04NU_MDIO_MASK); -+ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.has_ar8216 = 1; ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = MZK_W04NU_WAN_PHYMASK; ++ ar71xx_add_device_usb(); + -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); ++ ar71xx_add_device_m25p80(&db120_flash_data); + -+ ar71xx_add_device_m25p80(&mzk_w04nu_flash_data); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio), ++ db120_leds_gpio); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio), -+ mzk_w04nu_leds_gpio); ++ ar71xx_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(db120_gpio_keys), ++ db120_gpio_keys); + -+ ar71xx_add_device_gpio_buttons(-1, MZK_W04NU_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(mzk_w04nu_gpio_buttons), -+ mzk_w04nu_gpio_buttons); -+ ar71xx_add_device_usb(); ++ ar9xxx_add_device_wmac(art + DB120_CALDATA_OFFSET, ++ art + DB120_WMAC_MAC_OFFSET); + -+ ar913x_add_device_wmac(eeprom, NULL); ++ db120_pci_init(); +} + -+MIPS_MACHINE(AR71XX_MACH_MZK_W04NU, "MZK-W04NU", "Planex MZK-W04NU", -+ mzk_w04nu_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,158 @@ ++MIPS_MACHINE(AR71XX_MACH_DB120, "DB120", "Atheros DB120", db120_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c 2011-08-24 02:41:55.487989871 +0200 +@@ -0,0 +1,159 @@ +/* -+ * Planex MZK-W300NH board support ++ * D-Link DIR-600 rev. A1 board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -4112,1641 +4431,1772 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c linux-2.6.39/arch +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ar913x-wmac.h" ++#include "dev-ap91-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "nvram.h" + -+#define MZK_W300NH_GPIO_LED_STATUS 1 -+#define MZK_W300NH_GPIO_LED_WPS 3 -+#define MZK_W300NH_GPIO_LED_WLAN 6 -+#define MZK_W300NH_GPIO_LED_AP 15 -+#define MZK_W300NH_GPIO_LED_ROUTER 16 ++#define DIR_600_A1_GPIO_LED_WPS 0 ++#define DIR_600_A1_GPIO_LED_POWER_AMBER 1 ++#define DIR_600_A1_GPIO_LED_POWER_GREEN 6 + -+#define MZK_W300NH_GPIO_BTN_APROUTER 5 -+#define MZK_W300NH_GPIO_BTN_WPS 12 -+#define MZK_W300NH_GPIO_BTN_RESET 21 ++#define DIR_600_A1_GPIO_BTN_RESET 8 ++#define DIR_600_A1_GPIO_BTN_WPS 12 + -+#define MZK_W04NU_BUTTONS_POLL_INTERVAL 20 ++#define DIR_600_A1_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define DIR_600_A1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_600_A1_KEYS_POLL_INTERVAL) ++ ++#define DIR_600_A1_NVRAM_ADDR 0x1f030000 ++#define DIR_600_A1_NVRAM_SIZE 0x10000 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition mzk_w300nh_partitions[] = { ++static struct mtd_partition dir_600_a1_partitions[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x040000, ++ .size = 0x030000, + .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "u-boot-env", -+ .offset = 0x040000, ++ }, { ++ .name = "nvram", ++ .offset = 0x030000, + .size = 0x010000, -+ } , { ++ }, { + .name = "kernel", -+ .offset = 0x050000, -+ .size = 0x160000, -+ } , { ++ .offset = 0x040000, ++ .size = 0x0e0000, ++ }, { + .name = "rootfs", -+ .offset = 0x1b0000, -+ .size = 0x630000, -+ } , { ++ .offset = 0x120000, ++ .size = 0x2c0000, ++ }, { ++ .name = "mac", ++ .offset = 0x3e0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { + .name = "art", -+ .offset = 0x7e0000, -+ .size = 0x020000, ++ .offset = 0x3f0000, ++ .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ } , { ++ }, { + .name = "firmware", -+ .offset = 0x050000, -+ .size = 0x790000, ++ .offset = 0x040000, ++ .size = 0x3a0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data mzk_w300nh_flash_data = { ++static struct flash_platform_data dir_600_a1_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = mzk_w300nh_partitions, -+ .nr_parts = ARRAY_SIZE(mzk_w300nh_partitions), ++ .parts = dir_600_a1_partitions, ++ .nr_parts = ARRAY_SIZE(dir_600_a1_partitions), +#endif +}; + -+static struct gpio_led mzk_w300nh_leds_gpio[] __initdata = { ++static struct gpio_led dir_600_a1_leds_gpio[] __initdata = { + { -+ .name = "mzk-w300nh:green:status", -+ .gpio = MZK_W300NH_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "mzk-w300nh:blue:wps", -+ .gpio = MZK_W300NH_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "mzk-w300nh:green:wlan", -+ .gpio = MZK_W300NH_GPIO_LED_WLAN, -+ .active_low = 1, ++ .name = "dir-600-a1:green:power", ++ .gpio = DIR_600_A1_GPIO_LED_POWER_GREEN, + }, { -+ .name = "mzk-w300nh:green:ap", -+ .gpio = MZK_W300NH_GPIO_LED_AP, -+ .active_low = 1, ++ .name = "dir-600-a1:amber:power", ++ .gpio = DIR_600_A1_GPIO_LED_POWER_AMBER, + }, { -+ .name = "mzk-w300nh:green:router", -+ .gpio = MZK_W300NH_GPIO_LED_ROUTER, ++ .name = "dir-600-a1:blue:wps", ++ .gpio = DIR_600_A1_GPIO_LED_WPS, + .active_low = 1, + } +}; + -+static struct gpio_button mzk_w300nh_gpio_buttons[] __initdata = { ++static struct gpio_keys_button dir_600_a1_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = MZK_W300NH_GPIO_BTN_RESET, ++ .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR_600_A1_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = MZK_W300NH_GPIO_BTN_WPS, ++ .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR_600_A1_GPIO_BTN_WPS, + .active_low = 1, -+ }, { -+ .desc = "aprouter", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .threshold = 3, -+ .gpio = MZK_W300NH_GPIO_BTN_APROUTER, -+ .active_low = 0, + } +}; + -+#define MZK_W300NH_WAN_PHYMASK BIT(4) -+#define MZK_W300NH_MDIO_MASK (~MZK_W300NH_WAN_PHYMASK) -+ -+static void __init mzk_w300nh_setup(void) ++static void __init dir_600_a1_setup(void) +{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ const char *nvram = (char *) KSEG1ADDR(DIR_600_A1_NVRAM_ADDR); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 mac_buff[6]; ++ u8 *mac = NULL; ++ ++ if (nvram_parse_mac_addr(nvram, DIR_600_A1_NVRAM_SIZE, ++ "lan_mac=", mac_buff) == 0) { ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac_buff, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac_buff, 1); ++ mac = mac_buff; ++ } + -+ ar71xx_set_mac_base(eeprom); ++ ar71xx_add_device_m25p80(&dir_600_a1_flash_data); + -+ ar71xx_add_device_mdio(MZK_W300NH_MDIO_MASK); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_600_a1_leds_gpio), ++ dir_600_a1_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, DIR_600_A1_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(dir_600_a1_gpio_keys), ++ dir_600_a1_gpio_keys); + ++ ar71xx_eth1_data.has_ar7240_switch = 1; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ ++ /* WAN port */ + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.has_ar8216 = 1; ++ ar71xx_eth0_data.phy_mask = BIT(4); + ++ /* LAN ports */ + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = MZK_W300NH_WAN_PHYMASK; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; + -+ ar71xx_add_device_eth(0); ++ ar71xx_add_device_mdio(0x0); + ar71xx_add_device_eth(1); ++ ar71xx_add_device_eth(0); + -+ ar71xx_add_device_m25p80(&mzk_w300nh_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w300nh_leds_gpio), -+ mzk_w300nh_leds_gpio); -+ -+ ar71xx_add_device_gpio_buttons(-1, MZK_W04NU_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(mzk_w300nh_gpio_buttons), -+ mzk_w300nh_gpio_buttons); -+ ar913x_add_device_wmac(eeprom, NULL); ++ ap91_pci_init(ee, mac); +} + -+MIPS_MACHINE(AR71XX_MACH_MZK_W300NH, "MZK-W300NH", "Planex MZK-W300NH", -+ mzk_w300nh_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,222 @@ ++MIPS_MACHINE(AR71XX_MACH_DIR_600_A1, "DIR-600-A1", "D-Link DIR-600 rev. A1", ++ dir_600_a1_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c 2011-08-24 02:41:55.487989871 +0200 +@@ -0,0 +1,175 @@ +/* -+ * Zyxel NBG 460N/550N/550NH board support -+ * -+ * Copyright (C) 2010 Michael Kurz ++ * D-Link DIR-615 rev C1 board support + * -+ * based on mach-tl-wr1043nd.c ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include +#include +#include -+#include -+#include -+ -+#include -+#include -+#include + +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ar913x-wmac.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "nvram.h" + -+/* LEDs */ -+#define NBG460N_GPIO_LED_WPS 3 -+#define NBG460N_GPIO_LED_WAN 6 -+#define NBG460N_GPIO_LED_POWER 14 -+#define NBG460N_GPIO_LED_WLAN 15 ++#define DIR_615C1_GPIO_LED_ORANGE_STATUS 1 /* ORANGE:STATUS:TRICOLOR */ ++#define DIR_615C1_GPIO_LED_BLUE_WPS 3 /* BLUE:WPS */ ++#define DIR_615C1_GPIO_LED_GREEN_WAN 4 /* GREEN:WAN:TRICOLOR */ ++#define DIR_615C1_GPIO_LED_GREEN_WANCPU 5 /* GREEN:WAN:CPU:TRICOLOR */ ++#define DIR_615C1_GPIO_LED_GREEN_WLAN 6 /* GREEN:WLAN */ ++#define DIR_615C1_GPIO_LED_GREEN_STATUS 14 /* GREEN:STATUS:TRICOLOR */ ++#define DIR_615C1_GPIO_LED_ORANGE_WAN 15 /* ORANGE:WAN:TRICOLOR */ + -+/* Buttons */ -+#define NBG460N_GPIO_BTN_WPS 12 -+#define NBG460N_GPIO_BTN_RESET 21 -+#define NBG460N_BUTTONS_POLL_INTERVAL 20 ++/* buttons may need refinement */ + -+/* RTC chip PCF8563 I2C interface */ -+#define NBG460N_GPIO_PCF8563_SDA 8 -+#define NBG460N_GPIO_PCF8563_SCK 7 ++#define DIR_615C1_GPIO_BTN_WPS 12 ++#define DIR_615C1_GPIO_BTN_RESET 21 + -+/* Switch configuration I2C interface */ -+#define NBG460N_GPIO_RTL8366_SDA 16 -+#define NBG460N_GPIO_RTL8366_SCK 18 ++#define DIR_615C1_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define DIR_615C1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_615C1_KEYS_POLL_INTERVAL) ++ ++#define DIR_615C1_CONFIG_ADDR 0x1f020000 ++#define DIR_615C1_CONFIG_SIZE 0x10000 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition nbg460n_partitions[] = { ++static struct mtd_partition dir_615c1_partitions[] = { + { -+ .name = "Bootbase", ++ .name = "u-boot", + .offset = 0, -+ .size = 0x010000, ++ .size = 0x020000, + .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "U-Boot Config", -+ .offset = 0x010000, -+ .size = 0x030000, -+ } , { -+ .name = "U-Boot", -+ .offset = 0x040000, -+ .size = 0x030000, -+ } , { -+ .name = "linux", -+ .offset = 0x070000, ++ }, { ++ .name = "config", ++ .offset = 0x020000, ++ .size = 0x010000, ++ }, { ++ .name = "kernel", ++ .offset = 0x030000, + .size = 0x0e0000, -+ } , { ++ }, { + .name = "rootfs", -+ .offset = 0x150000, -+ .size = 0x2a0000, -+ } , { -+ .name = "CalibData", ++ .offset = 0x110000, ++ .size = 0x2e0000, ++ }, { ++ .name = "art", + .offset = 0x3f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ } , { ++ }, { + .name = "firmware", -+ .offset = 0x070000, -+ .size = 0x380000, ++ .offset = 0x030000, ++ .size = 0x3c0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data nbg460n_flash_data = { ++static struct flash_platform_data dir_615c1_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = nbg460n_partitions, -+ .nr_parts = ARRAY_SIZE(nbg460n_partitions), ++ .parts = dir_615c1_partitions, ++ .nr_parts = ARRAY_SIZE(dir_615c1_partitions), +#endif +}; + -+static struct gpio_led nbg460n_leds_gpio[] __initdata = { ++static struct gpio_led dir_615c1_leds_gpio[] __initdata = { + { -+ .name = "nbg460n:green:power", -+ .gpio = NBG460N_GPIO_LED_POWER, -+ .active_low = 0, -+ .default_trigger = "default-on", ++ .name = "dir-615c1:orange:status", ++ .gpio = DIR_615C1_GPIO_LED_ORANGE_STATUS, ++ .active_low = 1, + }, { -+ .name = "nbg460n:green:wps", -+ .gpio = NBG460N_GPIO_LED_WPS, -+ .active_low = 0, ++ .name = "dir-615c1:blue:wps", ++ .gpio = DIR_615C1_GPIO_LED_BLUE_WPS, ++ .active_low = 1, + }, { -+ .name = "nbg460n:green:wlan", -+ .gpio = NBG460N_GPIO_LED_WLAN, -+ .active_low = 0, ++ .name = "dir-615c1:green:wan", ++ .gpio = DIR_615C1_GPIO_LED_GREEN_WAN, ++ .active_low = 1, + }, { -+ /* Not really for controlling the LED, -+ when set low the LED blinks uncontrollable */ -+ .name = "nbg460n:green:wan", -+ .gpio = NBG460N_GPIO_LED_WAN, -+ .active_low = 0, ++ .name = "dir-615c1:green:wancpu", ++ .gpio = DIR_615C1_GPIO_LED_GREEN_WANCPU, ++ .active_low = 1, ++ }, { ++ .name = "dir-615c1:green:wlan", ++ .gpio = DIR_615C1_GPIO_LED_GREEN_WLAN, ++ .active_low = 1, ++ }, { ++ .name = "dir-615c1:green:status", ++ .gpio = DIR_615C1_GPIO_LED_GREEN_STATUS, ++ .active_low = 1, ++ }, { ++ .name = "dir-615c1:orange:wan", ++ .gpio = DIR_615C1_GPIO_LED_ORANGE_WAN, ++ .active_low = 1, + } ++ +}; + -+static struct gpio_button nbg460n_gpio_buttons[] __initdata = { ++static struct gpio_keys_button dir_615c1_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = NBG460N_GPIO_BTN_RESET, -+ .active_low = 1, ++ .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR_615C1_GPIO_BTN_RESET, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = NBG460N_GPIO_BTN_WPS, -+ .active_low = 1, ++ .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR_615C1_GPIO_BTN_WPS, + } +}; + -+static struct i2c_gpio_platform_data nbg460n_i2c_device_platdata = { -+ .sda_pin = NBG460N_GPIO_PCF8563_SDA, -+ .scl_pin = NBG460N_GPIO_PCF8563_SCK, -+ .udelay = 10, -+}; -+ -+static struct platform_device nbg460n_i2c_device = { -+ .name = "i2c-gpio", -+ .id = -1, -+ .num_resources = 0, -+ .resource = NULL, -+ .dev = { -+ .platform_data = &nbg460n_i2c_device_platdata, -+ }, -+}; -+ -+static struct i2c_board_info nbg460n_i2c_devs[] __initdata = { -+ { -+ I2C_BOARD_INFO("pcf8563", 0x51), -+ }, -+}; ++#define DIR_615C1_LAN_PHYMASK BIT(0) ++#define DIR_615C1_WAN_PHYMASK BIT(4) ++#define DIR_615C1_MDIO_MASK (~(DIR_615C1_LAN_PHYMASK | \ ++ DIR_615C1_WAN_PHYMASK)) + -+static void __devinit nbg460n_i2c_init(void) ++static void __init dir_615c1_setup(void) +{ -+ /* The gpio interface */ -+ platform_device_register(&nbg460n_i2c_device); -+ /* I2C devices */ -+ i2c_register_board_info(0, nbg460n_i2c_devs, -+ ARRAY_SIZE(nbg460n_i2c_devs)); -+} -+ -+ -+static struct rtl8366s_platform_data nbg460n_rtl8366s_data = { -+ .gpio_sda = NBG460N_GPIO_RTL8366_SDA, -+ .gpio_sck = NBG460N_GPIO_RTL8366_SCK, -+}; ++ const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR); ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 mac[6]; ++ u8 *wlan_mac = NULL; + -+static struct platform_device nbg460n_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &nbg460n_rtl8366s_data, ++ if (nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE, ++ "lan_mac=", mac) == 0) { ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ wlan_mac = mac; + } -+}; + -+static void __init nbg460n_setup(void) -+{ -+ /* end of bootloader sector contains mac address*/ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fc0fff8); -+ /* last sector contains wlan calib data */ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ ar71xx_add_device_mdio(DIR_615C1_MDIO_MASK); + -+ ar71xx_set_mac_base(mac); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.phy_mask = DIR_615C1_LAN_PHYMASK; + -+ /* LAN Port */ -+ ar71xx_eth0_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.speed = SPEED_1000; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ -+ /* WAN Port */ -+ ar71xx_eth1_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = DIR_615C1_WAN_PHYMASK; + + ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ /* register the switch phy */ -+ platform_device_register(&nbg460n_rtl8366s_device); -+ -+ /* register flash */ -+ ar71xx_add_device_m25p80(&nbg460n_flash_data); -+ -+ ar913x_add_device_wmac(eeprom, mac); ++ ar71xx_add_device_m25p80(&dir_615c1_flash_data); + -+ /* register RTC chip */ -+ nbg460n_i2c_init(); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_615c1_leds_gpio), ++ dir_615c1_leds_gpio); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(nbg460n_leds_gpio), -+ nbg460n_leds_gpio); ++ ar71xx_register_gpio_keys_polled(-1, DIR_615C1_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(dir_615c1_gpio_keys), ++ dir_615c1_gpio_keys); + -+ ar71xx_add_device_gpio_buttons(-1, NBG460N_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(nbg460n_gpio_buttons), -+ nbg460n_gpio_buttons); ++ ar9xxx_add_device_wmac(eeprom, wlan_mac); +} + -+MIPS_MACHINE(AR71XX_MACH_NBG460N, "NBG460N", "Zyxel NBG460N/550N/550NH", nbg460n_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c linux-2.6.39/arch/mips/ar71xx/mach-pb42.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-pb42.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,71 @@ ++MIPS_MACHINE(AR71XX_MACH_DIR_615_C1, "DIR-615-C1", "D-Link DIR-615 rev. C1", ++ dir_615c1_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c 2011-08-24 02:41:55.487989871 +0200 +@@ -0,0 +1,198 @@ +/* -+ * Atheros PB42 board support ++ * D-Link DIR-825 rev. B1 board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009 Lukas Kuna, Evkanet, s.r.o. ++ * ++ * based on mach-wndr3700.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include ++#include ++#include ++#include ++#include ++ +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" ++#include "dev-ap94-pci.h" +#include "dev-gpio-buttons.h" -+#include "dev-pb42-pci.h" ++#include "dev-leds-gpio.h" +#include "dev-usb.h" + -+#define PB42_BUTTONS_POLL_INTERVAL 20 ++#define DIR825B1_GPIO_LED_BLUE_USB 0 ++#define DIR825B1_GPIO_LED_ORANGE_POWER 1 ++#define DIR825B1_GPIO_LED_BLUE_POWER 2 ++#define DIR825B1_GPIO_LED_BLUE_WPS 4 ++#define DIR825B1_GPIO_LED_ORANGE_PLANET 6 ++#define DIR825B1_GPIO_LED_BLUE_PLANET 11 ++ ++#define DIR825B1_GPIO_BTN_RESET 3 ++#define DIR825B1_GPIO_BTN_WPS 8 + -+#define PB42_GPIO_BTN_SW4 8 -+#define PB42_GPIO_BTN_SW5 3 ++#define DIR825B1_GPIO_RTL8366_SDA 5 ++#define DIR825B1_GPIO_RTL8366_SCK 7 ++ ++#define DIR825B1_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define DIR825B1_KEYS_DEBOUNCE_INTERVAL (3 * DIR825B1_KEYS_POLL_INTERVAL) ++ ++#define DIR825B1_CAL_LOCATION_0 0x1f661000 ++#define DIR825B1_CAL_LOCATION_1 0x1f665000 ++ ++#define DIR825B1_MAC_LOCATION_0 0x2ffa81b8 ++#define DIR825B1_MAC_LOCATION_1 0x2ffa8370 ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition dir825b1_partitions[] = { ++ { ++ .name = "uboot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "config", ++ .offset = 0x040000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x050000, ++ .size = 0x610000, ++ }, { ++ .name = "caldata", ++ .offset = 0x660000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "unknown", ++ .offset = 0x670000, ++ .size = 0x190000, ++ .mask_flags = MTD_WRITEABLE, ++ } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ ++ ++static struct flash_platform_data dir825b1_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = dir825b1_partitions, ++ .nr_parts = ARRAY_SIZE(dir825b1_partitions), ++#endif ++}; + -+static struct gpio_button pb42_gpio_buttons[] __initdata = { ++static struct gpio_led dir825b1_leds_gpio[] __initdata = { + { -+ .desc = "sw4", ++ .name = "dir825b1:blue:usb", ++ .gpio = DIR825B1_GPIO_LED_BLUE_USB, ++ .active_low = 1, ++ }, { ++ .name = "dir825b1:orange:power", ++ .gpio = DIR825B1_GPIO_LED_ORANGE_POWER, ++ .active_low = 1, ++ }, { ++ .name = "dir825b1:blue:power", ++ .gpio = DIR825B1_GPIO_LED_BLUE_POWER, ++ .active_low = 1, ++ }, { ++ .name = "dir825b1:blue:wps", ++ .gpio = DIR825B1_GPIO_LED_BLUE_WPS, ++ .active_low = 1, ++ }, { ++ .name = "dir825b1:orange:planet", ++ .gpio = DIR825B1_GPIO_LED_ORANGE_PLANET, ++ .active_low = 1, ++ }, { ++ .name = "dir825b1:blue:planet", ++ .gpio = DIR825B1_GPIO_LED_BLUE_PLANET, ++ .active_low = 1, ++ } ++}; ++ ++static struct gpio_keys_button dir825b1_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", + .type = EV_KEY, -+ .code = BTN_0, -+ .threshold = 3, -+ .gpio = PB42_GPIO_BTN_SW4, ++ .code = KEY_RESTART, ++ .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR825B1_GPIO_BTN_RESET, + .active_low = 1, -+ } , { -+ .desc = "sw5", ++ }, { ++ .desc = "wps", + .type = EV_KEY, -+ .code = BTN_1, -+ .threshold = 3, -+ .gpio = PB42_GPIO_BTN_SW5, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR825B1_GPIO_BTN_WPS, + .active_low = 1, + } +}; + -+#define PB42_WAN_PHYMASK BIT(20) -+#define PB42_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19)) -+#define PB42_MDIO_PHYMASK (PB42_LAN_PHYMASK | PB42_WAN_PHYMASK) ++static struct rtl8366_initval dir825b1_rtl8366s_initvals[] = { ++ { .reg = 0x06, .val = 0x0108 }, ++}; + -+static void __init pb42_init(void) ++static struct rtl8366_platform_data dir825b1_rtl8366s_data = { ++ .gpio_sda = DIR825B1_GPIO_RTL8366_SDA, ++ .gpio_sck = DIR825B1_GPIO_RTL8366_SCK, ++ .num_initvals = ARRAY_SIZE(dir825b1_rtl8366s_initvals), ++ .initvals = dir825b1_rtl8366s_initvals, ++}; ++ ++static struct platform_device dir825b1_rtl8366s_device = { ++ .name = RTL8366S_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &dir825b1_rtl8366s_data, ++ } ++}; ++ ++static void __init dir825b1_setup(void) +{ -+ ar71xx_add_device_m25p80(NULL); ++ u8 *mac = (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1); + -+ ar71xx_add_device_mdio(~PB42_MDIO_PHYMASK); ++ ar71xx_add_device_mdio(0x0); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = PB42_WAN_PHYMASK; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 1); ++ ar71xx_eth0_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_pll_data.pll_1000 = 0x11110000; + -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_100; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 2); ++ ar71xx_eth1_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = 0x10; ++ ar71xx_eth1_pll_data.pll_1000 = 0x11110000; + + ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_gpio_buttons(-1, PB42_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(pb42_gpio_buttons), -+ pb42_gpio_buttons); ++ ar71xx_add_device_m25p80(&dir825b1_flash_data); + -+ pb42_pci_init(); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir825b1_leds_gpio), ++ dir825b1_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, DIR825B1_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(dir825b1_gpio_keys), ++ dir825b1_gpio_keys); ++ ++ ar71xx_add_device_usb(); ++ ++ platform_device_register(&dir825b1_rtl8366s_device); ++ ++ ap94_pci_setup_wmac_led_pin(0, 5); ++ ap94_pci_setup_wmac_led_pin(1, 5); ++ ++ ap94_pci_init((u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_0), ++ (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_0), ++ (u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_1), ++ (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1)); +} + -+MIPS_MACHINE(AR71XX_MACH_PB42, "PB42", "Atheros PB42", pb42_init); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c linux-2.6.39/arch/mips/ar71xx/mach-pb44.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-pb44.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,207 @@ ++MIPS_MACHINE(AR71XX_MACH_DIR_825_B1, "DIR-825-B1", "D-Link DIR-825 rev. B1", ++ dir825b1_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-eap7660d.c linux-2.6.39/arch/mips/ar71xx/mach-eap7660d.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-eap7660d.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-eap7660d.c 2011-08-24 02:41:55.497990784 +0200 +@@ -0,0 +1,180 @@ +/* -+ * Atheros PB44 board support ++ * Senao EAP7660D board support + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2010 Daniel Golle ++ * Copyright (C) 2008 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include ++#include ++#include +#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ +#include ++#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-pb42-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "dev-usb.h" ++#include "dev-m25p80.h" + -+#define PB44_PCF8757_VSC7395_CS 0 -+#define PB44_PCF8757_STEREO_CS 1 -+#define PB44_PCF8757_SLIC_CS0 2 -+#define PB44_PCF8757_SLIC_TEST 3 -+#define PB44_PCF8757_SLIC_INT0 4 -+#define PB44_PCF8757_SLIC_INT1 5 -+#define PB44_PCF8757_SW_RESET 6 -+#define PB44_PCF8757_SW_JUMP 8 -+#define PB44_PCF8757_LED_JUMP1 9 -+#define PB44_PCF8757_LED_JUMP2 10 -+#define PB44_PCF8757_TP24 11 -+#define PB44_PCF8757_TP25 12 -+#define PB44_PCF8757_TP26 13 -+#define PB44_PCF8757_TP27 14 -+#define PB44_PCF8757_TP28 15 ++#define EAP7660D_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define EAP7660D_KEYS_DEBOUNCE_INTERVAL (3 * EAP7660D_KEYS_POLL_INTERVAL) ++ ++#define EAP7660D_GPIO_DS4 7 ++#define EAP7660D_GPIO_DS5 2 ++#define EAP7660D_GPIO_DS7 0 ++#define EAP7660D_GPIO_DS8 4 ++#define EAP7660D_GPIO_SW1 3 ++#define EAP7660D_GPIO_SW3 8 ++#define EAP7660D_PHYMASK BIT(20) ++#define EAP7660D_BOARDCONFIG 0x1F7F0000 ++#define EAP7660D_GBIC_MAC_OFFSET 0x1000 ++#define EAP7660D_WMAC0_MAC_OFFSET 0x1010 ++#define EAP7660D_WMAC1_MAC_OFFSET 0x1016 ++#define EAP7660D_WMAC0_CALDATA_OFFSET 0x2000 ++#define EAP7660D_WMAC1_CALDATA_OFFSET 0x3000 ++ ++static struct ath5k_platform_data eap7660d_wmac0_data; ++static struct ath5k_platform_data eap7660d_wmac1_data; ++static char eap7660d_wmac0_mac[6]; ++static char eap7660d_wmac1_mac[6]; ++static u16 eap7660d_wmac0_eeprom[ATH5K_PLAT_EEP_MAX_WORDS]; ++static u16 eap7660d_wmac1_eeprom[ATH5K_PLAT_EEP_MAX_WORDS]; ++ ++#ifdef CONFIG_PCI ++static struct ar71xx_pci_irq eap7660d_pci_irqs[] __initdata = { ++ { ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, ++ }, { ++ .slot = 1, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV1, ++ } ++}; + -+#define PB44_GPIO_I2C_SCL 0 -+#define PB44_GPIO_I2C_SDA 1 ++static int eap7660d_pci_plat_dev_init(struct pci_dev *dev) ++{ ++ switch (PCI_SLOT(dev->devfn)) { ++ case 17: ++ dev->dev.platform_data = &eap7660d_wmac0_data; ++ break; + -+#define PB44_GPIO_EXP_BASE 16 -+#define PB44_GPIO_VSC7395_CS (PB44_GPIO_EXP_BASE + PB44_PCF8757_VSC7395_CS) -+#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_RESET) -+#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_JUMP) -+#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP1) -+#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP2) ++ case 18: ++ dev->dev.platform_data = &eap7660d_wmac1_data; ++ break; ++ } + -+static struct i2c_gpio_platform_data pb44_i2c_gpio_data = { -+ .sda_pin = PB44_GPIO_I2C_SDA, -+ .scl_pin = PB44_GPIO_I2C_SCL, -+}; ++ return 0; ++} + -+static struct platform_device pb44_i2c_gpio_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &pb44_i2c_gpio_data, ++void __init eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0, ++ u8 *cal_data1, u8 *mac_addr1) ++{ ++ if (cal_data0 && *cal_data0 == 0xa55a) { ++ memcpy(eap7660d_wmac0_eeprom, cal_data0, ++ ATH5K_PLAT_EEP_MAX_WORDS); ++ eap7660d_wmac0_data.eeprom_data = eap7660d_wmac0_eeprom; + } -+}; + -+static struct pcf857x_platform_data pb44_pcf857x_data = { -+ .gpio_base = PB44_GPIO_EXP_BASE, -+}; ++ if (cal_data1 && *cal_data1 == 0xa55a) { ++ memcpy(eap7660d_wmac1_eeprom, cal_data1, ++ ATH5K_PLAT_EEP_MAX_WORDS); ++ eap7660d_wmac1_data.eeprom_data = eap7660d_wmac1_eeprom; ++ } + -+static struct i2c_board_info pb44_i2c_board_info[] __initdata = { ++ if (mac_addr0) { ++ memcpy(eap7660d_wmac0_mac, mac_addr0, ++ sizeof(eap7660d_wmac0_mac)); ++ eap7660d_wmac0_data.macaddr = eap7660d_wmac0_mac; ++ } ++ ++ if (mac_addr1) { ++ memcpy(eap7660d_wmac1_mac, mac_addr1, ++ sizeof(eap7660d_wmac1_mac)); ++ eap7660d_wmac1_data.macaddr = eap7660d_wmac1_mac; ++ } ++ ++ ar71xx_pci_plat_dev_init = eap7660d_pci_plat_dev_init; ++ ar71xx_pci_init(ARRAY_SIZE(eap7660d_pci_irqs), eap7660d_pci_irqs); ++} ++#else ++static inline void eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0, ++ u8 *cal_data1, u8 *mac_addr1) ++{ ++} ++#endif /* CONFIG_PCI */ ++ ++static struct gpio_led eap7660d_leds_gpio[] __initdata = { + { -+ I2C_BOARD_INFO("pcf8575", 0x20), -+ .platform_data = &pb44_pcf857x_data, ++ .name = "eap7660d:green:ds8", ++ .gpio = EAP7660D_GPIO_DS8, ++ .active_low = 0, + }, -+}; -+ -+static struct gpio_led pb44_leds_gpio[] __initdata = { + { -+ .name = "pb44:amber:jump1", -+ .gpio = PB44_GPIO_LED_JUMP1, -+ .active_low = 1, -+ }, { -+ .name = "pb44:green:jump2", -+ .gpio = PB44_GPIO_LED_JUMP2, -+ .active_low = 1, ++ .name = "eap7660d:green:ds5", ++ .gpio = EAP7660D_GPIO_DS5, ++ .active_low = 0, ++ }, ++ { ++ .name = "eap7660d:green:ds7", ++ .gpio = EAP7660D_GPIO_DS7, ++ .active_low = 0, + }, ++ { ++ .name = "eap7660d:green:ds4", ++ .gpio = EAP7660D_GPIO_DS4, ++ .active_low = 0, ++ } +}; + -+static struct gpio_button pb44_gpio_buttons[] __initdata = { ++static struct gpio_keys_button eap7660d_gpio_keys[] __initdata = { + { -+ .desc = "soft_reset", ++ .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = PB44_GPIO_SW_RESET, ++ .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = EAP7660D_GPIO_SW1, + .active_low = 1, -+ } , { -+ .desc = "jumpstart", ++ }, ++ { ++ .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = PB44_GPIO_SW_JUMP, ++ .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = EAP7660D_GPIO_SW3, + .active_low = 1, + } +}; + -+static void pb44_vsc7395_reset(void) ++static void __init eap7660d_setup(void) +{ -+ ar71xx_device_stop(RESET_MODULE_GE1_PHY); -+ udelay(10); -+ ar71xx_device_start(RESET_MODULE_GE1_PHY); -+ mdelay(50); -+} ++ u8 *boardconfig = (u8 *) KSEG1ADDR(EAP7660D_BOARDCONFIG); + -+static struct vsc7385_platform_data pb44_vsc7395_data = { -+ .reset = pb44_vsc7395_reset, -+ .ucode_name = "vsc7395_ucode_pb44.bin", -+ .mac_cfg = { -+ .tx_ipg = 6, -+ .bit2 = 1, -+ .clk_sel = 0, -+ }, -+}; ++ ar71xx_add_device_mdio(~EAP7660D_PHYMASK); + -+static struct spi_board_info pb44_spi_info[] = { ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ++ boardconfig + EAP7660D_GBIC_MAC_OFFSET, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = EAP7660D_PHYMASK; ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_m25p80(NULL); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(eap7660d_leds_gpio), ++ eap7660d_leds_gpio); ++ ar71xx_register_gpio_keys_polled(-1, EAP7660D_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(eap7660d_gpio_keys), ++ eap7660d_gpio_keys); ++ eap7660d_pci_init(boardconfig + EAP7660D_WMAC0_CALDATA_OFFSET, ++ boardconfig + EAP7660D_WMAC0_MAC_OFFSET, ++ boardconfig + EAP7660D_WMAC1_CALDATA_OFFSET, ++ boardconfig + EAP7660D_WMAC1_MAC_OFFSET); ++}; ++ ++MIPS_MACHINE(AR71XX_MACH_EAP7660D, "EAP7660D", "Senao EAP7660D", ++ eap7660d_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ja76pf.c linux-2.6.39/arch/mips/ar71xx/mach-ja76pf.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ja76pf.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ja76pf.c 2011-08-24 02:41:55.517989552 +0200 +@@ -0,0 +1,102 @@ ++/* ++ * jjPlus JA76PF board support ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "machtype.h" ++#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-gpio-buttons.h" ++#include "dev-pb42-pci.h" ++#include "dev-usb.h" ++#include "dev-leds-gpio.h" ++ ++#define JA76PF_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define JA76PF_KEYS_DEBOUNCE_INTERVAL (3 * JA76PF_KEYS_POLL_INTERVAL) ++ ++#define JA76PF_GPIO_I2C_SCL 0 ++#define JA76PF_GPIO_I2C_SDA 1 ++#define JA76PF_GPIO_LED_1 5 ++#define JA76PF_GPIO_LED_2 4 ++#define JA76PF_GPIO_LED_3 3 ++#define JA76PF_GPIO_BTN_RESET 11 ++ ++static struct gpio_led ja76pf_leds_gpio[] __initdata = { + { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", ++ .name = "ja76pf:green:led1", ++ .gpio = JA76PF_GPIO_LED_1, ++ .active_low = 1, + }, { -+ .bus_num = 0, -+ .chip_select = 1, -+ .max_speed_hz = 25000000, -+ .modalias = "spi-vsc7385", -+ .platform_data = &pb44_vsc7395_data, -+ .controller_data = (void *) PB44_GPIO_VSC7395_CS, -+ }, ++ .name = "ja76pf:green:led2", ++ .gpio = JA76PF_GPIO_LED_2, ++ .active_low = 1, ++ }, { ++ .name = "ja76pf:green:led3", ++ .gpio = JA76PF_GPIO_LED_3, ++ .active_low = 1, ++ } +}; + -+static struct resource pb44_spi_resources[] = { -+ [0] = { -+ .start = AR71XX_SPI_BASE, -+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, ++static struct gpio_keys_button ja76pf_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = JA76PF_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = JA76PF_GPIO_BTN_RESET, ++ .active_low = 1, ++ } +}; + -+static struct ar71xx_spi_platform_data pb44_spi_data = { -+ .bus_num = 0, -+ .num_chipselect = 2, ++static struct i2c_gpio_platform_data ja76pf_i2c_gpio_data = { ++ .sda_pin = JA76PF_GPIO_I2C_SDA, ++ .scl_pin = JA76PF_GPIO_I2C_SCL, +}; + -+static struct platform_device pb44_spi_device = { -+ .name = "pb44-spi", -+ .id = -1, -+ .resource = pb44_spi_resources, -+ .num_resources = ARRAY_SIZE(pb44_spi_resources), ++static struct platform_device ja76pf_i2c_gpio_device = { ++ .name = "i2c-gpio", ++ .id = 0, + .dev = { -+ .platform_data = &pb44_spi_data, -+ }, ++ .platform_data = &ja76pf_i2c_gpio_data, ++ } +}; + -+#define PB44_WAN_PHYMASK BIT(0) -+#define PB44_LAN_PHYMASK 0 -+#define PB44_MDIO_PHYMASK (PB44_LAN_PHYMASK | PB44_WAN_PHYMASK) ++#define JA76PF_WAN_PHYMASK (1 << 4) ++#define JA76PF_LAN_PHYMASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 < 3)) ++#define JA76PF_MDIO_PHYMASK (JA76PF_LAN_PHYMASK | JA76PF_WAN_PHYMASK) + -+static void __init pb44_init(void) ++static void __init ja76pf_init(void) +{ -+ ar71xx_add_device_mdio(~PB44_MDIO_PHYMASK); ++ ar71xx_add_device_m25p80(NULL); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.phy_mask = PB44_WAN_PHYMASK; ++ ar71xx_add_device_mdio(~JA76PF_MDIO_PHYMASK); + -+ ar71xx_add_device_eth(0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = JA76PF_LAN_PHYMASK; + + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = JA76PF_WAN_PHYMASK; + ar71xx_eth1_data.speed = SPEED_1000; + ar71xx_eth1_data.duplex = DUPLEX_FULL; -+ ar71xx_eth1_pll_data.pll_1000 = 0x110000; + ++ ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_usb(); -+ -+ pb42_pci_init(); -+ -+ i2c_register_board_info(0, pb44_i2c_board_info, -+ ARRAY_SIZE(pb44_i2c_board_info)); -+ -+ platform_device_register(&pb44_i2c_gpio_device); ++ platform_device_register(&ja76pf_i2c_gpio_device); + -+ spi_register_board_info(pb44_spi_info, ARRAY_SIZE(pb44_spi_info)); -+ platform_device_register(&pb44_spi_device); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ja76pf_leds_gpio), ++ ja76pf_leds_gpio); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio), -+ pb44_leds_gpio); ++ ar71xx_register_gpio_keys_polled(-1, JA76PF_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ja76pf_gpio_keys), ++ ja76pf_gpio_keys); + -+ ar71xx_add_device_gpio_buttons(-1, 20, ARRAY_SIZE(pb44_gpio_buttons), -+ pb44_gpio_buttons); ++ ar71xx_add_device_usb(); ++ pb42_pci_init(); +} + -+MIPS_MACHINE(AR71XX_MACH_PB44, "PB44", "Atheros PB44", pb44_init); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c linux-2.6.39/arch/mips/ar71xx/mach-pb92.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-pb92.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,109 @@ ++MIPS_MACHINE(AR71XX_MACH_JA76PF, "JA76PF", "jjPlus JA76PF", ja76pf_init); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-jwap003.c linux-2.6.39/arch/mips/ar71xx/mach-jwap003.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-jwap003.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-jwap003.c 2011-08-24 02:41:55.517989552 +0200 +@@ -0,0 +1,83 @@ +/* -+ * Atheros PB92 board support -+ * -+ * Copyright (C) 2010 Felix Fietkau -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * jjPlus JWAP003 board support + * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. + */ + -+#include -+#include +#include ++#include ++#include ++#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" +#include "dev-gpio-buttons.h" -+#include "dev-pb9x-pci.h" ++#include "dev-pb42-pci.h" +#include "dev-usb.h" + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition pb92_partitions[] = { ++#define JWAP003_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define JWAP003_KEYS_DEBOUNCE_INTERVAL (3 * JWAP003_KEYS_POLL_INTERVAL) ++ ++#define JWAP003_GPIO_WPS 11 ++#define JWAP003_GPIO_I2C_SCL 0 ++#define JWAP003_GPIO_I2C_SDA 1 ++ ++static struct gpio_keys_button jwap003_gpio_keys[] __initdata = { + { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x040000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "u-boot-env", -+ .offset = 0x040000, -+ .size = 0x010000, -+ } , { -+ .name = "rootfs", -+ .offset = 0x050000, -+ .size = 0x2b0000, -+ } , { -+ .name = "uImage", -+ .offset = 0x300000, -+ .size = 0x0e0000, -+ } , { -+ .name = "ART", -+ .offset = 0x3e0000, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, ++ .desc = "wps", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = JWAP003_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = JWAP003_GPIO_WPS, ++ .active_low = 1, + } +}; -+#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data pb92_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = pb92_partitions, -+ .nr_parts = ARRAY_SIZE(pb92_partitions), -+#endif ++static struct i2c_gpio_platform_data jwap003_i2c_gpio_data = { ++ .sda_pin = JWAP003_GPIO_I2C_SDA, ++ .scl_pin = JWAP003_GPIO_I2C_SCL, +}; + -+ -+#define PB92_BUTTONS_POLL_INTERVAL 20 -+ -+#define PB92_GPIO_BTN_SW4 8 -+#define PB92_GPIO_BTN_SW5 3 -+ -+static struct gpio_button pb92_gpio_buttons[] __initdata = { -+ { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .threshold = 3, -+ .gpio = PB92_GPIO_BTN_SW4, -+ .active_low = 1, -+ } , { -+ .desc = "sw5", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .threshold = 3, -+ .gpio = PB92_GPIO_BTN_SW5, -+ .active_low = 1, ++static struct platform_device jwap003_i2c_gpio_device = { ++ .name = "i2c-gpio", ++ .id = 0, ++ .dev = { ++ .platform_data = &jwap003_i2c_gpio_data, + } +}; + -+static void __init pb92_init(void) ++#define JWAP003_WAN_PHYMASK BIT(0) ++#define JWAP003_LAN_PHYMASK BIT(4) ++ ++static void __init jwap003_init(void) +{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); ++ ar71xx_add_device_m25p80(NULL); + -+ ar71xx_set_mac_base(mac); -+ ar71xx_add_device_m25p80(&pb92_flash_data); ++ ar71xx_add_device_mdio(0x0); + -+ ar71xx_add_device_mdio(~0); + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.phy_mask = JWAP003_WAN_PHYMASK; ++ ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.has_ar8216 = 1; + + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.phy_mask = JWAP003_LAN_PHYMASK; ++ ar71xx_eth1_data.speed = SPEED_100; + ar71xx_eth1_data.duplex = DUPLEX_FULL; + + ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_gpio_buttons(-1, PB92_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(pb92_gpio_buttons), -+ pb92_gpio_buttons); ++ platform_device_register(&jwap003_i2c_gpio_device); + -+ pb9x_pci_init(); ++ ar71xx_add_device_usb(); ++ ++ ar71xx_register_gpio_keys_polled(-1, JWAP003_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(jwap003_gpio_keys), ++ jwap003_gpio_keys); ++ ++ pb42_pci_init(); +} + -+MIPS_MACHINE(AR71XX_MACH_PB92, "PB92", "Atheros PB92", pb92_init); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,290 @@ ++MIPS_MACHINE(AR71XX_MACH_JWAP003, "JWAP003", "jjPlus JWAP003", jwap003_init); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c 2011-08-24 02:41:55.517989552 +0200 +@@ -0,0 +1,166 @@ +/* -+ * MikroTik RouterBOARD 4xx series support ++ * Planex MZK-W04NU board support + * -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+#include -+#include -+#include ++#include ++#include + +#include -+#include + +#include "machtype.h" +#include "devices.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "dev-m25p80.h" +#include "dev-usb.h" + -+#define RB4XX_GPIO_USER_LED 4 -+#define RB4XX_GPIO_RESET_SWITCH 7 -+ -+#define RB4XX_BUTTONS_POLL_INTERVAL 20 -+ -+static struct gpio_led rb4xx_leds_gpio[] __initdata = { -+ { -+ .name = "rb4xx:yellow:user", -+ .gpio = RB4XX_GPIO_USER_LED, -+ .active_low = 0, -+ }, -+}; ++#define MZK_W04NU_GPIO_LED_USB 0 ++#define MZK_W04NU_GPIO_LED_STATUS 1 ++#define MZK_W04NU_GPIO_LED_WPS 3 ++#define MZK_W04NU_GPIO_LED_WLAN 6 ++#define MZK_W04NU_GPIO_LED_AP 15 ++#define MZK_W04NU_GPIO_LED_ROUTER 16 + -+static struct gpio_button rb4xx_gpio_buttons[] __initdata = { -+ { -+ .desc = "reset_switch", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = RB4XX_GPIO_RESET_SWITCH, -+ .active_low = 1, -+ } -+}; ++#define MZK_W04NU_GPIO_BTN_APROUTER 5 ++#define MZK_W04NU_GPIO_BTN_WPS 12 ++#define MZK_W04NU_GPIO_BTN_RESET 21 + -+static struct platform_device rb4xx_nand_device = { -+ .name = "rb4xx-nand", -+ .id = -1, -+}; ++#define MZK_W04NU_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define MZK_W04NU_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W04NU_KEYS_POLL_INTERVAL) + -+static struct ar71xx_pci_irq rb4xx_pci_irqs[] __initdata = { ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition mzk_w04nu_partitions[] = { + { -+ .slot = 0, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV2, ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .slot = 1, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV0, ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, + }, { -+ .slot = 1, -+ .pin = 2, -+ .irq = AR71XX_PCI_IRQ_DEV1, ++ .name = "kernel", ++ .offset = 0x050000, ++ .size = 0x160000, + }, { -+ .slot = 2, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV1, ++ .name = "rootfs", ++ .offset = 0x1b0000, ++ .size = 0x630000, + }, { -+ .slot = 3, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV2, ++ .name = "art", ++ .offset = 0x7e0000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x050000, ++ .size = 0x790000, + } +}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+#if 0 -+/* -+ * SPI device support is experimental -+ */ -+static struct flash_platform_data rb4xx_flash_data = { -+ .type = "pm25lv512", ++static struct flash_platform_data mzk_w04nu_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = mzk_w04nu_partitions, ++ .nr_parts = ARRAY_SIZE(mzk_w04nu_partitions), ++#endif +}; + -+static struct spi_board_info rb4xx_spi_info[] = { ++static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = { + { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ .platform_data = &rb4xx_flash_data, ++ .name = "mzk-w04nu:green:status", ++ .gpio = MZK_W04NU_GPIO_LED_STATUS, ++ .active_low = 1, ++ }, { ++ .name = "mzk-w04nu:blue:wps", ++ .gpio = MZK_W04NU_GPIO_LED_WPS, ++ .active_low = 1, ++ }, { ++ .name = "mzk-w04nu:green:wlan", ++ .gpio = MZK_W04NU_GPIO_LED_WLAN, ++ .active_low = 1, ++ }, { ++ .name = "mzk-w04nu:green:usb", ++ .gpio = MZK_W04NU_GPIO_LED_USB, ++ .active_low = 1, ++ }, { ++ .name = "mzk-w04nu:green:ap", ++ .gpio = MZK_W04NU_GPIO_LED_AP, ++ .active_low = 1, ++ }, { ++ .name = "mzk-w04nu:green:router", ++ .gpio = MZK_W04NU_GPIO_LED_ROUTER, ++ .active_low = 1, + } +}; + -+static struct mmc_spi_platform_data rb433_mmc_data = { -+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, -+}; -+ -+static struct spi_board_info rb433_spi_info[] = { ++static struct gpio_keys_button mzk_w04nu_gpio_keys[] __initdata = { + { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ .platform_data = &rb433_flash_data, ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W04NU_GPIO_BTN_RESET, ++ .active_low = 1, + }, { -+ .bus_num = 0, -+ .chip_select = 2, -+ .max_speed_hz = 25000000, -+ .modalias = "mmc_spi", -+ .platform_data = &rb433_mmc_data, -+ } -+}; -+ -+static u32 rb433_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on) -+{ -+ u32 ret; -+ -+ if (is_on == AR71XX_SPI_CS_INACTIVE) { -+ ret = SPI_IOC_CS0 | SPI_IOC_CS1; -+ } else { -+ if (cs_high) { -+ ret = SPI_IOC_CS0 | SPI_IOC_CS1; -+ } else { -+ if ((chip_select ^ 2) == 0) -+ ret = SPI_IOC_CS1 ^ (SPI_IOC_CS0 | SPI_IOC_CS1); -+ else -+ ret = SPI_IOC_CS0 ^ (SPI_IOC_CS0 | SPI_IOC_CS1); -+ } ++ .desc = "wps", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W04NU_GPIO_BTN_WPS, ++ .active_low = 1, ++ }, { ++ .desc = "aprouter", ++ .type = EV_KEY, ++ .code = BTN_2, ++ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W04NU_GPIO_BTN_APROUTER, ++ .active_low = 0, + } -+ -+ return ret; -+} -+ -+struct ar71xx_spi_platform_data rb433_spi_data = { -+ .bus_num = 0, -+ .num_chipselect = 3, -+ .get_ioc_base = rb433_spi_get_ioc_base, +}; + -+static void rb4xx_add_device_spi(void) -+{ -+ ar71xx_add_device_spi(NULL, rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info)); -+} -+ -+static void rb433_add_device_spi(void) -+{ -+ ar71xx_add_device_spi(&rb433_spi_data, rb433_spi_info, -+ ARRAY_SIZE(rb433_spi_info)); -+} -+#else -+static inline void rb4xx_add_device_spi(void) {} -+static inline void rb433_add_device_spi(void) {} -+#endif -+ -+static void __init rb4xx_generic_setup(void) -+{ -+ ar71xx_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN | -+ AR71XX_GPIO_FUNC_SPI_CS2_EN); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio), -+ rb4xx_leds_gpio); -+ -+ ar71xx_add_device_gpio_buttons(-1, RB4XX_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(rb4xx_gpio_buttons), -+ rb4xx_gpio_buttons); -+ -+ platform_device_register(&rb4xx_nand_device); -+} -+ -+static void __init rb411_setup(void) -+{ -+ rb4xx_generic_setup(); -+ rb4xx_add_device_spi(); -+ -+ ar71xx_add_device_mdio(0xfffffffc); -+ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = 0x00000003; -+ -+ ar71xx_add_device_eth(0); -+ -+ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_RB_411, "411", "MikroTik RouterBOARD 411/A/AH", -+ rb411_setup); -+ -+static void __init rb411u_setup(void) -+{ -+ rb411_setup(); -+ ar71xx_add_device_usb(); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_RB_411U, "411U", "MikroTik RouterBOARD 411U", -+ rb411u_setup); ++#define MZK_W04NU_WAN_PHYMASK BIT(4) ++#define MZK_W04NU_MDIO_MASK (~MZK_W04NU_WAN_PHYMASK) + -+static void __init rb433_setup(void) ++static void __init mzk_w04nu_setup(void) +{ -+ rb4xx_generic_setup(); -+ rb433_add_device_spi(); ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_add_device_mdio(0xffffffe9); ++ ar71xx_add_device_mdio(MZK_W04NU_MDIO_MASK); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.has_ar8216 = 1; + ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x00000010; ++ ar71xx_eth1_data.phy_mask = MZK_W04NU_WAN_PHYMASK; + -+ ar71xx_add_device_eth(1); + ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); -+} ++ ar71xx_add_device_m25p80(&mzk_w04nu_flash_data); + -+MIPS_MACHINE(AR71XX_MACH_RB_433, "433", "MikroTik RouterBOARD 433/AH", -+ rb433_setup); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio), ++ mzk_w04nu_leds_gpio); + -+static void __init rb433u_setup(void) -+{ -+ rb433_setup(); ++ ar71xx_register_gpio_keys_polled(-1, MZK_W04NU_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(mzk_w04nu_gpio_keys), ++ mzk_w04nu_gpio_keys); + ar71xx_add_device_usb(); ++ ++ ar9xxx_add_device_wmac(eeprom, NULL); +} + -+MIPS_MACHINE(AR71XX_MACH_RB_433U, "433U", "MikroTik RouterBOARD 433UAH", -+ rb433u_setup); ++MIPS_MACHINE(AR71XX_MACH_MZK_W04NU, "MZK-W04NU", "Planex MZK-W04NU", ++ mzk_w04nu_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c 2011-08-24 02:41:55.527982711 +0200 +@@ -0,0 +1,159 @@ ++/* ++ * Planex MZK-W300NH board support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+static void __init rb450_generic_setup(int gige) -+{ -+ rb4xx_generic_setup(); -+ rb4xx_add_device_spi(); ++#include ++#include + -+ ar71xx_add_device_mdio(0xffffffe0); ++#include + -+ ar71xx_eth0_data.phy_if_mode = (gige) ? PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = (gige) ? (1 << 0) : 0; -+ ar71xx_eth0_data.speed = (gige) ? SPEED_1000 : SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++#include "machtype.h" ++#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" + -+ ar71xx_eth1_data.phy_if_mode = (gige) ? PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x00000010; ++#define MZK_W300NH_GPIO_LED_STATUS 1 ++#define MZK_W300NH_GPIO_LED_WPS 3 ++#define MZK_W300NH_GPIO_LED_WLAN 6 ++#define MZK_W300NH_GPIO_LED_AP 15 ++#define MZK_W300NH_GPIO_LED_ROUTER 16 + -+ ar71xx_add_device_eth(1); -+ ar71xx_add_device_eth(0); -+} ++#define MZK_W300NH_GPIO_BTN_APROUTER 5 ++#define MZK_W300NH_GPIO_BTN_WPS 12 ++#define MZK_W300NH_GPIO_BTN_RESET 21 + -+static void __init rb450_setup(void) -+{ -+ rb450_generic_setup(0); -+} ++#define MZK_W300NH_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define MZK_W300NH_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W300NH_KEYS_POLL_INTERVAL) + -+MIPS_MACHINE(AR71XX_MACH_RB_450, "450", "MikroTik RouterBOARD 450", -+ rb450_setup); -+ -+static void __init rb450g_setup(void) -+{ -+ rb450_generic_setup(1); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G", -+ rb450g_setup); -+ -+static void __init rb493_setup(void) -+{ -+ rb4xx_generic_setup(); -+ rb4xx_add_device_spi(); -+ -+ ar71xx_add_device_mdio(0x3fffff00); -+ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x00000001; -+ -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); -+ -+ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_RB_493, "493", "MikroTik RouterBOARD 493/AH", -+ rb493_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c linux-2.6.39/arch/mips/ar71xx/mach-rb750.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-rb750.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,133 @@ -+/* -+ * MikroTik RouterBOARD 750 support -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition mzk_w300nh_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, ++ }, { ++ .name = "kernel", ++ .offset = 0x050000, ++ .size = 0x160000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x1b0000, ++ .size = 0x630000, ++ }, { ++ .name = "art", ++ .offset = 0x7e0000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x050000, ++ .size = 0x790000, ++ } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+#include "machtype.h" -+#include "dev-ap91-eth.h" ++static struct flash_platform_data mzk_w300nh_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = mzk_w300nh_partitions, ++ .nr_parts = ARRAY_SIZE(mzk_w300nh_partitions), ++#endif ++}; + -+static struct rb750_led_data rb750_leds[] = { ++static struct gpio_led mzk_w300nh_leds_gpio[] __initdata = { + { -+ .name = "rb750:green:act", -+ .mask = RB750_LED_ACT, -+ .active_low = 1, -+ }, { -+ .name = "rb750:green:port1", -+ .mask = RB750_LED_PORT5, ++ .name = "mzk-w300nh:green:status", ++ .gpio = MZK_W300NH_GPIO_LED_STATUS, + .active_low = 1, + }, { -+ .name = "rb750:green:port2", -+ .mask = RB750_LED_PORT4, ++ .name = "mzk-w300nh:blue:wps", ++ .gpio = MZK_W300NH_GPIO_LED_WPS, + .active_low = 1, + }, { -+ .name = "rb750:green:port3", -+ .mask = RB750_LED_PORT3, ++ .name = "mzk-w300nh:green:wlan", ++ .gpio = MZK_W300NH_GPIO_LED_WLAN, + .active_low = 1, + }, { -+ .name = "rb750:green:port4", -+ .mask = RB750_LED_PORT2, ++ .name = "mzk-w300nh:green:ap", ++ .gpio = MZK_W300NH_GPIO_LED_AP, + .active_low = 1, + }, { -+ .name = "rb750:green:port5", -+ .mask = RB750_LED_PORT1, ++ .name = "mzk-w300nh:green:router", ++ .gpio = MZK_W300NH_GPIO_LED_ROUTER, + .active_low = 1, + } +}; + -+static struct rb750_led_platform_data rb750_leds_data = { -+ .num_leds = ARRAY_SIZE(rb750_leds), -+ .leds = rb750_leds, -+}; -+ -+static struct platform_device rb750_leds_device = { -+ .name = "leds-rb750", -+ .dev = { -+ .platform_data = &rb750_leds_data, ++static struct gpio_keys_button mzk_w300nh_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W300NH_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "wps", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W300NH_GPIO_BTN_WPS, ++ .active_low = 1, ++ }, { ++ .desc = "aprouter", ++ .type = EV_KEY, ++ .code = BTN_2, ++ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W300NH_GPIO_BTN_APROUTER, ++ .active_low = 0, + } +}; + -+static const char *rb750_port_names[AP91_ETH_NUM_PORT_NAMES] __initdata = { -+ "port5", -+ "port4", -+ "port3", -+ "port2", -+}; -+ -+static struct platform_device rb750_nand_device = { -+ .name = "rb750-nand", -+ .id = -1, -+}; ++#define MZK_W300NH_WAN_PHYMASK BIT(4) ++#define MZK_W300NH_MDIO_MASK (~MZK_W300NH_WAN_PHYMASK) + -+int rb750_latch_change(u32 mask_clr, u32 mask_set) ++static void __init mzk_w300nh_setup(void) +{ -+ static DEFINE_SPINLOCK(lock); -+ static u32 latch_set = RB750_LED_BITS | RB750_LVC573_LE; -+ static u32 latch_oe; -+ static u32 latch_clr; -+ unsigned long flags; -+ u32 t; -+ int ret = 0; -+ -+ spin_lock_irqsave(&lock, flags); -+ -+ if ((mask_clr & BIT(31)) != 0 && -+ (latch_set & RB750_LVC573_LE) == 0) { -+ goto unlock; -+ } -+ -+ latch_set = (latch_set | mask_set) & ~mask_clr; -+ latch_clr = (latch_clr | mask_clr) & ~mask_set; -+ -+ if (latch_oe == 0) -+ latch_oe = __raw_readl(ar71xx_gpio_base + GPIO_REG_OE); -+ -+ if (likely(latch_set & RB750_LVC573_LE)) { -+ void __iomem *base = ar71xx_gpio_base; ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+ t = __raw_readl(base + GPIO_REG_OE); -+ t |= mask_clr | latch_oe | mask_set; ++ ar71xx_add_device_mdio(MZK_W300NH_MDIO_MASK); + -+ __raw_writel(t, base + GPIO_REG_OE); -+ __raw_writel(latch_clr, base + GPIO_REG_CLEAR); -+ __raw_writel(latch_set, base + GPIO_REG_SET); -+ } else if (mask_clr & RB750_LVC573_LE) { -+ void __iomem *base = ar71xx_gpio_base; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.has_ar8216 = 1; + -+ latch_oe = __raw_readl(base + GPIO_REG_OE); -+ __raw_writel(RB750_LVC573_LE, base + GPIO_REG_CLEAR); -+ /* flush write */ -+ __raw_readl(base + GPIO_REG_CLEAR); -+ } ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = MZK_W300NH_WAN_PHYMASK; + -+ ret = 1; ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ unlock: -+ spin_unlock_irqrestore(&lock, flags); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(rb750_latch_change); ++ ar71xx_add_device_m25p80(&mzk_w300nh_flash_data); + -+static void __init rb750_setup(void) -+{ -+ ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w300nh_leds_gpio), ++ mzk_w300nh_leds_gpio); + -+ ap91_eth_init(NULL, rb750_port_names); -+ platform_device_register(&rb750_leds_device); -+ platform_device_register(&rb750_nand_device); ++ ar71xx_register_gpio_keys_polled(-1, MZK_W300NH_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(mzk_w300nh_gpio_keys), ++ mzk_w300nh_gpio_keys); ++ ar9xxx_add_device_wmac(eeprom, NULL); +} + -+MIPS_MACHINE(AR71XX_MACH_RB_750, "750i", "MikroTik RouterBOARD 750", -+ rb750_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,149 @@ ++MIPS_MACHINE(AR71XX_MACH_MZK_W300NH, "MZK-W300NH", "Planex MZK-W300NH", ++ mzk_w300nh_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c 2011-08-24 02:41:55.537990605 +0200 +@@ -0,0 +1,225 @@ +/* -+ * TrendNET TEW-632BRP board support ++ * Zyxel NBG 460N/550N/550NH board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2010 Michael Kurz ++ * ++ * based on mach-tl-wr1043nd.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include +#include +#include ++#include ++#include ++ ++#include ++#include ++#include + +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ar913x-wmac.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "nvram.h" + -+#define TEW_632BRP_GPIO_LED_STATUS 1 -+#define TEW_632BRP_GPIO_LED_WPS 3 -+#define TEW_632BRP_GPIO_LED_WLAN 6 -+#define TEW_632BRP_GPIO_BTN_WPS 12 -+#define TEW_632BRP_GPIO_BTN_RESET 21 ++/* LEDs */ ++#define NBG460N_GPIO_LED_WPS 3 ++#define NBG460N_GPIO_LED_WAN 6 ++#define NBG460N_GPIO_LED_POWER 14 ++#define NBG460N_GPIO_LED_WLAN 15 ++ ++/* Buttons */ ++#define NBG460N_GPIO_BTN_WPS 12 ++#define NBG460N_GPIO_BTN_RESET 21 + -+#define TEW_632BRP_BUTTONS_POLL_INTERVAL 20 ++#define NBG460N_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define NBG460N_KEYS_DEBOUNCE_INTERVAL (3 * NBG460N_KEYS_POLL_INTERVAL) + -+#define TEW_632BRP_CONFIG_ADDR 0x1f020000 -+#define TEW_632BRP_CONFIG_SIZE 0x10000 ++/* RTC chip PCF8563 I2C interface */ ++#define NBG460N_GPIO_PCF8563_SDA 8 ++#define NBG460N_GPIO_PCF8563_SCK 7 ++ ++/* Switch configuration I2C interface */ ++#define NBG460N_GPIO_RTL8366_SDA 16 ++#define NBG460N_GPIO_RTL8366_SCK 18 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tew_632brp_partitions[] = { ++static struct mtd_partition nbg460n_partitions[] = { + { -+ .name = "u-boot", ++ .name = "Bootbase", + .offset = 0, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "config", -+ .offset = 0x020000, + .size = 0x010000, -+ } , { -+ .name = "kernel", -+ .offset = 0x030000, -+ .size = 0x0d0000, -+ } , { ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "U-Boot Config", ++ .offset = 0x010000, ++ .size = 0x030000, ++ }, { ++ .name = "U-Boot", ++ .offset = 0x040000, ++ .size = 0x030000, ++ }, { ++ .name = "linux", ++ .offset = 0x070000, ++ .size = 0x0e0000, ++ }, { + .name = "rootfs", -+ .offset = 0x100000, -+ .size = 0x2f0000, -+ } , { -+ .name = "art", ++ .offset = 0x150000, ++ .size = 0x2a0000, ++ }, { ++ .name = "CalibData", + .offset = 0x3f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ } , { ++ }, { + .name = "firmware", -+ .offset = 0x030000, -+ .size = 0x3c0000, ++ .offset = 0x070000, ++ .size = 0x380000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data tew_632brp_flash_data = { ++static struct flash_platform_data nbg460n_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tew_632brp_partitions, -+ .nr_parts = ARRAY_SIZE(tew_632brp_partitions), ++ .parts = nbg460n_partitions, ++ .nr_parts = ARRAY_SIZE(nbg460n_partitions), +#endif +}; + -+static struct gpio_led tew_632brp_leds_gpio[] __initdata = { ++static struct gpio_led nbg460n_leds_gpio[] __initdata = { + { -+ .name = "tew-632brp:green:status", -+ .gpio = TEW_632BRP_GPIO_LED_STATUS, -+ .active_low = 1, ++ .name = "nbg460n:green:power", ++ .gpio = NBG460N_GPIO_LED_POWER, ++ .active_low = 0, ++ .default_trigger = "default-on", + }, { -+ .name = "tew-632brp:blue:wps", -+ .gpio = TEW_632BRP_GPIO_LED_WPS, -+ .active_low = 1, ++ .name = "nbg460n:green:wps", ++ .gpio = NBG460N_GPIO_LED_WPS, ++ .active_low = 0, + }, { -+ .name = "tew-632brp:green:wlan", -+ .gpio = TEW_632BRP_GPIO_LED_WLAN, -+ .active_low = 1, ++ .name = "nbg460n:green:wlan", ++ .gpio = NBG460N_GPIO_LED_WLAN, ++ .active_low = 0, ++ }, { ++ /* Not really for controlling the LED, ++ when set low the LED blinks uncontrollable */ ++ .name = "nbg460n:green:wan", ++ .gpio = NBG460N_GPIO_LED_WAN, ++ .active_low = 0, + } +}; + -+static struct gpio_button tew_632brp_gpio_buttons[] __initdata = { ++static struct gpio_keys_button nbg460n_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = TEW_632BRP_GPIO_BTN_RESET, ++ .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = NBG460N_GPIO_BTN_RESET, ++ .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = TEW_632BRP_GPIO_BTN_WPS, ++ .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = NBG460N_GPIO_BTN_WPS, ++ .active_low = 1, + } +}; + -+#define TEW_632BRP_LAN_PHYMASK BIT(0) -+#define TEW_632BRP_WAN_PHYMASK BIT(4) -+#define TEW_632BRP_MDIO_MASK (~(TEW_632BRP_LAN_PHYMASK | \ -+ TEW_632BRP_WAN_PHYMASK)) ++static struct i2c_gpio_platform_data nbg460n_i2c_device_platdata = { ++ .sda_pin = NBG460N_GPIO_PCF8563_SDA, ++ .scl_pin = NBG460N_GPIO_PCF8563_SCK, ++ .udelay = 10, ++}; + -+static void __init tew_632brp_setup(void) ++static struct platform_device nbg460n_i2c_device = { ++ .name = "i2c-gpio", ++ .id = -1, ++ .num_resources = 0, ++ .resource = NULL, ++ .dev = { ++ .platform_data = &nbg460n_i2c_device_platdata, ++ }, ++}; ++ ++static struct i2c_board_info nbg460n_i2c_devs[] __initdata = { ++ { ++ I2C_BOARD_INFO("pcf8563", 0x51), ++ }, ++}; ++ ++static void __devinit nbg460n_i2c_init(void) +{ -+ const char *config = (char *) KSEG1ADDR(TEW_632BRP_CONFIG_ADDR); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[6]; -+ u8 *wlan_mac = NULL; ++ /* The gpio interface */ ++ platform_device_register(&nbg460n_i2c_device); ++ /* I2C devices */ ++ i2c_register_board_info(0, nbg460n_i2c_devs, ++ ARRAY_SIZE(nbg460n_i2c_devs)); ++} + -+ if (nvram_parse_mac_addr(config, TEW_632BRP_CONFIG_SIZE, -+ "lan_mac=", mac) == 0) { -+ ar71xx_set_mac_base(mac); -+ wlan_mac = mac; ++ ++static struct rtl8366_platform_data nbg460n_rtl8366s_data = { ++ .gpio_sda = NBG460N_GPIO_RTL8366_SDA, ++ .gpio_sck = NBG460N_GPIO_RTL8366_SCK, ++}; ++ ++static struct platform_device nbg460n_rtl8366s_device = { ++ .name = RTL8366S_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &nbg460n_rtl8366s_data, + } ++}; + -+ ar71xx_add_device_mdio(TEW_632BRP_MDIO_MASK); ++static void __init nbg460n_setup(void) ++{ ++ /* end of bootloader sector contains mac address */ ++ u8 *mac = (u8 *) KSEG1ADDR(0x1fc0fff8); ++ /* last sector contains wlan calib data */ ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.phy_mask = TEW_632BRP_LAN_PHYMASK; ++ /* LAN Port */ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_eth0_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = TEW_632BRP_WAN_PHYMASK; ++ /* WAN Port */ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ ar71xx_eth1_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = 0x10; + + ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_m25p80(&tew_632brp_flash_data); ++ /* register the switch phy */ ++ platform_device_register(&nbg460n_rtl8366s_device); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio), -+ tew_632brp_leds_gpio); ++ /* register flash */ ++ ar71xx_add_device_m25p80(&nbg460n_flash_data); ++ ++ ar9xxx_add_device_wmac(eeprom, mac); ++ ++ /* register RTC chip */ ++ nbg460n_i2c_init(); + -+ ar71xx_add_device_gpio_buttons(-1, TEW_632BRP_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(tew_632brp_gpio_buttons), -+ tew_632brp_gpio_buttons); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(nbg460n_leds_gpio), ++ nbg460n_leds_gpio); + -+ ar913x_add_device_wmac(eeprom, wlan_mac); ++ ar71xx_register_gpio_keys_polled(-1, NBG460N_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(nbg460n_gpio_keys), ++ nbg460n_gpio_keys); +} + -+MIPS_MACHINE(AR71XX_MACH_TEW_632BRP, "TEW-632BRP", "TRENDnet TEW-632BRP", -+ tew_632brp_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,156 @@ ++MIPS_MACHINE(AR71XX_MACH_NBG460N, "NBG460N", "Zyxel NBG460N/550N/550NH", ++ nbg460n_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c linux-2.6.39/arch/mips/ar71xx/mach-pb42.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-pb42.c 2011-08-24 02:41:55.537990605 +0200 +@@ -0,0 +1,74 @@ +/* -+ * TP-LINK TL-WR1043ND board support ++ * Atheros PB42 board support + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+#include +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ar913x-wmac.h" +#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" ++#include "dev-pb42-pci.h" +#include "dev-usb.h" + -+#define TL_WR1043ND_GPIO_LED_USB 1 -+#define TL_WR1043ND_GPIO_LED_SYSTEM 2 -+#define TL_WR1043ND_GPIO_LED_QSS 5 -+#define TL_WR1043ND_GPIO_LED_WLAN 9 -+ -+#define TL_WR1043ND_GPIO_BTN_RESET 3 -+#define TL_WR1043ND_GPIO_BTN_QSS 7 -+ -+#define TL_WR1043ND_GPIO_RTL8366_SDA 18 -+#define TL_WR1043ND_GPIO_RTL8366_SCK 19 -+ -+#define TL_WR1043ND_BUTTONS_POLL_INTERVAL 20 -+ -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_wr1043nd_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "kernel", -+ .offset = 0x020000, -+ .size = 0x140000, -+ } , { -+ .name = "rootfs", -+ .offset = 0x160000, -+ .size = 0x690000, -+ } , { -+ .name = "art", -+ .offset = 0x7f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "firmware", -+ .offset = 0x020000, -+ .size = 0x7d0000, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ -+ -+static struct flash_platform_data tl_wr1043nd_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tl_wr1043nd_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wr1043nd_partitions), -+#endif -+}; ++#define PB42_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define PB42_KEYS_DEBOUNCE_INTERVAL (3 * PB42_KEYS_POLL_INTERVAL) + -+static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = { -+ { -+ .name = "tl-wr1043nd:green:usb", -+ .gpio = TL_WR1043ND_GPIO_LED_USB, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr1043nd:green:system", -+ .gpio = TL_WR1043ND_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr1043nd:green:qss", -+ .gpio = TL_WR1043ND_GPIO_LED_QSS, -+ .active_low = 0, -+ }, { -+ .name = "tl-wr1043nd:green:wlan", -+ .gpio = TL_WR1043ND_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; ++#define PB42_GPIO_BTN_SW4 8 ++#define PB42_GPIO_BTN_SW5 3 + -+static struct gpio_button tl_wr1043nd_gpio_buttons[] __initdata = { ++static struct gpio_keys_button pb42_gpio_keys[] __initdata = { + { -+ .desc = "reset", ++ .desc = "sw4", + .type = EV_KEY, -+ .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = TL_WR1043ND_GPIO_BTN_RESET, ++ .code = BTN_0, ++ .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB42_GPIO_BTN_SW4, + .active_low = 1, + }, { -+ .desc = "qss", ++ .desc = "sw5", + .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = TL_WR1043ND_GPIO_BTN_QSS, ++ .code = BTN_1, ++ .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB42_GPIO_BTN_SW5, + .active_low = 1, + } +}; + -+static struct rtl8366rb_platform_data tl_wr1043nd_rtl8366rb_data = { -+ .gpio_sda = TL_WR1043ND_GPIO_RTL8366_SDA, -+ .gpio_sck = TL_WR1043ND_GPIO_RTL8366_SCK, -+}; -+ -+static struct platform_device tl_wr1043nd_rtl8366rb_device = { -+ .name = RTL8366RB_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &tl_wr1043nd_rtl8366rb_data, -+ } -+}; ++#define PB42_WAN_PHYMASK BIT(20) ++#define PB42_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19)) ++#define PB42_MDIO_PHYMASK (PB42_LAN_PHYMASK | PB42_WAN_PHYMASK) + -+static void __init tl_wr1043nd_setup(void) ++static void __init pb42_init(void) +{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ ar71xx_add_device_m25p80(NULL); + -+ ar71xx_set_mac_base(mac); ++ ar71xx_add_device_mdio(~PB42_MDIO_PHYMASK); + -+ ar71xx_eth0_data.mii_bus_dev = &tl_wr1043nd_rtl8366rb_device.dev; -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.speed = SPEED_1000; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_pll_data.pll_1000 = 0x1a000000; -+ -+ ar71xx_add_device_eth(0); -+ -+ ar71xx_add_device_usb(); -+ -+ ar71xx_add_device_m25p80(&tl_wr1043nd_flash_data); ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = PB42_WAN_PHYMASK; + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr1043nd_leds_gpio), -+ tl_wr1043nd_leds_gpio); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_100; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; + -+ platform_device_register(&tl_wr1043nd_rtl8366rb_device); ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ ar71xx_add_device_gpio_buttons(-1, TL_WR1043ND_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr1043nd_gpio_buttons), -+ tl_wr1043nd_gpio_buttons); ++ ar71xx_register_gpio_keys_polled(-1, PB42_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(pb42_gpio_keys), ++ pb42_gpio_keys); + -+ ar913x_add_device_wmac(eeprom, mac); ++ pb42_pci_init(); +} + -+MIPS_MACHINE(AR71XX_MACH_TL_WR1043ND, "TL-WR1043ND", "TP-LINK TL-WR1043ND", -+ tl_wr1043nd_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,115 @@ ++MIPS_MACHINE(AR71XX_MACH_PB42, "PB42", "Atheros PB42", pb42_init); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c linux-2.6.39/arch/mips/ar71xx/mach-pb44.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-pb44.c 2011-08-24 02:41:55.537990605 +0200 +@@ -0,0 +1,213 @@ +/* -+ * TP-LINK TL-WR741ND board support ++ * Atheros PB44 board support + * -+ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + +#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ap91-eth.h" -+#include "dev-ap91-pci.h" ++#include "dev-pb42-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+#define TL_WR741ND_GPIO_LED_QSS 0 -+#define TL_WR741ND_GPIO_LED_SYSTEM 1 ++#define PB44_PCF8757_VSC7395_CS 0 ++#define PB44_PCF8757_STEREO_CS 1 ++#define PB44_PCF8757_SLIC_CS0 2 ++#define PB44_PCF8757_SLIC_TEST 3 ++#define PB44_PCF8757_SLIC_INT0 4 ++#define PB44_PCF8757_SLIC_INT1 5 ++#define PB44_PCF8757_SW_RESET 6 ++#define PB44_PCF8757_SW_JUMP 8 ++#define PB44_PCF8757_LED_JUMP1 9 ++#define PB44_PCF8757_LED_JUMP2 10 ++#define PB44_PCF8757_TP24 11 ++#define PB44_PCF8757_TP25 12 ++#define PB44_PCF8757_TP26 13 ++#define PB44_PCF8757_TP27 14 ++#define PB44_PCF8757_TP28 15 + -+#define TL_WR741ND_GPIO_BTN_RESET 11 -+#define TL_WR741ND_GPIO_BTN_QSS 12 ++#define PB44_GPIO_I2C_SCL 0 ++#define PB44_GPIO_I2C_SDA 1 + -+#define TL_WR741ND_BUTTONS_POLL_INTERVAL 20 ++#define PB44_GPIO_EXP_BASE 16 ++#define PB44_GPIO_VSC7395_CS (PB44_GPIO_EXP_BASE + PB44_PCF8757_VSC7395_CS) ++#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_RESET) ++#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_JUMP) ++#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP1) ++#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP2) + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_wr741nd_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "kernel", -+ .offset = 0x020000, -+ .size = 0x140000, -+ } , { -+ .name = "rootfs", -+ .offset = 0x160000, -+ .size = 0x290000, -+ } , { -+ .name = "art", -+ .offset = 0x3f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "firmware", -+ .offset = 0x020000, -+ .size = 0x3d0000, ++#define PB44_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL) ++ ++static struct i2c_gpio_platform_data pb44_i2c_gpio_data = { ++ .sda_pin = PB44_GPIO_I2C_SDA, ++ .scl_pin = PB44_GPIO_I2C_SCL, ++}; ++ ++static struct platform_device pb44_i2c_gpio_device = { ++ .name = "i2c-gpio", ++ .id = 0, ++ .dev = { ++ .platform_data = &pb44_i2c_gpio_data, + } +}; -+#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data tl_wr741nd_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tl_wr741nd_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wr741nd_partitions), -+#endif ++static struct pcf857x_platform_data pb44_pcf857x_data = { ++ .gpio_base = PB44_GPIO_EXP_BASE, +}; + -+static struct gpio_led tl_wr741nd_leds_gpio[] __initdata = { ++static struct i2c_board_info pb44_i2c_board_info[] __initdata = { + { -+ .name = "tl-wr741nd:green:system", -+ .gpio = TL_WR741ND_GPIO_LED_SYSTEM, ++ I2C_BOARD_INFO("pcf8575", 0x20), ++ .platform_data = &pb44_pcf857x_data, ++ }, ++}; ++ ++static struct gpio_led pb44_leds_gpio[] __initdata = { ++ { ++ .name = "pb44:amber:jump1", ++ .gpio = PB44_GPIO_LED_JUMP1, + .active_low = 1, + }, { -+ .name = "tl-wr741nd:green:qss", -+ .gpio = TL_WR741ND_GPIO_LED_QSS, ++ .name = "pb44:green:jump2", ++ .gpio = PB44_GPIO_LED_JUMP2, + .active_low = 1, -+ } ++ }, +}; + -+static struct gpio_button tl_wr741nd_gpio_buttons[] __initdata = { ++static struct gpio_keys_button pb44_gpio_keys[] __initdata = { + { -+ .desc = "reset", ++ .desc = "soft_reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = TL_WR741ND_GPIO_BTN_RESET, ++ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB44_GPIO_SW_RESET, + .active_low = 1, + }, { -+ .desc = "qss", ++ .desc = "jumpstart", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = TL_WR741ND_GPIO_BTN_QSS, ++ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB44_GPIO_SW_JUMP, + .active_low = 1, + } +}; + -+static void __init tl_wr741nd_setup(void) ++static void pb44_vsc7395_reset(void) +{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); ++ ar71xx_device_stop(RESET_MODULE_GE1_PHY); ++ udelay(10); ++ ar71xx_device_start(RESET_MODULE_GE1_PHY); ++ mdelay(50); ++} + -+ ar71xx_add_device_m25p80(&tl_wr741nd_flash_data); ++static struct vsc7385_platform_data pb44_vsc7395_data = { ++ .reset = pb44_vsc7395_reset, ++ .ucode_name = "vsc7395_ucode_pb44.bin", ++ .mac_cfg = { ++ .tx_ipg = 6, ++ .bit2 = 1, ++ .clk_sel = 0, ++ }, ++}; + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr741nd_leds_gpio), -+ tl_wr741nd_leds_gpio); ++static struct spi_board_info pb44_spi_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "m25p80", ++ }, { ++ .bus_num = 0, ++ .chip_select = 1, ++ .max_speed_hz = 25000000, ++ .modalias = "spi-vsc7385", ++ .platform_data = &pb44_vsc7395_data, ++ .controller_data = (void *) PB44_GPIO_VSC7395_CS, ++ }, ++}; ++ ++static struct resource pb44_spi_resources[] = { ++ [0] = { ++ .start = AR71XX_SPI_BASE, ++ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; + -+ ar71xx_add_device_gpio_buttons(-1, TL_WR741ND_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr741nd_gpio_buttons), -+ tl_wr741nd_gpio_buttons); ++static struct ar71xx_spi_platform_data pb44_spi_data = { ++ .bus_num = 0, ++ .num_chipselect = 2, ++}; + -+ ap91_eth_init(mac, NULL); -+ ap91_pci_init(ee, mac); ++static struct platform_device pb44_spi_device = { ++ .name = "pb44-spi", ++ .id = -1, ++ .resource = pb44_spi_resources, ++ .num_resources = ARRAY_SIZE(pb44_spi_resources), ++ .dev = { ++ .platform_data = &pb44_spi_data, ++ }, ++}; ++ ++#define PB44_WAN_PHYMASK BIT(0) ++#define PB44_LAN_PHYMASK 0 ++#define PB44_MDIO_PHYMASK (PB44_LAN_PHYMASK | PB44_WAN_PHYMASK) ++ ++static void __init pb44_init(void) ++{ ++ ar71xx_add_device_mdio(~PB44_MDIO_PHYMASK); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = PB44_WAN_PHYMASK; ++ ++ ar71xx_add_device_eth(0); ++ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_eth1_pll_data.pll_1000 = 0x110000; ++ ++ ar71xx_add_device_eth(1); ++ ++ ar71xx_add_device_usb(); ++ ++ pb42_pci_init(); ++ ++ i2c_register_board_info(0, pb44_i2c_board_info, ++ ARRAY_SIZE(pb44_i2c_board_info)); ++ ++ platform_device_register(&pb44_i2c_gpio_device); ++ ++ spi_register_board_info(pb44_spi_info, ARRAY_SIZE(pb44_spi_info)); ++ platform_device_register(&pb44_spi_device); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio), ++ pb44_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(pb44_gpio_keys), ++ pb44_gpio_keys); +} -+MIPS_MACHINE(AR71XX_MACH_TL_WR741ND, "TL-WR741ND", "TP-LINK TL-WR741ND", -+ tl_wr741nd_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,143 @@ ++ ++MIPS_MACHINE(AR71XX_MACH_PB44, "PB44", "Atheros PB44", pb44_init); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c linux-2.6.39/arch/mips/ar71xx/mach-pb92.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-pb92.c 2011-08-24 02:41:55.567991163 +0200 +@@ -0,0 +1,105 @@ +/* -+ * TP-LINK TL-WR841N board support ++ * Atheros PB92 board support + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2010 Felix Fietkau ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -5755,577 +6205,453 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c linux-2.6.39/arch/ + +#include +#include -+ +#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-dsa.h" +#include "dev-m25p80.h" +#include "dev-gpio-buttons.h" -+#include "dev-pb42-pci.h" -+#include "dev-leds-gpio.h" -+ -+#define TL_WR841ND_V1_GPIO_LED_SYSTEM 2 -+#define TL_WR841ND_V1_GPIO_LED_QSS_GREEN 4 -+#define TL_WR841ND_V1_GPIO_LED_QSS_RED 5 -+ -+#define TL_WR841ND_V1_GPIO_BTN_RESET 3 -+#define TL_WR841ND_V1_GPIO_BTN_QSS 7 -+ -+#define TL_WR841ND_V1_BUTTONS_POLL_INTERVAL 20 ++#include "dev-pb9x-pci.h" ++#include "dev-usb.h" + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_wr841n_v1_partitions[] = { ++static struct mtd_partition pb92_partitions[] = { + { -+ .name = "redboot", ++ .name = "u-boot", + .offset = 0, -+ .size = 0x020000, ++ .size = 0x040000, + .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "kernel", -+ .offset = 0x020000, -+ .size = 0x140000, -+ } , { ++ }, { ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, ++ }, { + .name = "rootfs", -+ .offset = 0x160000, -+ .size = 0x280000, -+ } , { -+ .name = "config", ++ .offset = 0x050000, ++ .size = 0x2b0000, ++ }, { ++ .name = "uImage", ++ .offset = 0x300000, ++ .size = 0x0e0000, ++ }, { ++ .name = "ART", + .offset = 0x3e0000, + .size = 0x020000, + .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "firmware", -+ .offset = 0x020000, -+ .size = 0x3c0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data tl_wr841n_v1_flash_data = { ++static struct flash_platform_data pb92_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tl_wr841n_v1_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wr841n_v1_partitions), ++ .parts = pb92_partitions, ++ .nr_parts = ARRAY_SIZE(pb92_partitions), +#endif +}; + -+static struct gpio_led tl_wr841n_v1_leds_gpio[] __initdata = { -+ { -+ .name = "tl-wr841n:green:system", -+ .gpio = TL_WR841ND_V1_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr841n:red:qss", -+ .gpio = TL_WR841ND_V1_GPIO_LED_QSS_RED, -+ }, { -+ .name = "tl-wr841n:green:qss", -+ .gpio = TL_WR841ND_V1_GPIO_LED_QSS_GREEN, -+ } -+}; ++#define PB92_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define PB92_KEYS_DEBOUNCE_INTERVAL (3 * PB92_KEYS_POLL_INTERVAL) ++ ++#define PB92_GPIO_BTN_SW4 8 ++#define PB92_GPIO_BTN_SW5 3 + -+static struct gpio_button tl_wr841n_v1_gpio_buttons[] __initdata = { ++static struct gpio_keys_button pb92_gpio_keys[] __initdata = { + { -+ .desc = "reset", ++ .desc = "sw4", + .type = EV_KEY, -+ .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = TL_WR841ND_V1_GPIO_BTN_RESET, ++ .code = BTN_0, ++ .debounce_interval = PB92_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB92_GPIO_BTN_SW4, + .active_low = 1, + }, { -+ .desc = "qss", ++ .desc = "sw5", + .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = TL_WR841ND_V1_GPIO_BTN_QSS, ++ .code = BTN_1, ++ .debounce_interval = PB92_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB92_GPIO_BTN_SW5, + .active_low = 1, + } +}; + -+static struct dsa_chip_data tl_wr841n_v1_dsa_chip = { -+ .port_names[0] = "wan", -+ .port_names[1] = "lan1", -+ .port_names[2] = "lan2", -+ .port_names[3] = "lan3", -+ .port_names[4] = "lan4", -+ .port_names[5] = "cpu", -+}; -+ -+static struct dsa_platform_data tl_wr841n_v1_dsa_data = { -+ .nr_chips = 1, -+ .chip = &tl_wr841n_v1_dsa_chip, -+}; -+ -+static void __init tl_wr841n_v1_setup(void) ++static void __init pb92_init(void) +{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ -+ ar71xx_set_mac_base(mac); ++ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); + -+ ar71xx_add_device_mdio(0x0); ++ ar71xx_add_device_m25p80(&pb92_flash_data); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_add_device_mdio(~BIT(0)); ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.speed = SPEED_1000; + ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = BIT(0); + + ar71xx_add_device_eth(0); + -+ ar71xx_add_device_dsa(0, &tl_wr841n_v1_dsa_data); -+ -+ ar71xx_add_device_m25p80(&tl_wr841n_v1_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v1_leds_gpio), -+ tl_wr841n_v1_leds_gpio); -+ -+ ar71xx_add_device_gpio_buttons(-1, TL_WR841ND_V1_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr841n_v1_gpio_buttons), -+ tl_wr841n_v1_gpio_buttons); ++ ar71xx_register_gpio_keys_polled(-1, PB92_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(pb92_gpio_keys), ++ pb92_gpio_keys); + -+ pb42_pci_init(); ++ pb9x_pci_init(); +} + -+MIPS_MACHINE(AR71XX_MACH_TL_WR841N_V1, "TL-WR841N-v1.5", "TP-LINK TL-WR841N v1", -+ tl_wr841n_v1_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,142 @@ ++MIPS_MACHINE(AR71XX_MACH_PB92, "PB92", "Atheros PB92", pb92_init); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c 2011-08-24 02:41:55.567991163 +0200 +@@ -0,0 +1,344 @@ +/* -+ * TP-LINK TL-WR941ND board support ++ * MikroTik RouterBOARD 4xx series support + * -+ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include ++#include ++#include ++#include ++#include ++#include +#include +#include + +#include ++#include ++#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-dsa.h" -+#include "dev-m25p80.h" -+#include "dev-ar913x-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+#define TL_WR941ND_GPIO_LED_SYSTEM 2 -+#define TL_WR941ND_GPIO_LED_QSS_RED 4 -+#define TL_WR941ND_GPIO_LED_QSS_GREEN 5 ++#define RB4XX_GPIO_USER_LED 4 ++#define RB4XX_GPIO_RESET_SWITCH 7 + -+#define TL_WR941ND_GPIO_BTN_RESET 3 -+#define TL_WR941ND_GPIO_BTN_QSS 7 ++#define RB4XX_GPIO_CPLD_BASE 32 ++#define RB4XX_GPIO_CPLD_LED1 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED1) ++#define RB4XX_GPIO_CPLD_LED2 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED2) ++#define RB4XX_GPIO_CPLD_LED3 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED3) ++#define RB4XX_GPIO_CPLD_LED4 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED4) ++#define RB4XX_GPIO_CPLD_LED5 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED5) + -+#define TL_WR941ND_BUTTONS_POLL_INTERVAL 20 ++#define RB4XX_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define RB4XX_KEYS_DEBOUNCE_INTERVAL (3 * RB4XX_KEYS_POLL_INTERVAL) + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_wr941nd_partitions[] = { ++static struct gpio_led rb4xx_leds_gpio[] __initdata = { + { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "kernel", -+ .offset = 0x020000, -+ .size = 0x140000, -+ } , { -+ .name = "rootfs", -+ .offset = 0x160000, -+ .size = 0x290000, -+ } , { -+ .name = "art", -+ .offset = 0x3f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "firmware", -+ .offset = 0x020000, -+ .size = 0x3d0000, ++ .name = "rb4xx:yellow:user", ++ .gpio = RB4XX_GPIO_USER_LED, ++ .active_low = 0, ++ }, { ++ .name = "rb4xx:green:led1", ++ .gpio = RB4XX_GPIO_CPLD_LED1, ++ .active_low = 1, ++ }, { ++ .name = "rb4xx:green:led2", ++ .gpio = RB4XX_GPIO_CPLD_LED2, ++ .active_low = 1, ++ }, { ++ .name = "rb4xx:green:led3", ++ .gpio = RB4XX_GPIO_CPLD_LED3, ++ .active_low = 1, ++ }, { ++ .name = "rb4xx:green:led4", ++ .gpio = RB4XX_GPIO_CPLD_LED4, ++ .active_low = 1, ++ }, { ++ .name = "rb4xx:green:led5", ++ .gpio = RB4XX_GPIO_CPLD_LED5, ++ .active_low = 0, ++ }, ++}; ++ ++static struct gpio_keys_button rb4xx_gpio_keys[] __initdata = { ++ { ++ .desc = "reset_switch", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = RB4XX_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = RB4XX_GPIO_RESET_SWITCH, ++ .active_low = 1, + } +}; -+#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data tl_wr941nd_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tl_wr941nd_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wr941nd_partitions), -+#endif ++static struct platform_device rb4xx_nand_device = { ++ .name = "rb4xx-nand", ++ .id = -1, +}; + -+static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = { ++static struct ar71xx_pci_irq rb4xx_pci_irqs[] __initdata = { + { -+ .name = "tl-wr941nd:green:system", -+ .gpio = TL_WR941ND_GPIO_LED_SYSTEM, -+ .active_low = 1, ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV2, + }, { -+ .name = "tl-wr941nd:red:qss", -+ .gpio = TL_WR941ND_GPIO_LED_QSS_RED, ++ .slot = 1, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, + }, { -+ .name = "tl-wr941nd:green:qss", -+ .gpio = TL_WR941ND_GPIO_LED_QSS_GREEN, ++ .slot = 1, ++ .pin = 2, ++ .irq = AR71XX_PCI_IRQ_DEV1, ++ }, { ++ .slot = 2, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV1, ++ }, { ++ .slot = 3, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV2, + } +}; + -+static struct gpio_button tl_wr941nd_gpio_buttons[] __initdata = { ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition rb4xx_partitions[] = { + { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = TL_WR941ND_GPIO_BTN_RESET, -+ .active_low = 1, ++ .name = "routerboot", ++ .offset = 0, ++ .size = 0x0b000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = TL_WR941ND_GPIO_BTN_QSS, -+ .active_low = 1, ++ .name = "hard_config", ++ .offset = 0x0b000, ++ .size = 0x01000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "bios", ++ .offset = 0x0d000, ++ .size = 0x02000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "soft_config", ++ .offset = 0x0f000, ++ .size = 0x01000, + } +}; ++#define rb4xx_num_partitions ARRAY_SIZE(rb4xx_partitions) ++#else /* CONFIG_MTD_PARTITIONS */ ++#define rb4xx_partitions NULL ++#define rb4xx_num_partitions 0 ++#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct dsa_chip_data tl_wr941nd_dsa_chip = { -+ .port_names[0] = "wan", -+ .port_names[1] = "lan1", -+ .port_names[2] = "lan2", -+ .port_names[3] = "lan3", -+ .port_names[4] = "lan4", -+ .port_names[5] = "cpu", ++static struct flash_platform_data rb4xx_flash_data = { ++ .type = "pm25lv512", ++ .parts = rb4xx_partitions, ++ .nr_parts = rb4xx_num_partitions, +}; + -+static struct dsa_platform_data tl_wr941nd_dsa_data = { -+ .nr_chips = 1, -+ .chip = &tl_wr941nd_dsa_chip, ++static struct rb4xx_cpld_platform_data rb4xx_cpld_data = { ++ .gpio_base = RB4XX_GPIO_CPLD_BASE, +}; + -+static void __init tl_wr941nd_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ar71xx_set_mac_base(mac); ++static struct mmc_spi_platform_data rb4xx_mmc_data = { ++ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, ++}; + -+ ar71xx_add_device_mdio(0x0); ++static struct spi_board_info rb4xx_spi_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "m25p80", ++ .platform_data = &rb4xx_flash_data, ++ }, { ++ .bus_num = 0, ++ .chip_select = 1, ++ .max_speed_hz = 25000000, ++ .modalias = "spi-rb4xx-cpld", ++ .platform_data = &rb4xx_cpld_data, ++ } ++}; + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_dsa(0, &tl_wr941nd_dsa_data); -+ -+ ar71xx_add_device_m25p80(&tl_wr941nd_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio), -+ tl_wr941nd_leds_gpio); -+ -+ ar71xx_add_device_gpio_buttons(-1, TL_WR941ND_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr941nd_gpio_buttons), -+ tl_wr941nd_gpio_buttons); -+ ar913x_add_device_wmac(eeprom, mac); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_TL_WR941ND, "TL-WR941ND", "TP-LINK TL-WR941ND", -+ tl_wr941nd_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,281 @@ -+/* -+ * Ubiquiti RouterStation support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2008 Ubiquiti -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "machtype.h" -+#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ap91-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-pb42-pci.h" -+#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+ -+#define UBNT_RS_GPIO_LED_RF 2 -+#define UBNT_RS_GPIO_SW4 8 -+ -+#define UBNT_LS_SR71_GPIO_LED_D25 0 -+#define UBNT_LS_SR71_GPIO_LED_D26 1 -+#define UBNT_LS_SR71_GPIO_LED_D24 2 -+#define UBNT_LS_SR71_GPIO_LED_D23 4 -+#define UBNT_LS_SR71_GPIO_LED_D22 5 -+#define UBNT_LS_SR71_GPIO_LED_D27 6 -+#define UBNT_LS_SR71_GPIO_LED_D28 7 -+ -+#define UBNT_M_GPIO_LED_L1 0 -+#define UBNT_M_GPIO_LED_L2 1 -+#define UBNT_M_GPIO_LED_L3 11 -+#define UBNT_M_GPIO_LED_L4 7 -+#define UBNT_M_GPIO_BTN_RESET 12 -+ -+#define UBNT_BUTTONS_POLL_INTERVAL 20 -+ -+static struct gpio_led ubnt_rs_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:green:rf", -+ .gpio = UBNT_RS_GPIO_LED_RF, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = { ++static struct spi_board_info rb4xx_microsd_info[] = { + { -+ .name = "ubnt:green:d22", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D22, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d23", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D23, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d24", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D24, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:red:d25", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D25, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:red:d26", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D26, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d27", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D27, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d28", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D28, -+ .active_low = 0, ++ .bus_num = 0, ++ .chip_select = 2, ++ .max_speed_hz = 25000000, ++ .modalias = "mmc_spi", ++ .platform_data = &rb4xx_mmc_data, + } +}; + -+static struct gpio_led ubnt_m_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:red:link1", -+ .gpio = UBNT_M_GPIO_LED_L1, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:orange:link2", -+ .gpio = UBNT_M_GPIO_LED_L2, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:link3", -+ .gpio = UBNT_M_GPIO_LED_L3, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:link4", -+ .gpio = UBNT_M_GPIO_LED_L4, -+ .active_low = 0, -+ } -+}; + -+static struct gpio_button ubnt_gpio_buttons[] __initdata = { ++static struct resource rb4xx_spi_resources[] = { + { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = UBNT_RS_GPIO_SW4, -+ .active_low = 1, -+ } ++ .start = AR71XX_SPI_BASE, ++ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, +}; + -+static struct gpio_button ubnt_m_gpio_buttons[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = UBNT_M_GPIO_BTN_RESET, -+ .active_low = 1, -+ } ++static struct platform_device rb4xx_spi_device = { ++ .name = "rb4xx-spi", ++ .id = -1, ++ .resource = rb4xx_spi_resources, ++ .num_resources = ARRAY_SIZE(rb4xx_spi_resources), +}; + -+static void __init ubnt_generic_setup(void) ++static void __init rb4xx_generic_setup(void) +{ -+ ar71xx_add_device_m25p80(NULL); ++ ar71xx_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN | ++ AR71XX_GPIO_FUNC_SPI_CS2_EN); + -+ ar71xx_add_device_gpio_buttons(-1, UBNT_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_gpio_buttons), -+ ubnt_gpio_buttons); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio), ++ rb4xx_leds_gpio); + -+ pb42_pci_init(); -+} ++ ar71xx_register_gpio_keys_polled(-1, RB4XX_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(rb4xx_gpio_keys), ++ rb4xx_gpio_keys); + -+#define UBNT_RS_WAN_PHYMASK (1 << 20) -+#define UBNT_RS_LAN_PHYMASK ((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19)) ++ spi_register_board_info(rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info)); ++ platform_device_register(&rb4xx_spi_device); ++ platform_device_register(&rb4xx_nand_device); ++} + -+static void __init ubnt_rs_setup(void) ++static void __init rb411_setup(void) +{ -+ ubnt_generic_setup(); ++ rb4xx_generic_setup(); ++ spi_register_board_info(rb4xx_microsd_info, ++ ARRAY_SIZE(rb4xx_microsd_info)); + -+ ar71xx_add_device_mdio(~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK)); ++ ar71xx_add_device_mdio(0xfffffffc); + ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK; -+ -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_100; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = 0x00000003; + + ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); + -+ ar71xx_add_device_usb(); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), -+ ubnt_rs_leds_gpio); ++ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); +} + -+MIPS_MACHINE(AR71XX_MACH_UBNT_RS, "UBNT-RS", "Ubiquiti RouterStation", -+ ubnt_rs_setup); ++MIPS_MACHINE(AR71XX_MACH_RB_411, "411", "MikroTik RouterBOARD 411/A/AH", ++ rb411_setup); ++ ++static void __init rb411u_setup(void) ++{ ++ rb411_setup(); ++ ar71xx_add_device_usb(); ++} + -+MIPS_MACHINE(AR71XX_MACH_UBNT_AR71XX, "Ubiquiti AR71xx-based board", -+ "Ubiquiti RouterStation", ubnt_rs_setup); ++MIPS_MACHINE(AR71XX_MACH_RB_411U, "411U", "MikroTik RouterBOARD 411U", ++ rb411u_setup); + -+#define UBNT_RSPRO_WAN_PHYMASK (1 << 4) -+#define UBNT_RSPRO_LAN_PHYMASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) ++#define RB433_LAN_PHYMASK BIT(0) ++#define RB433_WAN_PHYMASK BIT(4) ++#define RB433_MDIO_PHYMASK (RB433_LAN_PHYMASK | RB433_WAN_PHYMASK) + -+static void __init ubnt_rspro_setup(void) ++static void __init rb433_setup(void) +{ -+ ubnt_generic_setup(); ++ rb4xx_generic_setup(); ++ spi_register_board_info(rb4xx_microsd_info, ++ ARRAY_SIZE(rb4xx_microsd_info)); + -+ ar71xx_add_device_mdio(~(UBNT_RSPRO_WAN_PHYMASK | UBNT_RSPRO_LAN_PHYMASK)); ++ ar71xx_add_device_mdio(~RB433_MDIO_PHYMASK); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.phy_mask = UBNT_RSPRO_WAN_PHYMASK; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 1); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = RB433_LAN_PHYMASK; + -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = UBNT_RSPRO_LAN_PHYMASK; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = RB433_WAN_PHYMASK; + -+ ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); ++ ar71xx_add_device_eth(0); + -+ ar71xx_add_device_usb(); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), -+ ubnt_rs_leds_gpio); ++ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); +} + -+MIPS_MACHINE(AR71XX_MACH_UBNT_RSPRO, "UBNT-RSPRO", "Ubiquiti RouterStation Pro", -+ ubnt_rspro_setup); ++MIPS_MACHINE(AR71XX_MACH_RB_433, "433", "MikroTik RouterBOARD 433/AH", ++ rb433_setup); + -+static void __init ubnt_lsx_setup(void) ++static void __init rb433u_setup(void) +{ -+ ubnt_generic_setup(); ++ rb433_setup(); ++ ar71xx_add_device_usb(); +} + -+MIPS_MACHINE(AR71XX_MACH_UBNT_LSX, "UBNT-LSX", "Ubiquiti LSX", ubnt_lsx_setup); ++MIPS_MACHINE(AR71XX_MACH_RB_433U, "433U", "MikroTik RouterBOARD 433UAH", ++ rb433u_setup); + -+#define UBNT_LSSR71_PHY_MASK (1 << 1) ++#define RB450_LAN_PHYMASK BIT(0) ++#define RB450_WAN_PHYMASK BIT(4) ++#define RB450_MDIO_PHYMASK (RB450_LAN_PHYMASK | RB450_WAN_PHYMASK) + -+static void __init ubnt_lssr71_setup(void) ++static void __init rb450_generic_setup(int gige) +{ -+ ubnt_generic_setup(); ++ rb4xx_generic_setup(); ++ ar71xx_add_device_mdio(~RB450_MDIO_PHYMASK); + -+ ar71xx_add_device_mdio(~UBNT_LSSR71_PHY_MASK); ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 1); ++ ar71xx_eth0_data.phy_if_mode = (gige) ? ++ PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = RB450_LAN_PHYMASK; + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK; ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth1_data.phy_if_mode = (gige) ? ++ PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = RB450_WAN_PHYMASK; + ++ ar71xx_add_device_eth(1); + ar71xx_add_device_eth(0); ++} + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio), -+ ubnt_ls_sr71_leds_gpio); ++static void __init rb450_setup(void) ++{ ++ rb450_generic_setup(0); +} + -+MIPS_MACHINE(AR71XX_MACH_UBNT_LSSR71, "UBNT-LS-SR71", "Ubiquiti LS-SR71", -+ ubnt_lssr71_setup); ++MIPS_MACHINE(AR71XX_MACH_RB_450, "450", "MikroTik RouterBOARD 450", ++ rb450_setup); + -+static void __init ubnt_m_setup(void) ++static void __init rb450g_setup(void) +{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); ++ rb450_generic_setup(1); ++ spi_register_board_info(rb4xx_microsd_info, ++ ARRAY_SIZE(rb4xx_microsd_info)); ++} + -+ ar71xx_set_mac_base(mac); ++MIPS_MACHINE(AR71XX_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G", ++ rb450g_setup); + -+ ar71xx_add_device_m25p80(NULL); ++static void __init rb493_setup(void) ++{ ++ rb4xx_generic_setup(); + -+ ar71xx_add_device_mdio(~0); ++ ar71xx_add_device_mdio(0x3fffff00); + ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; + ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.fifo_cfg1 = 0x0010ffff; -+ ar71xx_eth0_data.fifo_cfg2 = 0x015500aa; -+ ar71xx_eth0_data.fifo_cfg3 = 0x01f00140; -+ -+ ar71xx_add_device_eth(0); -+ -+ ap91_pci_init(ee, NULL); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_m_leds_gpio), -+ ubnt_m_leds_gpio); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = 0x00000001; + -+ ar71xx_add_device_gpio_buttons(-1, UBNT_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_m_gpio_buttons), -+ ubnt_m_gpio_buttons); -+} ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+static void __init ubnt_rocket_m_setup(void) -+{ -+ ubnt_m_setup(); -+ ar71xx_add_device_usb(); ++ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); +} + -+MIPS_MACHINE(AR71XX_MACH_UBNT_BULLET_M, "UBNT-BM", "Ubiquiti Bullet M", -+ ubnt_m_setup); -+MIPS_MACHINE(AR71XX_MACH_UBNT_ROCKET_M, "UBNT-RM", "Ubiquiti Rocket M", -+ ubnt_rocket_m_setup); -+ -+/* TODO detect the second ethernet port and use one -+ init function for all Ubiquiti MIMO series products */ -+static void __init ubnt_nano_m_setup(void) -+{ -+ ubnt_m_setup(); -+ -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; -+ ar71xx_eth1_data.fifo_cfg1 = 0x0010ffff; -+ ar71xx_eth1_data.fifo_cfg2 = 0x015500aa; -+ ar71xx_eth1_data.fifo_cfg3 = 0x01f00140; -+ -+ ar71xx_add_device_eth(1); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_UBNT_NANO_M, "UBNT-NM", "Ubiquiti Nanostation M", -+ ubnt_nano_m_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,209 @@ ++MIPS_MACHINE(AR71XX_MACH_RB_493, "493", "MikroTik RouterBOARD 493/AH", ++ rb493_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c linux-2.6.39/arch/mips/ar71xx/mach-rb750.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-rb750.c 2011-08-24 02:41:55.567991163 +0200 +@@ -0,0 +1,144 @@ +/* -+ * Netgear WNDR3700 board support ++ * MikroTik RouterBOARD 750 support + * -+ * Copyright (C) 2009 Marco Porsch -+ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -6333,213 +6659,148 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c linux-2.6.39/arch/m + */ + +#include -+#include -+#include -+#include -+#include -+ +#include ++#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ap94-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+ -+#define WNDR3700_GPIO_LED_WPS_ORANGE 0 -+#define WNDR3700_GPIO_LED_POWER_ORANGE 1 -+#define WNDR3700_GPIO_LED_POWER_GREEN 2 -+#define WNDR3700_GPIO_LED_WPS_GREEN 4 -+#define WNDR3700_GPIO_LED_WAN_GREEN 6 -+ -+#define WNDR3700_GPIO_BTN_WPS 3 -+#define WNDR3700_GPIO_BTN_RESET 8 -+#define WNDR3700_GPIO_BTN_WIFI 11 -+ -+#define WNDR3700_GPIO_RTL8366_SDA 5 -+#define WNDR3700_GPIO_RTL8366_SCK 7 -+ -+#define WNDR3700_BUTTONS_POLL_INTERVAL 20 -+ -+#define WNDR3700_WMAC0_MAC_OFFSET 0 -+#define WNDR3700_WMAC1_MAC_OFFSET 0xc -+#define WNDR3700_CALDATA0_OFFSET 0x1000 -+#define WNDR3700_CALDATA1_OFFSET 0x5000 -+ -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wndr3700_partitions[] = { -+ { -+ .name = "uboot", -+ .offset = 0, -+ .size = 0x050000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "env", -+ .offset = 0x050000, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "rootfs", -+ .offset = 0x070000, -+ .size = 0x720000, -+ } , { -+ .name = "config", -+ .offset = 0x790000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "config_bak", -+ .offset = 0x7a0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "pot", -+ .offset = 0x7b0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "traffic_meter", -+ .offset = 0x7c0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "language", -+ .offset = 0x7d0000, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "caldata", -+ .offset = 0x7f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ -+ -+static struct flash_platform_data wndr3700_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = wndr3700_partitions, -+ .nr_parts = ARRAY_SIZE(wndr3700_partitions), -+#endif -+}; + -+static struct gpio_led wndr3700_leds_gpio[] __initdata = { ++static struct rb750_led_data rb750_leds[] = { + { -+ .name = "wndr3700:green:power", -+ .gpio = WNDR3700_GPIO_LED_POWER_GREEN, ++ .name = "rb750:green:act", ++ .mask = RB750_LED_ACT, + .active_low = 1, + }, { -+ .name = "wndr3700:orange:power", -+ .gpio = WNDR3700_GPIO_LED_POWER_ORANGE, ++ .name = "rb750:green:port1", ++ .mask = RB750_LED_PORT5, + .active_low = 1, + }, { -+ .name = "wndr3700:green:wps", -+ .gpio = WNDR3700_GPIO_LED_WPS_GREEN, ++ .name = "rb750:green:port2", ++ .mask = RB750_LED_PORT4, + .active_low = 1, + }, { -+ .name = "wndr3700:orange:wps", -+ .gpio = WNDR3700_GPIO_LED_WPS_ORANGE, ++ .name = "rb750:green:port3", ++ .mask = RB750_LED_PORT3, + .active_low = 1, + }, { -+ .name = "wndr3700:green:wan", -+ .gpio = WNDR3700_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_button wndr3700_gpio_buttons[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = WNDR3700_GPIO_BTN_RESET, ++ .name = "rb750:green:port4", ++ .mask = RB750_LED_PORT2, + .active_low = 1, + }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = WNDR3700_GPIO_BTN_WPS, -+ .active_low = 1, -+ } , { -+ .desc = "wifi", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .threshold = 3, -+ .gpio = WNDR3700_GPIO_BTN_WIFI, ++ .name = "rb750:green:port5", ++ .mask = RB750_LED_PORT1, + .active_low = 1, + } +}; + -+static struct rtl8366s_platform_data wndr3700_rtl8366s_data = { -+ .gpio_sda = WNDR3700_GPIO_RTL8366_SDA, -+ .gpio_sck = WNDR3700_GPIO_RTL8366_SCK, ++static struct rb750_led_platform_data rb750_leds_data = { ++ .num_leds = ARRAY_SIZE(rb750_leds), ++ .leds = rb750_leds, +}; + -+static struct platform_device wndr3700_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &wndr3700_rtl8366s_data, ++static struct platform_device rb750_leds_device = { ++ .name = "leds-rb750", ++ .dev = { ++ .platform_data = &rb750_leds_data, + } +}; + -+static void __init wndr3700_setup(void) ++static struct platform_device rb750_nand_device = { ++ .name = "rb750-nand", ++ .id = -1, ++}; ++ ++int rb750_latch_change(u32 mask_clr, u32 mask_set) +{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); ++ static DEFINE_SPINLOCK(lock); ++ static u32 latch_set = RB750_LED_BITS | RB750_LVC573_LE; ++ static u32 latch_oe; ++ static u32 latch_clr; ++ unsigned long flags; ++ u32 t; ++ int ret = 0; + -+ ar71xx_set_mac_base(art); ++ spin_lock_irqsave(&lock, flags); + -+ ar71xx_eth0_pll_data.pll_1000 = 0x11110000; -+ ar71xx_eth0_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.speed = SPEED_1000; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ if ((mask_clr & BIT(31)) != 0 && ++ (latch_set & RB750_LVC573_LE) == 0) { ++ goto unlock; ++ } + -+ ar71xx_eth1_pll_data.pll_1000 = 0x11110000; -+ ar71xx_eth1_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++ latch_set = (latch_set | mask_set) & ~mask_clr; ++ latch_clr = (latch_clr | mask_clr) & ~mask_set; + -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); ++ if (latch_oe == 0) ++ latch_oe = __raw_readl(ar71xx_gpio_base + GPIO_REG_OE); + -+ ar71xx_add_device_usb(); ++ if (likely(latch_set & RB750_LVC573_LE)) { ++ void __iomem *base = ar71xx_gpio_base; + -+ ar71xx_add_device_m25p80(&wndr3700_flash_data); ++ t = __raw_readl(base + GPIO_REG_OE); ++ t |= mask_clr | latch_oe | mask_set; + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wndr3700_leds_gpio), -+ wndr3700_leds_gpio); ++ __raw_writel(t, base + GPIO_REG_OE); ++ __raw_writel(latch_clr, base + GPIO_REG_CLEAR); ++ __raw_writel(latch_set, base + GPIO_REG_SET); ++ } else if (mask_clr & RB750_LVC573_LE) { ++ void __iomem *base = ar71xx_gpio_base; + -+ ar71xx_add_device_gpio_buttons(-1, WNDR3700_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(wndr3700_gpio_buttons), -+ wndr3700_gpio_buttons); ++ latch_oe = __raw_readl(base + GPIO_REG_OE); ++ __raw_writel(RB750_LVC573_LE, base + GPIO_REG_CLEAR); ++ /* flush write */ ++ __raw_readl(base + GPIO_REG_CLEAR); ++ } + -+ platform_device_register(&wndr3700_rtl8366s_device); -+ platform_device_register_simple("wndr3700-led-usb", -1, NULL, 0); ++ ret = 1; + -+ ap94_pci_enable_quirk_wndr3700(); -+ ap94_pci_init(art + WNDR3700_CALDATA0_OFFSET, -+ art + WNDR3700_WMAC0_MAC_OFFSET, -+ art + WNDR3700_CALDATA1_OFFSET, -+ art + WNDR3700_WMAC1_MAC_OFFSET); ++unlock: ++ spin_unlock_irqrestore(&lock, flags); ++ return ret; +} ++EXPORT_SYMBOL_GPL(rb750_latch_change); + -+MIPS_MACHINE(AR71XX_MACH_WNDR3700, "WNDR3700", "NETGEAR WNDR3700", -+ wndr3700_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,148 @@ ++static void __init rb750_setup(void) ++{ ++ ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1); ++ ++ /* WAN port */ ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = BIT(4); ++ ++ /* LAN ports */ ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_eth1_data.has_ar7240_switch = 1; ++ ++ ar71xx_add_device_mdio(0x0); ++ ar71xx_add_device_eth(1); ++ ar71xx_add_device_eth(0); ++ ++ platform_device_register(&rb750_leds_device); ++ platform_device_register(&rb750_nand_device); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_RB_750, "750i", "MikroTik RouterBOARD 750", ++ rb750_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c 2011-08-24 02:41:55.577989822 +0200 +@@ -0,0 +1,151 @@ +/* -+ * NETGEAR WNR2000 board support ++ * TrendNET TEW-632BRP board support + * + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2008-2009 Andy Boyett + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -6554,149 +6815,153 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.39/arch/mi +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ar913x-wmac.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "nvram.h" + -+#define WNR2000_GPIO_LED_PWR_GREEN 14 -+#define WNR2000_GPIO_LED_PWR_AMBER 7 -+#define WNR2000_GPIO_LED_WPS 4 -+#define WNR2000_GPIO_LED_WLAN 6 -+#define WNR2000_GPIO_BTN_RESET 21 -+#define WNR2000_GPIO_BTN_WPS 8 ++#define TEW_632BRP_GPIO_LED_STATUS 1 ++#define TEW_632BRP_GPIO_LED_WPS 3 ++#define TEW_632BRP_GPIO_LED_WLAN 6 ++#define TEW_632BRP_GPIO_BTN_WPS 12 ++#define TEW_632BRP_GPIO_BTN_RESET 21 + -+#define WNR2000_BUTTONS_POLL_INTERVAL 20 ++#define TEW_632BRP_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TEW_632BRP_KEYS_DEBOUNCE_INTERVAL (3 * TEW_632BRP_KEYS_POLL_INTERVAL) ++ ++#define TEW_632BRP_CONFIG_ADDR 0x1f020000 ++#define TEW_632BRP_CONFIG_SIZE 0x10000 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wnr2000_partitions[] = { ++static struct mtd_partition tew_632brp_partitions[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x040000, ++ .size = 0x020000, + .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "u-boot-env", -+ .offset = 0x040000, ++ }, { ++ .name = "config", ++ .offset = 0x020000, + .size = 0x010000, -+ } , { ++ }, { ++ .name = "kernel", ++ .offset = 0x030000, ++ .size = 0x0e0000, ++ }, { + .name = "rootfs", -+ .offset = 0x050000, -+ .size = 0x240000, -+ } , { -+ .name = "user-config", -+ .offset = 0x290000, -+ .size = 0x010000, -+ } , { -+ .name = "uImage", -+ .offset = 0x2a0000, -+ .size = 0x120000, -+ } , { -+ .name = "language_table", -+ .offset = 0x3c0000, -+ .size = 0x020000, -+ } , { -+ .name = "rootfs_checksum", -+ .offset = 0x3e0000, -+ .size = 0x010000, -+ } , { ++ .offset = 0x110000, ++ .size = 0x2e0000, ++ }, { + .name = "art", + .offset = 0x3f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x030000, ++ .size = 0x3c0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data wnr2000_flash_data = { ++static struct flash_platform_data tew_632brp_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = wnr2000_partitions, -+ .nr_parts = ARRAY_SIZE(wnr2000_partitions), ++ .parts = tew_632brp_partitions, ++ .nr_parts = ARRAY_SIZE(tew_632brp_partitions), +#endif +}; + -+static struct gpio_led wnr2000_leds_gpio[] __initdata = { ++static struct gpio_led tew_632brp_leds_gpio[] __initdata = { + { -+ .name = "wnr2000:green:power", -+ .gpio = WNR2000_GPIO_LED_PWR_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "wnr2000:amber:power", -+ .gpio = WNR2000_GPIO_LED_PWR_AMBER, ++ .name = "tew-632brp:green:status", ++ .gpio = TEW_632BRP_GPIO_LED_STATUS, + .active_low = 1, + }, { -+ .name = "wnr2000:green:wps", -+ .gpio = WNR2000_GPIO_LED_WPS, ++ .name = "tew-632brp:blue:wps", ++ .gpio = TEW_632BRP_GPIO_LED_WPS, + .active_low = 1, + }, { -+ .name = "wnr2000:blue:wlan", -+ .gpio = WNR2000_GPIO_LED_WLAN, ++ .name = "tew-632brp:green:wlan", ++ .gpio = TEW_632BRP_GPIO_LED_WLAN, + .active_low = 1, + } +}; + -+static struct gpio_button wnr2000_gpio_buttons[] __initdata = { ++static struct gpio_keys_button tew_632brp_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = WNR2000_GPIO_BTN_RESET, ++ .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TEW_632BRP_GPIO_BTN_RESET, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = WNR2000_GPIO_BTN_WPS, ++ .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TEW_632BRP_GPIO_BTN_WPS, + } +}; + -+static void __init wnr2000_setup(void) ++#define TEW_632BRP_LAN_PHYMASK BIT(0) ++#define TEW_632BRP_WAN_PHYMASK BIT(4) ++#define TEW_632BRP_MDIO_MASK (~(TEW_632BRP_LAN_PHYMASK | \ ++ TEW_632BRP_WAN_PHYMASK)) ++ ++static void __init tew_632brp_setup(void) +{ ++ const char *config = (char *) KSEG1ADDR(TEW_632BRP_CONFIG_ADDR); + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 mac[6]; ++ u8 *wlan_mac = NULL; + -+ ar71xx_set_mac_base(eeprom); -+ ar71xx_add_device_mdio(0x0); ++ if (nvram_parse_mac_addr(config, TEW_632BRP_CONFIG_SIZE, ++ "lan_mac=", mac) == 0) { ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ wlan_mac = mac; ++ } ++ ++ ar71xx_add_device_mdio(TEW_632BRP_MDIO_MASK); + + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.has_ar8216 = 1; ++ ar71xx_eth0_data.phy_mask = TEW_632BRP_LAN_PHYMASK; + + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++ ar71xx_eth1_data.phy_mask = TEW_632BRP_WAN_PHYMASK; + + ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_m25p80(&wnr2000_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio), -+ wnr2000_leds_gpio); ++ ar71xx_add_device_m25p80(&tew_632brp_flash_data); + -+ ar71xx_add_device_gpio_buttons(-1, WNR2000_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(wnr2000_gpio_buttons), -+ wnr2000_gpio_buttons); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio), ++ tew_632brp_leds_gpio); + ++ ar71xx_register_gpio_keys_polled(-1, TEW_632BRP_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tew_632brp_gpio_keys), ++ tew_632brp_gpio_keys); + -+ ar913x_add_device_wmac(eeprom, NULL); ++ ar9xxx_add_device_wmac(eeprom, wlan_mac); +} + -+MIPS_MACHINE(AR71XX_MACH_WNR2000, "WNR2000", "NETGEAR WNR2000", wnr2000_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.39/arch/mips/ar71xx/mach-wp543.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wp543.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,99 @@ ++MIPS_MACHINE(AR71XX_MACH_TEW_632BRP, "TEW-632BRP", "TRENDnet TEW-632BRP", ++ tew_632brp_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-mr3x20.c linux-2.6.39/arch/mips/ar71xx/mach-tl-mr3x20.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-mr3x20.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-mr3x20.c 2011-08-24 02:41:55.577989822 +0200 +@@ -0,0 +1,166 @@ +/* -+ * Compex WP543/WPJ543 board support ++ * TP-LINK TL-MR3220/3420 board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include +#include +#include + @@ -6705,94 +6970,162 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.39/arch/mips +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-pb42-pci.h" ++#include "dev-ap91-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-usb.h" + -+#define WP543_GPIO_SW6 2 -+#define WP543_GPIO_LED_1 3 -+#define WP543_GPIO_LED_2 4 -+#define WP543_GPIO_LED_WLAN 5 -+#define WP543_GPIO_LED_CONN 6 -+#define WP543_GPIO_LED_DIAG 7 -+#define WP543_GPIO_SW4 8 ++#define TL_MR3X20_GPIO_LED_QSS 0 ++#define TL_MR3X20_GPIO_LED_SYSTEM 1 ++#define TL_MR3X20_GPIO_LED_3G 8 + -+#define WP543_BUTTONS_POLL_INTERVAL 20 ++#define TL_MR3X20_GPIO_BTN_RESET 11 ++#define TL_MR3X20_GPIO_BTN_QSS 12 + -+static struct gpio_led wp543_leds_gpio[] __initdata = { ++#define TL_MR3X20_GPIO_USB_POWER 6 ++ ++#define TL_MR3X20_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_MR3X20_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3X20_KEYS_POLL_INTERVAL) ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition tl_mr3x20_partitions[] = { + { -+ .name = "wp543:green:led1", -+ .gpio = WP543_GPIO_LED_1, -+ .active_low = 1, ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "wp543:green:led2", -+ .gpio = WP543_GPIO_LED_2, -+ .active_low = 1, ++ .name = "kernel", ++ .offset = 0x020000, ++ .size = 0x140000, + }, { -+ .name = "wp543:green:wlan", -+ .gpio = WP543_GPIO_LED_WLAN, ++ .name = "rootfs", ++ .offset = 0x160000, ++ .size = 0x290000, ++ }, { ++ .name = "art", ++ .offset = 0x3f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x020000, ++ .size = 0x3d0000, ++ } ++}; ++#define tl_mr3x20_num_partitions ARRAY_SIZE(tl_mr3x20_partitions) ++#else ++#define tl_mr3x20_partitions NULL ++#define tl_mr3x20_num_partitions 0 ++#endif /* CONFIG_MTD_PARTITIONS */ ++ ++static struct flash_platform_data tl_mr3x20_flash_data = { ++ .parts = tl_mr3x20_partitions, ++ .nr_parts = tl_mr3x20_num_partitions, ++}; ++ ++static struct gpio_led tl_mr3x20_leds_gpio[] __initdata = { ++ { ++ .name = "tl-mr3x20:green:system", ++ .gpio = TL_MR3X20_GPIO_LED_SYSTEM, + .active_low = 1, + }, { -+ .name = "wp543:green:conn", -+ .gpio = WP543_GPIO_LED_CONN, ++ .name = "tl-mr3x20:green:qss", ++ .gpio = TL_MR3X20_GPIO_LED_QSS, + .active_low = 1, + }, { -+ .name = "wp543:green:diag", -+ .gpio = WP543_GPIO_LED_DIAG, ++ .name = "tl-mr3x20:green:3g", ++ .gpio = TL_MR3X20_GPIO_LED_3G, + .active_low = 1, + } +}; + -+static struct gpio_button wp543_gpio_buttons[] __initdata = { ++static struct gpio_keys_button tl_mr3x20_gpio_keys[] __initdata = { + { -+ .desc = "sw6", ++ .desc = "reset", + .type = EV_KEY, -+ .code = BTN_0, -+ .threshold = 3, -+ .gpio = WP543_GPIO_SW6, ++ .code = KEY_RESTART, ++ .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_MR3X20_GPIO_BTN_RESET, ++ .active_low = 1, + }, { -+ .desc = "sw4", ++ .desc = "qss", + .type = EV_KEY, -+ .code = BTN_1, -+ .threshold = 3, -+ .gpio = WP543_GPIO_SW4, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_MR3X20_GPIO_BTN_QSS, ++ .active_low = 1, + } +}; + -+static void __init wp543_setup(void) ++static void __init tl_mr3x20_setup(void) +{ -+ ar71xx_add_device_m25p80(NULL); ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_add_device_mdio(0xfffffff7); ++ /* enable power for the USB port */ ++ gpio_request(TL_MR3X20_GPIO_USB_POWER, "USB power"); ++ gpio_direction_output(TL_MR3X20_GPIO_USB_POWER, 1); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = 0x08; -+ ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC | -+ RESET_MODULE_GE0_PHY; ++ ar71xx_add_device_m25p80(&tl_mr3x20_flash_data); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_mr3x20_leds_gpio), ++ tl_mr3x20_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, TL_MR3X20_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_mr3x20_gpio_keys), ++ tl_mr3x20_gpio_keys); ++ ++ ar71xx_eth1_data.has_ar7240_switch = 1; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ ++ /* WAN port */ ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = BIT(4); ++ ++ /* LAN ports */ ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ++ ar71xx_add_device_mdio(0x0); ++ ar71xx_add_device_eth(1); + ar71xx_add_device_eth(0); + + ar71xx_add_device_usb(); + -+ pb42_pci_init(); ++ ap91_pci_init(ee, mac); ++} + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio), -+ wp543_leds_gpio); ++static void __init tl_mr3220_setup(void) ++{ ++ tl_mr3x20_setup(); ++ ap91_pci_setup_wmac_led_pin(1); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_TL_MR3220, "TL-MR3220", "TP-LINK TL-MR3220", ++ tl_mr3220_setup); + -+ ar71xx_add_device_gpio_buttons(-1, WP543_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(wp543_gpio_buttons), -+ wp543_gpio_buttons); ++static void __init tl_mr3420_setup(void) ++{ ++ tl_mr3x20_setup(); ++ ap91_pci_setup_wmac_led_pin(0); +} + -+MIPS_MACHINE(AR71XX_MACH_WP543, "WP543", "Compex WP543", wp543_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,158 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_MR3420, "TL-MR3420", "TP-LINK TL-MR3420", ++ tl_mr3420_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd.c 2011-08-24 02:41:55.587990766 +0200 +@@ -0,0 +1,130 @@ +/* -+ * Linksys WRT160NL board support ++ * TP-LINK TL-WA901ND board support + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2010 Pieter Hollants + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -6807,155 +7140,127 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c linux-2.6.39/arch/m +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ar913x-wmac.h" ++#include "dev-ap91-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+#include "nvram.h" + -+#define WRT160NL_GPIO_LED_POWER 14 -+#define WRT160NL_GPIO_LED_WPS_AMBER 9 -+#define WRT160NL_GPIO_LED_WPS_BLUE 8 -+#define WRT160NL_GPIO_LED_WLAN 6 ++#define TL_WA901ND_GPIO_LED_QSS 0 ++#define TL_WA901ND_GPIO_LED_SYSTEM 1 + -+#define WRT160NL_GPIO_BTN_WPS 7 -+#define WRT160NL_GPIO_BTN_RESET 21 ++#define TL_WA901ND_GPIO_BTN_RESET 11 ++#define TL_WA901ND_GPIO_BTN_QSS 12 + -+#define WRT160NL_BUTTONS_POLL_INTERVAL 20 -+ -+#define WRT160NL_NVRAM_ADDR 0x1f7e0000 -+#define WRT160NL_NVRAM_SIZE 0x10000 ++#define TL_WA901ND_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WA901ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WA901ND_KEYS_POLL_INTERVAL) + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wrt160nl_partitions[] = { ++static struct mtd_partition tl_wa901nd_partitions[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x040000, ++ .size = 0x020000, + .mask_flags = MTD_WRITEABLE, -+ } , { ++ }, { + .name = "kernel", -+ .offset = 0x040000, -+ .size = 0x0e0000, -+ } , { -+ .name = "filesytem", -+ .offset = 0x120000, -+ .size = 0x6c0000, -+ } , { -+ .name = "nvram", -+ .offset = 0x7e0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "ART", -+ .offset = 0x7f0000, ++ .offset = 0x020000, ++ .size = 0x140000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x160000, ++ .size = 0x290000, ++ }, { ++ .name = "art", ++ .offset = 0x3f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ } , { ++ }, { + .name = "firmware", -+ .offset = 0x040000, -+ .size = 0x7a0000, ++ .offset = 0x020000, ++ .size = 0x3d0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data wrt160nl_flash_data = { ++static struct flash_platform_data tl_wa901nd_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = wrt160nl_partitions, -+ .nr_parts = ARRAY_SIZE(wrt160nl_partitions), ++ .parts = tl_wa901nd_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wa901nd_partitions), +#endif +}; + -+static struct gpio_led wrt160nl_leds_gpio[] __initdata = { ++static struct gpio_led tl_wa901nd_leds_gpio[] __initdata = { + { -+ .name = "wrt160nl:blue:power", -+ .gpio = WRT160NL_GPIO_LED_POWER, -+ .active_low = 1, -+ .default_trigger = "default-on", -+ }, { -+ .name = "wrt160nl:amber:wps", -+ .gpio = WRT160NL_GPIO_LED_WPS_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "wrt160nl:blue:wps", -+ .gpio = WRT160NL_GPIO_LED_WPS_BLUE, ++ .name = "tl-wa901nd:green:system", ++ .gpio = TL_WA901ND_GPIO_LED_SYSTEM, + .active_low = 1, + }, { -+ .name = "wrt160nl:blue:wlan", -+ .gpio = WRT160NL_GPIO_LED_WLAN, ++ .name = "tl-wa901nd:green:qss", ++ .gpio = TL_WA901ND_GPIO_LED_QSS, + .active_low = 1, + } +}; + -+static struct gpio_button wrt160nl_gpio_buttons[] __initdata = { ++static struct gpio_keys_button tl_wa901nd_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, -+ .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = WRT160NL_GPIO_BTN_RESET, ++ .code = BTN_0, ++ .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WA901ND_GPIO_BTN_RESET, + .active_low = 1, + }, { -+ .desc = "wps", ++ .desc = "qss", + .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = WRT160NL_GPIO_BTN_WPS, ++ .code = BTN_1, ++ .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WA901ND_GPIO_BTN_QSS, + .active_low = 1, + } +}; + -+static void __init wrt160nl_setup(void) ++static void __init tl_wa901nd_setup(void) +{ -+ const char *nvram = (char *) KSEG1ADDR(WRT160NL_NVRAM_ADDR); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[6]; -+ -+ if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, -+ "lan_hwaddr=", mac) == 0) -+ ar71xx_set_mac_base(mac); -+ -+ ar71xx_add_device_mdio(0x0); -+ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.phy_mask = 0x01; ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + ++ /* ++ * ar71xx_eth0 would be the WAN port, but is not connected on ++ * the TL-WA901ND. ar71xx_eth1 connects to the internal switch chip, ++ * however we have a single LAN port only. ++ */ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 0); + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_eth1_data.has_ar7240_switch = 1; + -+ ar71xx_add_device_eth(0); ++ ar71xx_add_device_mdio(0x0); + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_m25p80(&wrt160nl_flash_data); -+ -+ ar71xx_add_device_usb(); -+ -+ if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, -+ "wl0_hwaddr=", mac) == 0) -+ ar913x_add_device_wmac(eeprom, mac); -+ else -+ ar913x_add_device_wmac(eeprom, NULL); ++ ar71xx_add_device_m25p80(&tl_wa901nd_flash_data); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt160nl_leds_gpio), -+ wrt160nl_leds_gpio); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_leds_gpio), ++ tl_wa901nd_leds_gpio); + -+ ar71xx_add_device_gpio_buttons(-1, WRT160NL_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(wrt160nl_gpio_buttons), -+ wrt160nl_gpio_buttons); ++ ar71xx_register_gpio_keys_polled(-1, TL_WA901ND_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wa901nd_gpio_keys), ++ tl_wa901nd_gpio_keys); + ++ ap91_pci_init(ee, mac); +} + -+MIPS_MACHINE(AR71XX_MACH_WRT160NL, "WRT160NL", "Linksys WRT160NL", -+ wrt160nl_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,168 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_WA901ND, "TL-WA901ND", "TP-LINK TL-WA901ND", ++ tl_wa901nd_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd-v2.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd-v2.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd-v2.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd-v2.c 2011-08-24 02:41:55.587990766 +0200 +@@ -0,0 +1,132 @@ +/* -+ * Linksys WRT400N board support ++ * TP-LINK TL-WA901ND v2 board support + * + * Copyright (C) 2009-2010 Gabor Juhos -+ * Copyright (C) 2009 Imre Kaloz ++ * Copyright (C) 2010 Pieter Hollants ++ * Copyright (C) 2011 Jonathan Bennett + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -6969,574 +7274,424 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c linux-2.6.39/arch/mi + +#include "machtype.h" +#include "devices.h" -+#include "dev-ap94-pci.h" +#include "dev-m25p80.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "dev-ar9xxx-wmac.h" + -+#define WRT400N_GPIO_LED_ORANGE 5 -+#define WRT400N_GPIO_LED_GREEN 4 -+#define WRT400N_GPIO_LED_POWER 1 -+#define WRT400N_GPIO_LED_WLAN 0 -+ -+#define WRT400N_GPIO_BTN_RESET 8 -+#define WRT400N_GPIO_BTN_WLSEC 3 ++#define TL_WA901ND_V2_GPIO_LED_QSS 4 ++#define TL_WA901ND_V2_GPIO_LED_SYSTEM 2 ++#define TL_WA901ND_V2_GPIO_LED_WLAN 9 + -+#define WRT400N_BUTTONS_POLL_INTERVAL 20 + -+#define WRT400N_MAC_ADDR_OFFSET 0x120c -+#define WRT400N_CALDATA0_OFFSET 0x1000 -+#define WRT400N_CALDATA1_OFFSET 0x5000 ++#define TL_WA901ND_V2_GPIO_BTN_RESET 3 ++#define TL_WA901ND_V2_GPIO_BTN_QSS 7 + ++#define TL_WA901ND_V2_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL \ ++ (3 * TL_WA901ND_V2_KEYS_POLL_INTERVAL) +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wrt400n_partitions[] = { ++static struct mtd_partition tl_wa901nd_v2_partitions[] = { + { -+ .name = "uboot", ++ .name = "u-boot", + .offset = 0, -+ .size = 0x030000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "env", -+ .offset = 0x030000, -+ .size = 0x010000, ++ .size = 0x020000, + .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "linux", -+ .offset = 0x040000, ++ }, { ++ .name = "kernel", ++ .offset = 0x020000, + .size = 0x140000, -+ } , { ++ }, { + .name = "rootfs", -+ .offset = 0x180000, -+ .size = 0x630000, -+ } , { -+ .name = "nvram", -+ .offset = 0x7b0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "factory", -+ .offset = 0x7c0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "language", -+ .offset = 0x7d0000, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "caldata", -+ .offset = 0x7f0000, ++ .offset = 0x160000, ++ .size = 0x290000, ++ }, { ++ .name = "art", ++ .offset = 0x3f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ } , { ++ }, { + .name = "firmware", -+ .offset = 0x040000, -+ .size = 0x770000, ++ .offset = 0x020000, ++ .size = 0x3d0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data wrt400n_flash_data = { ++static struct flash_platform_data tl_wa901nd_v2_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = wrt400n_partitions, -+ .nr_parts = ARRAY_SIZE(wrt400n_partitions), ++ .parts = tl_wa901nd_v2_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wa901nd_v2_partitions), +#endif +}; + -+static struct gpio_led wrt400n_leds_gpio[] __initdata = { ++static struct gpio_led tl_wa901nd_v2_leds_gpio[] __initdata = { + { -+ .name = "wrt400n:green:status", -+ .gpio = WRT400N_GPIO_LED_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "wrt400n:amber:aoss", -+ .gpio = WRT400N_GPIO_LED_ORANGE, ++ .name = "tl-wa901nd-v2:green:system", ++ .gpio = TL_WA901ND_V2_GPIO_LED_SYSTEM, + .active_low = 1, + }, { -+ .name = "wrt400n:green:wlan", -+ .gpio = WRT400N_GPIO_LED_WLAN, -+ .active_low = 1, ++ .name = "tl-wa901nd-v2:green:qss", ++ .gpio = TL_WA901ND_V2_GPIO_LED_QSS, + }, { -+ .name = "wrt400n:green:power", -+ .gpio = WRT400N_GPIO_LED_POWER, ++ .name = "tl-wa901nd-v2:green:wlan", ++ .gpio = TL_WA901ND_V2_GPIO_LED_WLAN, + .active_low = 1, + } +}; + -+static struct gpio_button wrt400n_gpio_buttons[] __initdata = { ++static struct gpio_keys_button tl_wa901nd_v2_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = WRT400N_GPIO_BTN_RESET, ++ .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WA901ND_V2_GPIO_BTN_RESET, + .active_low = 1, -+ } , { -+ .desc = "wlsec", ++ }, { ++ .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = WRT400N_GPIO_BTN_WLSEC, ++ .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WA901ND_V2_GPIO_BTN_QSS, + .active_low = 1, + } +}; + -+static void __init wrt400n_setup(void) ++static void __init tl_wa901nd_v2_setup(void) +{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 mac[6]; -+ int i; -+ -+ memcpy(mac, art + WRT400N_MAC_ADDR_OFFSET, 6); -+ for (i = 5; i >= 3; i--) -+ if (++mac[i] != 0x00) break; ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_set_mac_base(mac); ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); + ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = 0x00001000; + ar71xx_add_device_mdio(0x0); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x10; -+ ++ ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC | ++ RESET_MODULE_GE0_PHY; + ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); + -+ ar71xx_add_device_m25p80(&wrt400n_flash_data); ++ ar71xx_add_device_m25p80(&tl_wa901nd_v2_flash_data); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt400n_leds_gpio), -+ wrt400n_leds_gpio); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_v2_leds_gpio), ++ tl_wa901nd_v2_leds_gpio); + -+ ar71xx_add_device_gpio_buttons(-1, WRT400N_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(wrt400n_gpio_buttons), -+ wrt400n_gpio_buttons); ++ ar71xx_register_gpio_keys_polled(-1, TL_WA901ND_V2_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wa901nd_v2_gpio_keys), ++ tl_wa901nd_v2_gpio_keys); + -+ ap94_pci_init(art + WRT400N_CALDATA0_OFFSET, NULL, -+ art + WRT400N_CALDATA1_OFFSET, NULL); ++ ar9xxx_add_device_wmac(eeprom, mac); +} + -+MIPS_MACHINE(AR71XX_MACH_WRT400N, "WRT400N", "Linksys WRT400N", wrt400n_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,265 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_WA901ND_V2, "TL-WA901ND-v2", ++ "TP-LINK TL-WA901ND v2", tl_wa901nd_v2_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c 2011-08-24 02:41:55.587990766 +0200 +@@ -0,0 +1,156 @@ +/* -+ * Buffalo WZR-HP-G300NH board support ++ * TP-LINK TL-WR1043ND board support + * -+ * Copyright (C) 2010 Gabor Juhos ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include +#include +#include -+#include -+#include -+ -+#include ++#include ++#include +#include -+#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-ar913x-wmac.h" ++#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-usb.h" + -+#define WZRHPG300NH_GPIO_LED_USB 0 -+#define WZRHPG300NH_GPIO_LED_DIAG 1 -+#define WZRHPG300NH_GPIO_LED_WIRELESS 6 -+#define WZRHPG300NH_GPIO_LED_SECURITY 17 -+#define WZRHPG300NH_GPIO_LED_ROUTER 18 -+ -+#define WZRHPG300NH_GPIO_RTL8366_SDA 19 -+#define WZRHPG300NH_GPIO_RTL8366_SCK 20 -+ -+#define WZRHPG300NH_GPIO_74HC153_S0 9 -+#define WZRHPG300NH_GPIO_74HC153_S1 11 -+#define WZRHPG300NH_GPIO_74HC153_1Y 12 -+#define WZRHPG300NH_GPIO_74HC153_2Y 14 ++#define TL_WR1043ND_GPIO_LED_USB 1 ++#define TL_WR1043ND_GPIO_LED_SYSTEM 2 ++#define TL_WR1043ND_GPIO_LED_QSS 5 ++#define TL_WR1043ND_GPIO_LED_WLAN 9 + -+#define WZRHPG300NH_GPIO_EXP_BASE 32 -+#define WZRHPG300NH_GPIO_BTN_AOSS (WZRHPG300NH_GPIO_EXP_BASE + 0) -+#define WZRHPG300NH_GPIO_BTN_RESET (WZRHPG300NH_GPIO_EXP_BASE + 1) -+#define WZRHPG300NH_GPIO_BTN_ROUTER_ON (WZRHPG300NH_GPIO_EXP_BASE + 2) -+#define WZRHPG300NH_GPIO_BTN_QOS_ON (WZRHPG300NH_GPIO_EXP_BASE + 3) -+#define WZRHPG300NH_GPIO_BTN_USB (WZRHPG300NH_GPIO_EXP_BASE + 5) -+#define WZRHPG300NH_GPIO_BTN_ROUTER_AUTO (WZRHPG300NH_GPIO_EXP_BASE + 6) -+#define WZRHPG300NH_GPIO_BTN_QOS_OFF (WZRHPG300NH_GPIO_EXP_BASE + 7) ++#define TL_WR1043ND_GPIO_BTN_RESET 3 ++#define TL_WR1043ND_GPIO_BTN_QSS 7 + -+#define WZRHPG300NH_BUTTONS_POLL_INTERVAL 20 ++#define TL_WR1043ND_GPIO_RTL8366_SDA 18 ++#define TL_WR1043ND_GPIO_RTL8366_SCK 19 + -+#define WZRHPG300NH_MAC_OFFSET 0x20c ++#define TL_WR1043ND_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR1043ND_KEYS_POLL_INTERVAL) + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wzrhpg300nh_flash_partitions[] = { ++static struct mtd_partition tl_wr1043nd_partitions[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x0040000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "u-boot-env", -+ .offset = 0x0040000, -+ .size = 0x0020000, ++ .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", -+ .offset = 0x0060000, -+ .size = 0x0100000, ++ .offset = 0x020000, ++ .size = 0x140000, + }, { + .name = "rootfs", -+ .offset = 0x0160000, -+ .size = 0x1e60000, -+ }, { -+ .name = "user_property", -+ .offset = 0x1fc0000, -+ .size = 0x0020000, -+ .mask_flags = MTD_WRITEABLE, ++ .offset = 0x160000, ++ .size = 0x690000, + }, { + .name = "art", -+ .offset = 0x1fe0000, -+ .size = 0x0020000, ++ .offset = 0x7f0000, ++ .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", -+ .offset = 0x0060000, -+ .size = 0x1f60000, ++ .offset = 0x020000, ++ .size = 0x7d0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct ar91xx_flash_platform_data wzrhpg300nh_flash_data = { -+ .width = 2, ++static struct flash_platform_data tl_wr1043nd_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = wzrhpg300nh_flash_partitions, -+ .nr_parts = ARRAY_SIZE(wzrhpg300nh_flash_partitions), ++ .parts = tl_wr1043nd_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wr1043nd_partitions), +#endif +}; + -+#define WZRHPG300NH_FLASH_BASE 0x1e000000 -+#define WZRHPG300NH_FLASH_SIZE (32 * 1024 * 1024) -+ -+static struct resource wzrhpg300nh_flash_resources[] = { -+ [0] = { -+ .start = WZRHPG300NH_FLASH_BASE, -+ .end = WZRHPG300NH_FLASH_BASE + WZRHPG300NH_FLASH_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+static struct platform_device wzrhpg300nh_flash_device = { -+ .name = "ar91xx-flash", -+ .id = -1, -+ .resource = wzrhpg300nh_flash_resources, -+ .num_resources = ARRAY_SIZE(wzrhpg300nh_flash_resources), -+ .dev = { -+ .platform_data = &wzrhpg300nh_flash_data, -+ } -+}; -+ -+static struct gpio_led wzrhpg300nh_leds_gpio[] __initdata = { ++static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = { + { -+ .name = "wzr-hp-g300nh:orange:security", -+ .gpio = WZRHPG300NH_GPIO_LED_SECURITY, ++ .name = "tl-wr1043nd:green:usb", ++ .gpio = TL_WR1043ND_GPIO_LED_USB, + .active_low = 1, + }, { -+ .name = "wzr-hp-g300nh:green:wireless", -+ .gpio = WZRHPG300NH_GPIO_LED_WIRELESS, -+ .active_low = 1, -+ }, { -+ .name = "wzr-hp-g300nh:green:router", -+ .gpio = WZRHPG300NH_GPIO_LED_ROUTER, ++ .name = "tl-wr1043nd:green:system", ++ .gpio = TL_WR1043ND_GPIO_LED_SYSTEM, + .active_low = 1, + }, { -+ .name = "wzr-hp-g300nh:red:diag", -+ .gpio = WZRHPG300NH_GPIO_LED_DIAG, -+ .active_low = 1, ++ .name = "tl-wr1043nd:green:qss", ++ .gpio = TL_WR1043ND_GPIO_LED_QSS, ++ .active_low = 0, + }, { -+ .name = "wzr-hp-g300nh:blue:usb", -+ .gpio = WZRHPG300NH_GPIO_LED_USB, ++ .name = "tl-wr1043nd:green:wlan", ++ .gpio = TL_WR1043ND_GPIO_LED_WLAN, + .active_low = 1, + } +}; + -+static struct gpio_button wzrhpg300nh_gpio_buttons[] __initdata = { ++static struct gpio_keys_button tl_wr1043nd_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .threshold = 3, -+ .gpio = WZRHPG300NH_GPIO_BTN_RESET, ++ .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR1043ND_GPIO_BTN_RESET, + .active_low = 1, + }, { -+ .desc = "aoss", ++ .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .threshold = 3, -+ .gpio = WZRHPG300NH_GPIO_BTN_AOSS, -+ .active_low = 1, -+ }, { -+ .desc = "usb", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .threshold = 3, -+ .gpio = WZRHPG300NH_GPIO_BTN_USB, ++ .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR1043ND_GPIO_BTN_QSS, + .active_low = 1, -+ }, { -+ .desc = "qos_on", -+ .type = EV_KEY, -+ .code = BTN_3, -+ .threshold = 3, -+ .gpio = WZRHPG300NH_GPIO_BTN_QOS_ON, -+ .active_low = 0, -+ }, { -+ .desc = "qos_off", -+ .type = EV_KEY, -+ .code = BTN_4, -+ .threshold = 3, -+ .gpio = WZRHPG300NH_GPIO_BTN_QOS_OFF, -+ .active_low = 0, -+ }, { -+ .desc = "router_on", -+ .type = EV_KEY, -+ .code = BTN_5, -+ .threshold = 3, -+ .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_ON, -+ .active_low = 0, -+ }, { -+ .desc = "router_auto", -+ .type = EV_KEY, -+ .code = BTN_6, -+ .threshold = 3, -+ .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_AUTO, -+ .active_low = 0, -+ } -+}; -+ -+static struct nxp_74hc153_platform_data wzrhpg300nh_74hc153_data = { -+ .gpio_base = WZRHPG300NH_GPIO_EXP_BASE, -+ .gpio_pin_s0 = WZRHPG300NH_GPIO_74HC153_S0, -+ .gpio_pin_s1 = WZRHPG300NH_GPIO_74HC153_S1, -+ .gpio_pin_1y = WZRHPG300NH_GPIO_74HC153_1Y, -+ .gpio_pin_2y = WZRHPG300NH_GPIO_74HC153_2Y, -+}; -+ -+static struct platform_device wzrhpg300nh_74hc153_device = { -+ .name = NXP_74HC153_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &wzrhpg300nh_74hc153_data, + } +}; + -+static struct rtl8366s_platform_data wzrhpg300nh_rtl8366s_data = { -+ .gpio_sda = WZRHPG300NH_GPIO_RTL8366_SDA, -+ .gpio_sck = WZRHPG300NH_GPIO_RTL8366_SCK, ++static struct rtl8366_platform_data tl_wr1043nd_rtl8366rb_data = { ++ .gpio_sda = TL_WR1043ND_GPIO_RTL8366_SDA, ++ .gpio_sck = TL_WR1043ND_GPIO_RTL8366_SCK, +}; + -+static struct platform_device wzrhpg300nh_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, ++static struct platform_device tl_wr1043nd_rtl8366rb_device = { ++ .name = RTL8366RB_DRIVER_NAME, + .id = -1, + .dev = { -+ .platform_data = &wzrhpg300nh_rtl8366s_data, ++ .platform_data = &tl_wr1043nd_rtl8366rb_data, + } +}; + -+static void __init wzrhpg300nh_setup(void) ++static void __init tl_wr1043nd_setup(void) +{ ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_set_mac_base(eeprom + WZRHPG300NH_MAC_OFFSET); -+ -+ ar71xx_eth0_pll_data.pll_1000 = 0x1e000100; -+ ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_eth0_data.mii_bus_dev = &tl_wr1043nd_rtl8366rb_device.dev; + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ar71xx_eth0_data.speed = SPEED_1000; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ -+ ar71xx_eth1_pll_data.pll_1000 = 0x1e000100; -+ ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++ ar71xx_eth0_pll_data.pll_1000 = 0x1a000000; + + ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); + + ar71xx_add_device_usb(); -+ ar913x_add_device_wmac(eeprom, NULL); + -+ platform_device_register(&wzrhpg300nh_74hc153_device); -+ platform_device_register(&wzrhpg300nh_flash_device); -+ platform_device_register(&wzrhpg300nh_rtl8366s_device); ++ ar71xx_add_device_m25p80(&tl_wr1043nd_flash_data); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh_leds_gpio), -+ wzrhpg300nh_leds_gpio); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr1043nd_leds_gpio), ++ tl_wr1043nd_leds_gpio); ++ ++ platform_device_register(&tl_wr1043nd_rtl8366rb_device); + -+ ar71xx_add_device_gpio_buttons(-1, WZRHPG300NH_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(wzrhpg300nh_gpio_buttons), -+ wzrhpg300nh_gpio_buttons); ++ ar71xx_register_gpio_keys_polled(-1, TL_WR1043ND_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wr1043nd_gpio_keys), ++ tl_wr1043nd_gpio_keys); + ++ ar9xxx_add_device_wmac(eeprom, mac); +} + -+MIPS_MACHINE(AR71XX_MACH_WZR_HP_G300NH, "WZR-HP-G300NH", -+ "Buffalo WZR-HP-G300NH", wzrhpg300nh_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/machtype.h linux-2.6.39/arch/mips/ar71xx/machtype.h ---- linux-2.6.39.orig/arch/mips/ar71xx/machtype.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/machtype.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,60 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_WR1043ND, "TL-WR1043ND", "TP-LINK TL-WR1043ND", ++ tl_wr1043nd_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c 2011-08-24 02:41:55.587990766 +0200 +@@ -0,0 +1,135 @@ +/* -+ * Atheros AR71xx machine type definitions ++ * TP-LINK TL-WR741ND board support + * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009-2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#ifndef _AR71XX_MACHTYPE_H -+#define _AR71XX_MACHTYPE_H ++#include ++#include + -+#include ++#include + -+enum ar71xx_mach_type { -+ AR71XX_MACH_GENERIC = 0, -+ AR71XX_MACH_AP81, /* Atheros AP81 */ -+ AR71XX_MACH_AP83, /* Atheros AP83 */ -+ AR71XX_MACH_AW_NR580, /* AzureWave AW-NR580 */ -+ AR71XX_MACH_DIR_600_A1, /* D-Link DIR-600 rev. A1 */ -+ AR71XX_MACH_DIR_615_C1, /* D-Link DIR-615 rev. C1 */ -+ AR71XX_MACH_DIR_825_B1, /* D-Link DIR-825 rev. B1 */ -+ AR71XX_MACH_RB_411, /* MikroTik RouterBOARD 411/411A/411AH */ -+ AR71XX_MACH_RB_411U, /* MikroTik RouterBOARD 411U */ -+ AR71XX_MACH_RB_433, /* MikroTik RouterBOARD 433/433AH */ -+ AR71XX_MACH_RB_433U, /* MikroTik RouterBOARD 433UAH */ -+ AR71XX_MACH_RB_450, /* MikroTik RouterBOARD 450 */ -+ AR71XX_MACH_RB_450G, /* MikroTik RouterBOARD 450G */ -+ AR71XX_MACH_RB_493, /* Mikrotik RouterBOARD 493/493AH */ -+ AR71XX_MACH_RB_750, /* MikroTik RouterBOARD 750 */ -+ AR71XX_MACH_PB42, /* Atheros PB42 */ -+ AR71XX_MACH_PB44, /* Atheros PB44 */ -+ AR71XX_MACH_PB92, /* Atheros PB92 */ -+ AR71XX_MACH_MZK_W04NU, /* Planex MZK-W04NU */ -+ AR71XX_MACH_MZK_W300NH, /* Planex MZK-W300NH */ -+ AR71XX_MACH_NBG460N, /* Zyxel NBG460N/550N/550NH */ -+ AR71XX_MACH_TEW_632BRP, /* TRENDnet TEW-632BRP */ -+ AR71XX_MACH_TL_WR741ND, /* TP-LINK TL-WR741ND */ -+ AR71XX_MACH_TL_WR841N_V1, /* TP-LINK TL-WR841N v1 */ -+ AR71XX_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ -+ AR71XX_MACH_TL_WR1043ND, /* TP-LINK TL-WR1041ND */ -+ AR71XX_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */ -+ AR71XX_MACH_UBNT_LSX, /* Ubiquiti LSX */ -+ AR71XX_MACH_UBNT_RS, /* Ubiquiti RouterStation */ -+ AR71XX_MACH_UBNT_AR71XX, /* Ubiquiti AR71xx-based board */ -+ AR71XX_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */ -+ AR71XX_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ -+ AR71XX_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */ -+ AR71XX_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */ -+ AR71XX_MACH_WNDR3700, /* NETGEAR WNDR3700 */ -+ AR71XX_MACH_WNR2000, /* NETGEAR WNR2000 */ -+ AR71XX_MACH_WP543, /* Compex WP543 */ -+ AR71XX_MACH_WRT160NL, /* Linksys WRT160NL */ -+ AR71XX_MACH_WRT400N, /* Linksys WRT400N */ -+ AR71XX_MACH_WZR_HP_G300NH, /* Buffalo WZR-HP-G300NH */ ++#include "machtype.h" ++#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-ap91-pci.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++ ++#define TL_WR741ND_GPIO_LED_QSS 0 ++#define TL_WR741ND_GPIO_LED_SYSTEM 1 ++ ++#define TL_WR741ND_GPIO_BTN_RESET 11 ++#define TL_WR741ND_GPIO_BTN_QSS 12 ++ ++#define TL_WR741ND_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WR741ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR741ND_KEYS_POLL_INTERVAL) ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition tl_wr741nd_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "kernel", ++ .offset = 0x020000, ++ .size = 0x140000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x160000, ++ .size = 0x290000, ++ }, { ++ .name = "art", ++ .offset = 0x3f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x020000, ++ .size = 0x3d0000, ++ } +}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+#endif /* _AR71XX_MACHTYPE_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.c linux-2.6.39/arch/mips/ar71xx/nvram.c ---- linux-2.6.39.orig/arch/mips/ar71xx/nvram.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/nvram.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,75 @@ -+/* -+ * Atheros AR71xx minimal nvram support -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++static struct flash_platform_data tl_wr741nd_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = tl_wr741nd_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wr741nd_partitions), ++#endif ++}; + -+#include -+#include -+#include -+#include -+#include ++static struct gpio_led tl_wr741nd_leds_gpio[] __initdata = { ++ { ++ .name = "tl-wr741nd:green:system", ++ .gpio = TL_WR741ND_GPIO_LED_SYSTEM, ++ .active_low = 1, ++ }, { ++ .name = "tl-wr741nd:green:qss", ++ .gpio = TL_WR741ND_GPIO_LED_QSS, ++ .active_low = 1, ++ } ++}; + -+#include "nvram.h" ++static struct gpio_keys_button tl_wr741nd_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR741ND_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "qss", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR741ND_GPIO_BTN_QSS, ++ .active_low = 1, ++ } ++}; + -+char *nvram_find_var(const char *name, const char *buf, unsigned buf_len) ++static void __init tl_wr741nd_setup(void) +{ -+ unsigned len = strlen(name); -+ char *cur, *last; ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + -+ if (buf_len == 0 || len == 0) -+ return NULL; ++ ar71xx_add_device_m25p80(&tl_wr741nd_flash_data); + -+ if (buf_len < len) -+ return NULL; ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr741nd_leds_gpio), ++ tl_wr741nd_leds_gpio); + -+ if (len == 1) -+ return memchr(buf, (int) *name, buf_len); ++ ar71xx_register_gpio_keys_polled(-1, TL_WR741ND_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wr741nd_gpio_keys), ++ tl_wr741nd_gpio_keys); + -+ last = (char *) buf + buf_len - len; -+ for (cur = (char *) buf; cur <= last; cur++) -+ if (cur[0] == name[0] && memcmp(cur, name, len) == 0) -+ return cur + len; -+ -+ return NULL; -+} -+ -+int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, -+ const char *name, char *mac) -+{ -+ char *buf; -+ char *mac_str; -+ int ret; -+ int t; -+ -+ buf = vmalloc(nvram_len); -+ if (!buf) -+ return -ENOMEM; -+ -+ memcpy(buf, nvram, nvram_len); -+ buf[nvram_len - 1] = '\0'; ++ ar71xx_eth1_data.has_ar7240_switch = 1; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); + -+ mac_str = nvram_find_var(name, buf, nvram_len); -+ if (!mac_str) { -+ ret = -EINVAL; -+ goto free; -+ } ++ /* WAN port */ ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = BIT(4); + -+ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); ++ /* LAN ports */ ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; + -+ if (t != 6) { -+ ret = -EINVAL; -+ goto free; -+ } ++ ar71xx_add_device_mdio(0x0); ++ ar71xx_add_device_eth(1); ++ ar71xx_add_device_eth(0); + -+ ret = 0; ++ ap91_pci_setup_wmac_led_pin(1); + -+ free: -+ vfree(buf); -+ return ret; ++ ap91_pci_init(ee, mac); +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.h linux-2.6.39/arch/mips/ar71xx/nvram.h ---- linux-2.6.39.orig/arch/mips/ar71xx/nvram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/nvram.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,19 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_WR741ND, "TL-WR741ND", "TP-LINK TL-WR741ND", ++ tl_wr741nd_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c 2011-08-24 02:41:55.597982750 +0200 +@@ -0,0 +1,144 @@ +/* -+ * Atheros AR71xx minimal nvram support ++ * TP-LINK TL-WR841N board support + * + * Copyright (C) 2009 Gabor Juhos + * @@ -7545,7553 +7700,8833 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.h linux-2.6.39/arch/mips/ar71 + * by the Free Software Foundation. + */ + -+#ifndef _AR71XX_NVRAM_H -+#define _AR71XX_NVRAM_H -+ -+char *nvram_find_var(const char *name, const char *buf, -+ unsigned buf_len) __init; -+int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, -+ const char *name, char *mac) __init; ++#include ++#include + -+#endif /* _AR71XX_NVRAM_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci.c linux-2.6.39/arch/mips/ar71xx/pci.c ---- linux-2.6.39.orig/arch/mips/ar71xx/pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/pci.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,93 @@ -+/* -+ * Atheros AR71xx PCI setup code -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++#include + -+#include ++#include "machtype.h" ++#include "devices.h" ++#include "dev-dsa.h" ++#include "dev-m25p80.h" ++#include "dev-gpio-buttons.h" ++#include "dev-pb42-pci.h" ++#include "dev-leds-gpio.h" + -+#include ++#define TL_WR841ND_V1_GPIO_LED_SYSTEM 2 ++#define TL_WR841ND_V1_GPIO_LED_QSS_GREEN 4 ++#define TL_WR841ND_V1_GPIO_LED_QSS_RED 5 + -+#include -+#include ++#define TL_WR841ND_V1_GPIO_BTN_RESET 3 ++#define TL_WR841ND_V1_GPIO_BTN_QSS 7 + -+unsigned ar71xx_pci_nr_irqs __initdata; -+struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata; ++#define TL_WR841ND_V1_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL \ ++ (3 * TL_WR841ND_V1_KEYS_POLL_INTERVAL) + -+int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev); ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition tl_wr841n_v1_partitions[] = { ++ { ++ .name = "redboot", ++ .offset = 0, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "kernel", ++ .offset = 0x020000, ++ .size = 0x140000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x160000, ++ .size = 0x280000, ++ }, { ++ .name = "config", ++ .offset = 0x3e0000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x020000, ++ .size = 0x3c0000, ++ } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+static int ar71xx_be_handler(struct pt_regs *regs, int is_fixup) -+{ -+ int err = 0; ++static struct flash_platform_data tl_wr841n_v1_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = tl_wr841n_v1_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wr841n_v1_partitions), ++#endif ++}; + -+ err = ar71xx_pci_be_handler(is_fixup); ++static struct gpio_led tl_wr841n_v1_leds_gpio[] __initdata = { ++ { ++ .name = "tl-wr841n:green:system", ++ .gpio = TL_WR841ND_V1_GPIO_LED_SYSTEM, ++ .active_low = 1, ++ }, { ++ .name = "tl-wr841n:red:qss", ++ .gpio = TL_WR841ND_V1_GPIO_LED_QSS_RED, ++ }, { ++ .name = "tl-wr841n:green:qss", ++ .gpio = TL_WR841ND_V1_GPIO_LED_QSS_GREEN, ++ } ++}; + -+ return (is_fixup && !err) ? MIPS_BE_FIXUP : MIPS_BE_FATAL; -+} ++static struct gpio_keys_button tl_wr841n_v1_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR841ND_V1_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "qss", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR841ND_V1_GPIO_BTN_QSS, ++ .active_low = 1, ++ } ++}; + -+int pcibios_plat_dev_init(struct pci_dev *dev) -+{ -+ if (ar71xx_pci_plat_dev_init) -+ return ar71xx_pci_plat_dev_init(dev); ++static struct dsa_chip_data tl_wr841n_v1_dsa_chip = { ++ .port_names[0] = "wan", ++ .port_names[1] = "lan1", ++ .port_names[2] = "lan2", ++ .port_names[3] = "lan3", ++ .port_names[4] = "lan4", ++ .port_names[5] = "cpu", ++}; + -+ return 0; -+} ++static struct dsa_platform_data tl_wr841n_v1_dsa_data = { ++ .nr_chips = 1, ++ .chip = &tl_wr841n_v1_dsa_chip, ++}; + -+int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) ++static void __init tl_wr841n_v1_setup(void) +{ -+ int ret = 0; -+ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ ret = ar71xx_pcibios_map_irq(dev, slot, pin); -+ break; -+ -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ ret = ar724x_pcibios_map_irq(dev, slot, pin); -+ break; ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + -+ default: -+ break; -+ } ++ ar71xx_add_device_mdio(0x0); + -+ return ret; -+} ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+int __init ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) -+{ -+ int ret = 0; ++ ar71xx_add_device_eth(0); + -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ board_be_handler = ar71xx_be_handler; -+ ret = ar71xx_pcibios_init(); -+ break; ++ ar71xx_add_device_dsa(0, &tl_wr841n_v1_dsa_data); + -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ ret = ar724x_pcibios_init(); -+ break; ++ ar71xx_add_device_m25p80(&tl_wr841n_v1_flash_data); + -+ default: -+ return 0; -+ } ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v1_leds_gpio), ++ tl_wr841n_v1_leds_gpio); + -+ ar71xx_pci_nr_irqs = nr_irqs; -+ ar71xx_pci_irq_map = map; ++ ar71xx_register_gpio_keys_polled(-1, TL_WR841ND_V1_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wr841n_v1_gpio_keys), ++ tl_wr841n_v1_gpio_keys); + -+ return ret; ++ pb42_pci_init(); +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/prom.c linux-2.6.39/arch/mips/ar71xx/prom.c ---- linux-2.6.39.orig/arch/mips/ar71xx/prom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/prom.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,105 @@ ++ ++MIPS_MACHINE(AR71XX_MACH_TL_WR841N_V1, "TL-WR841N-v1.5", "TP-LINK TL-WR841N v1", ++ tl_wr841n_v1_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c 2011-08-24 02:41:55.597982750 +0200 +@@ -0,0 +1,147 @@ +/* -+ * Atheros AR71xx SoC specific prom routines ++ * TP-LINK TL-WR941ND board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009-2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+#include -+ -+#include -+#include ++#include ++#include + +#include + -+static inline int is_valid_ram_addr(void *addr) -+{ -+ if (((u32) addr > KSEG0) && -+ ((u32) addr < (KSEG0 + AR71XX_MEM_SIZE_MAX))) -+ return 1; -+ -+ if (((u32) addr > KSEG1) && -+ ((u32) addr < (KSEG1 + AR71XX_MEM_SIZE_MAX))) -+ return 1; -+ -+ return 0; -+} ++#include "machtype.h" ++#include "devices.h" ++#include "dev-dsa.h" ++#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" + -+static void __init ar71xx_prom_append_cmdline(const char *name, -+ const char *value) -+{ -+ char buf[COMMAND_LINE_SIZE]; ++#define TL_WR941ND_GPIO_LED_SYSTEM 2 ++#define TL_WR941ND_GPIO_LED_QSS_RED 4 ++#define TL_WR941ND_GPIO_LED_QSS_GREEN 5 ++#define TL_WR941ND_GPIO_LED_WLAN 9 + -+ snprintf(buf, sizeof(buf), " %s=%s", name, value); -+ strlcat(arcs_cmdline, buf, sizeof(arcs_cmdline)); -+} ++#define TL_WR941ND_GPIO_BTN_RESET 3 ++#define TL_WR941ND_GPIO_BTN_QSS 7 + -+static void __init ar71xx_prom_find_env(char **envp, const char *name) -+{ -+ int len = strlen(name); -+ char **p; ++#define TL_WR941ND_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WR941ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR941ND_KEYS_POLL_INTERVAL) + -+ if (!is_valid_ram_addr(envp)) -+ return; ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition tl_wr941nd_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "kernel", ++ .offset = 0x020000, ++ .size = 0x140000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x160000, ++ .size = 0x290000, ++ }, { ++ .name = "art", ++ .offset = 0x3f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x020000, ++ .size = 0x3d0000, ++ } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+ for (p = envp; is_valid_ram_addr(*p); p++) { -+ if (strncmp(name, *p, len) == 0 && (*p)[len] == '=') { -+ ar71xx_prom_append_cmdline(name, *p + len + 1); -+ break; -+ } ++static struct flash_platform_data tl_wr941nd_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = tl_wr941nd_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wr941nd_partitions), ++#endif ++}; + -+ /* RedBoot env comes in pointer pairs - key, value */ -+ if (strncmp(name, *p, len) == 0 && (*p)[len] == 0) -+ if (is_valid_ram_addr(*(++p))) { -+ ar71xx_prom_append_cmdline(name, *p); -+ break; -+ } ++static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = { ++ { ++ .name = "tl-wr941nd:green:system", ++ .gpio = TL_WR941ND_GPIO_LED_SYSTEM, ++ .active_low = 1, ++ }, { ++ .name = "tl-wr941nd:red:qss", ++ .gpio = TL_WR941ND_GPIO_LED_QSS_RED, ++ }, { ++ .name = "tl-wr941nd:green:qss", ++ .gpio = TL_WR941ND_GPIO_LED_QSS_GREEN, ++ }, { ++ .name = "tl-wr941nd:green:wlan", ++ .gpio = TL_WR941ND_GPIO_LED_WLAN, ++ .active_low = 1, + } -+} ++}; + -+static int inline ar71xx_use__image_cmdline(void) { return 0; } ++static struct gpio_keys_button tl_wr941nd_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR941ND_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "qss", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR941ND_GPIO_BTN_QSS, ++ .active_low = 1, ++ } ++}; + -+static __init void ar71xx_prom_init_cmdline(int argc, char **argv) -+{ -+ int i; ++static struct dsa_chip_data tl_wr941nd_dsa_chip = { ++ .port_names[0] = "wan", ++ .port_names[1] = "lan1", ++ .port_names[2] = "lan2", ++ .port_names[3] = "lan3", ++ .port_names[4] = "lan4", ++ .port_names[5] = "cpu", ++}; + -+ if (ar71xx_use__image_cmdline()) -+ return; ++static struct dsa_platform_data tl_wr941nd_dsa_data = { ++ .nr_chips = 1, ++ .chip = &tl_wr941nd_dsa_chip, ++}; + -+ if (!is_valid_ram_addr(argv)) -+ return; ++static void __init tl_wr941nd_setup(void) ++{ ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+ for (i = 0; i < argc; i++) -+ if (is_valid_ram_addr(argv[i])) { -+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); -+ strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline)); -+ } -+} ++ ar71xx_add_device_mdio(0x0); + -+void __init prom_init(void) -+{ -+ char **envp; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+ printk(KERN_DEBUG "prom: fw_arg0=%08x, fw_arg1=%08x, " -+ "fw_arg2=%08x, fw_arg3=%08x\n", -+ (unsigned int)fw_arg0, (unsigned int)fw_arg1, -+ (unsigned int)fw_arg2, (unsigned int)fw_arg3); ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_dsa(0, &tl_wr941nd_dsa_data); + ++ ar71xx_add_device_m25p80(&tl_wr941nd_flash_data); + -+ ar71xx_prom_init_cmdline(fw_arg0, (char **)fw_arg1); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio), ++ tl_wr941nd_leds_gpio); + -+ envp = (char **)fw_arg2; -+ ar71xx_prom_find_env(envp, "board"); ++ ar71xx_register_gpio_keys_polled(-1, TL_WR941ND_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wr941nd_gpio_keys), ++ tl_wr941nd_gpio_keys); ++ ar9xxx_add_device_wmac(eeprom, mac); +} + -+void __init prom_free_prom_memory(void) -+{ -+ /* We do not have to prom memory to free */ -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/setup.c linux-2.6.39/arch/mips/ar71xx/setup.c ---- linux-2.6.39.orig/arch/mips/ar71xx/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/setup.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,310 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_WR941ND, "TL-WR941ND", "TP-LINK TL-WR941ND", ++ tl_wr941nd_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/machtype.h linux-2.6.39/arch/mips/ar71xx/machtype.h +--- linux-2.6.39.orig/arch/mips/ar71xx/machtype.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/machtype.h 2011-08-24 02:41:55.597982750 +0200 +@@ -0,0 +1,75 @@ +/* -+ * Atheros AR71xx SoC specific setup ++ * Atheros AR71xx machine type definitions + * -+ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include ++#ifndef _AR71XX_MACHTYPE_H ++#define _AR71XX_MACHTYPE_H + -+#include -+#include /* for mips_hpt_frequency */ -+#include /* for _machine_{restart,halt} */ +#include + ++enum ar71xx_mach_type { ++ AR71XX_MACH_GENERIC = 0, ++ AR71XX_MACH_AP121, /* Atheros AP121 */ ++ AR71XX_MACH_AP121_MINI, /* Atheros AP121-MINI */ ++ AR71XX_MACH_AP81, /* Atheros AP81 */ ++ AR71XX_MACH_AP83, /* Atheros AP83 */ ++ AR71XX_MACH_AW_NR580, /* AzureWave AW-NR580 */ ++ AR71XX_MACH_DIR_600_A1, /* D-Link DIR-600 rev. A1 */ ++ AR71XX_MACH_DIR_615_C1, /* D-Link DIR-615 rev. C1 */ ++ AR71XX_MACH_DIR_825_B1, /* D-Link DIR-825 rev. B1 */ ++ AR71XX_MACH_JA76PF, /* jjPlus JA76PF */ ++ AR71XX_MACH_JWAP003, /* jjPlus JWAP003 */ ++ AR71XX_MACH_RB_411, /* MikroTik RouterBOARD 411/411A/411AH */ ++ AR71XX_MACH_RB_411U, /* MikroTik RouterBOARD 411U */ ++ AR71XX_MACH_RB_433, /* MikroTik RouterBOARD 433/433AH */ ++ AR71XX_MACH_RB_433U, /* MikroTik RouterBOARD 433UAH */ ++ AR71XX_MACH_RB_450, /* MikroTik RouterBOARD 450 */ ++ AR71XX_MACH_RB_450G, /* MikroTik RouterBOARD 450G */ ++ AR71XX_MACH_RB_493, /* Mikrotik RouterBOARD 493/493AH */ ++ AR71XX_MACH_RB_750, /* MikroTik RouterBOARD 750 */ ++ AR71XX_MACH_PB42, /* Atheros PB42 */ ++ AR71XX_MACH_PB44, /* Atheros PB44 */ ++ AR71XX_MACH_PB92, /* Atheros PB92 */ ++ AR71XX_MACH_MZK_W04NU, /* Planex MZK-W04NU */ ++ AR71XX_MACH_MZK_W300NH, /* Planex MZK-W300NH */ ++ AR71XX_MACH_NBG460N, /* Zyxel NBG460N/550N/550NH */ ++ AR71XX_MACH_TEW_632BRP, /* TRENDnet TEW-632BRP */ ++ AR71XX_MACH_TL_MR3220, /* TP-LINK TL-MR3220 */ ++ AR71XX_MACH_TL_MR3420, /* TP-LINK TL-MR3420 */ ++ AR71XX_MACH_TL_WA901ND, /* TP-LINK TL-WA901ND */ ++ AR71XX_MACH_TL_WA901ND_V2, /* TP-LINK TL-WA901ND v2 */ ++ AR71XX_MACH_TL_WR741ND, /* TP-LINK TL-WR741ND */ ++ AR71XX_MACH_TL_WR841N_V1, /* TP-LINK TL-WR841N v1 */ ++ AR71XX_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ ++ AR71XX_MACH_TL_WR1043ND, /* TP-LINK TL-WR1041ND */ ++ AR71XX_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */ ++ AR71XX_MACH_UBNT_LSX, /* Ubiquiti LSX */ ++ AR71XX_MACH_UBNT_RS, /* Ubiquiti RouterStation */ ++ AR71XX_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */ ++ AR71XX_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ ++ AR71XX_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */ ++ AR71XX_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */ ++ AR71XX_MACH_WNDR3700, /* NETGEAR WNDR3700 */ ++ AR71XX_MACH_WNDR3700V2, /* NETGEAR WNDR3700v2 */ ++ AR71XX_MACH_WNR2000, /* NETGEAR WNR2000 */ ++ AR71XX_MACH_WP543, /* Compex WP543 */ ++ AR71XX_MACH_WRT160NL, /* Linksys WRT160NL */ ++ AR71XX_MACH_WRT400N, /* Linksys WRT400N */ ++ AR71XX_MACH_WZR_HP_AG300H, /* Buffalo WZR-HP-AG300H */ ++ AR71XX_MACH_WZR_HP_G300NH, /* Buffalo WZR-HP-G300NH */ ++ AR71XX_MACH_EAP7660D, /* Senao EAP7660D */ ++ AR71XX_MACH_ZCN_1523H_2, /* Zcomax ZCN-1523H-2-xx */ ++ AR71XX_MACH_ZCN_1523H_5, /* Zcomax ZCN-1523H-5-xx */ ++ AR71XX_MACH_AP96, /* Atheros AP96 */ ++ AR71XX_MACH_UBNT_UNIFI, /* Unifi */ ++ AR71XX_MACH_DB120, /* Atheros DB120 (AR934x based) */ ++}; ++ ++#endif /* _AR71XX_MACHTYPE_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c 2011-08-24 02:41:55.597982750 +0200 +@@ -0,0 +1,333 @@ ++/* ++ * Ubiquiti RouterStation support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2008 Ubiquiti ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ +#include + +#include "machtype.h" +#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-ap91-pci.h" ++#include "dev-gpio-buttons.h" ++#include "dev-pb42-pci.h" ++#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+#define AR71XX_SYS_TYPE_LEN 64 -+#define AR71XX_BASE_FREQ 40000000 -+#define AR91XX_BASE_FREQ 5000000 -+#define AR724X_BASE_FREQ 5000000 -+ -+u32 ar71xx_cpu_freq; -+EXPORT_SYMBOL_GPL(ar71xx_cpu_freq); ++#define UBNT_RS_GPIO_LED_RF 2 ++#define UBNT_RS_GPIO_SW4 8 + -+u32 ar71xx_ahb_freq; -+EXPORT_SYMBOL_GPL(ar71xx_ahb_freq); ++#define UBNT_LS_SR71_GPIO_LED_D25 0 ++#define UBNT_LS_SR71_GPIO_LED_D26 1 ++#define UBNT_LS_SR71_GPIO_LED_D24 2 ++#define UBNT_LS_SR71_GPIO_LED_D23 4 ++#define UBNT_LS_SR71_GPIO_LED_D22 5 ++#define UBNT_LS_SR71_GPIO_LED_D27 6 ++#define UBNT_LS_SR71_GPIO_LED_D28 7 + -+u32 ar71xx_ddr_freq; -+EXPORT_SYMBOL_GPL(ar71xx_ddr_freq); -+ -+enum ar71xx_soc_type ar71xx_soc; -+EXPORT_SYMBOL_GPL(ar71xx_soc); ++#define UBNT_M_GPIO_LED_L1 0 ++#define UBNT_M_GPIO_LED_L2 1 ++#define UBNT_M_GPIO_LED_L3 11 ++#define UBNT_M_GPIO_LED_L4 7 ++#define UBNT_M_GPIO_BTN_RESET 12 + -+static char ar71xx_sys_type[AR71XX_SYS_TYPE_LEN]; ++#define UBNT_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define UBNT_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_KEYS_POLL_INTERVAL) + -+static void ar71xx_restart(char *command) -+{ -+ ar71xx_device_stop(RESET_MODULE_FULL_CHIP); -+ for (;;) -+ if (cpu_wait) -+ cpu_wait(); -+} ++static struct gpio_led ubnt_rs_leds_gpio[] __initdata = { ++ { ++ .name = "ubnt:green:rf", ++ .gpio = UBNT_RS_GPIO_LED_RF, ++ .active_low = 0, ++ } ++}; + -+static void ar71xx_halt(void) -+{ -+ while (1) -+ cpu_wait(); -+} ++static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = { ++ { ++ .name = "ubnt:green:d22", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D22, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:green:d23", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D23, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:green:d24", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D24, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:red:d25", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D25, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:red:d26", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D26, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:green:d27", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D27, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:green:d28", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D28, ++ .active_low = 0, ++ } ++}; + -+static void __init ar71xx_detect_mem_size(void) -+{ -+ unsigned long size; ++static struct gpio_led ubnt_m_leds_gpio[] __initdata = { ++ { ++ .name = "ubnt:red:link1", ++ .gpio = UBNT_M_GPIO_LED_L1, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:orange:link2", ++ .gpio = UBNT_M_GPIO_LED_L2, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:green:link3", ++ .gpio = UBNT_M_GPIO_LED_L3, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:green:link4", ++ .gpio = UBNT_M_GPIO_LED_L4, ++ .active_low = 0, ++ } ++}; + -+ for (size = AR71XX_MEM_SIZE_MIN; size < AR71XX_MEM_SIZE_MAX; -+ size <<= 1 ) { -+ if (!memcmp(ar71xx_detect_mem_size, -+ ar71xx_detect_mem_size + size, 1024)) -+ break; ++static struct gpio_keys_button ubnt_gpio_keys[] __initdata = { ++ { ++ .desc = "sw4", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = UBNT_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = UBNT_RS_GPIO_SW4, ++ .active_low = 1, + } ++}; + -+ add_memory_region(0, size, BOOT_MEM_RAM); -+} ++static struct gpio_keys_button ubnt_m_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = UBNT_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = UBNT_M_GPIO_BTN_RESET, ++ .active_low = 1, ++ } ++}; + -+static void __init ar71xx_detect_sys_type(void) ++static void __init ubnt_generic_setup(void) +{ -+ char *chip = "????"; -+ u32 id; -+ u32 major; -+ u32 minor; -+ u32 rev = 0; ++ ar71xx_add_device_m25p80(NULL); + -+ id = ar71xx_reset_rr(AR71XX_RESET_REG_REV_ID); -+ major = id & REV_ID_MAJOR_MASK; ++ ar71xx_register_gpio_keys_polled(-1, UBNT_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ubnt_gpio_keys), ++ ubnt_gpio_keys); + -+ switch (major) { -+ case REV_ID_MAJOR_AR71XX: -+ minor = id & AR71XX_REV_ID_MINOR_MASK; -+ rev = id >> AR71XX_REV_ID_REVISION_SHIFT; -+ rev &= AR71XX_REV_ID_REVISION_MASK; -+ switch (minor) { -+ case AR71XX_REV_ID_MINOR_AR7130: -+ ar71xx_soc = AR71XX_SOC_AR7130; -+ chip = "7130"; -+ break; ++ pb42_pci_init(); ++} + -+ case AR71XX_REV_ID_MINOR_AR7141: -+ ar71xx_soc = AR71XX_SOC_AR7141; -+ chip = "7141"; -+ break; ++/* ++ * There is Secondary MAC address duplicate problem with some UBNT HW batches. ++ * Do not increase Secondary MAC address by 1 but do workaround ++ * with 'Locally Administrated' bit. ++ */ ++static void __init ubnt_init_secondary_mac(unsigned char *mac_base) ++{ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac_base, 0); ++ ar71xx_eth1_data.mac_addr[0] |= 0x02; ++} + -+ case AR71XX_REV_ID_MINOR_AR7161: -+ ar71xx_soc = AR71XX_SOC_AR7161; -+ chip = "7161"; -+ break; -+ } -+ break; ++#define UBNT_RS_WAN_PHYMASK BIT(20) ++#define UBNT_RS_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19)) + -+ case REV_ID_MAJOR_AR7240: -+ ar71xx_soc = AR71XX_SOC_AR7240; -+ chip = "7240"; -+ rev = (id & AR724X_REV_ID_REVISION_MASK); -+ break; ++static void __init ubnt_rs_setup(void) ++{ ++ ubnt_generic_setup(); + -+ case REV_ID_MAJOR_AR7241: -+ ar71xx_soc = AR71XX_SOC_AR7241; -+ chip = "7241"; -+ rev = (id & AR724X_REV_ID_REVISION_MASK); -+ break; ++ ar71xx_add_device_mdio(~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK)); + -+ case REV_ID_MAJOR_AR7242: -+ ar71xx_soc = AR71XX_SOC_AR7242; -+ chip = "7242"; -+ rev = (id & AR724X_REV_ID_REVISION_MASK); -+ break; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK; + -+ case REV_ID_MAJOR_AR913X: -+ minor = id & AR91XX_REV_ID_MINOR_MASK; -+ rev = id >> AR91XX_REV_ID_REVISION_SHIFT; -+ rev &= AR91XX_REV_ID_REVISION_MASK; -+ switch (minor) { -+ case AR91XX_REV_ID_MINOR_AR9130: -+ ar71xx_soc = AR71XX_SOC_AR9130; -+ chip = "9130"; -+ break; ++ ubnt_init_secondary_mac(ar71xx_mac_base); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_100; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; + -+ case AR91XX_REV_ID_MINOR_AR9132: -+ ar71xx_soc = AR71XX_SOC_AR9132; -+ chip = "9132"; -+ break; -+ } -+ break; ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ default: -+ panic("ar71xx: unknown chip id:0x%08x\n", id); -+ } ++ ar71xx_add_device_usb(); + -+ sprintf(ar71xx_sys_type, "Atheros AR%s rev %u", chip, rev); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), ++ ubnt_rs_leds_gpio); +} + -+static void __init ar91xx_detect_sys_frequency(void) ++MIPS_MACHINE(AR71XX_MACH_UBNT_RS, "UBNT-RS", "Ubiquiti RouterStation", ++ ubnt_rs_setup); ++ ++#define UBNT_RSPRO_WAN_PHYMASK BIT(4) ++#define UBNT_RSPRO_LAN_PHYMASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) ++ ++static void __init ubnt_rspro_setup(void) +{ -+ u32 pll; -+ u32 freq; -+ u32 div; ++ ubnt_generic_setup(); + -+ pll = ar71xx_pll_rr(AR91XX_PLL_REG_CPU_CONFIG); ++ ar71xx_add_device_mdio(~(UBNT_RSPRO_WAN_PHYMASK | ++ UBNT_RSPRO_LAN_PHYMASK)); + -+ div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK); -+ freq = div * AR91XX_BASE_FREQ; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = UBNT_RSPRO_WAN_PHYMASK; + -+ ar71xx_cpu_freq = freq; ++ ubnt_init_secondary_mac(ar71xx_mac_base); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = UBNT_RSPRO_LAN_PHYMASK; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; + -+ div = ((pll >> AR91XX_DDR_DIV_SHIFT) & AR91XX_DDR_DIV_MASK) + 1; -+ ar71xx_ddr_freq = freq / div; ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ div = (((pll >> AR91XX_AHB_DIV_SHIFT) & AR91XX_AHB_DIV_MASK) + 1) * 2; -+ ar71xx_ahb_freq = ar71xx_cpu_freq / div; ++ ar71xx_add_device_usb(); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), ++ ubnt_rs_leds_gpio); +} + -+static void __init ar71xx_detect_sys_frequency(void) ++MIPS_MACHINE(AR71XX_MACH_UBNT_RSPRO, "UBNT-RSPRO", "Ubiquiti RouterStation Pro", ++ ubnt_rspro_setup); ++ ++static void __init ubnt_lsx_setup(void) +{ -+ u32 pll; -+ u32 freq; -+ u32 div; ++ ubnt_generic_setup(); ++} + -+ pll = ar71xx_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); ++MIPS_MACHINE(AR71XX_MACH_UBNT_LSX, "UBNT-LSX", "Ubiquiti LSX", ubnt_lsx_setup); + -+ div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; -+ freq = div * AR71XX_BASE_FREQ; ++#define UBNT_LSSR71_PHY_MASK BIT(1) + -+ div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; -+ ar71xx_cpu_freq = freq / div; ++static void __init ubnt_lssr71_setup(void) ++{ ++ ubnt_generic_setup(); + -+ div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; -+ ar71xx_ddr_freq = freq / div; ++ ar71xx_add_device_mdio(~UBNT_LSSR71_PHY_MASK); + -+ div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; -+ ar71xx_ahb_freq = ar71xx_cpu_freq / div; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK; ++ ++ ar71xx_add_device_eth(0); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio), ++ ubnt_ls_sr71_leds_gpio); +} + -+static void __init ar724x_detect_sys_frequency(void) ++MIPS_MACHINE(AR71XX_MACH_UBNT_LSSR71, "UBNT-LS-SR71", "Ubiquiti LS-SR71", ++ ubnt_lssr71_setup); ++ ++#define UBNT_M_WAN_PHYMASK BIT(4) ++ ++static void __init ubnt_m_setup(void) +{ -+ u32 pll; -+ u32 freq; -+ u32 div; ++ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + -+ pll = ar71xx_pll_rr(AR724X_PLL_REG_CPU_CONFIG); ++ ar71xx_add_device_m25p80(NULL); + -+ div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); -+ freq = div * AR724X_BASE_FREQ; ++ ar71xx_add_device_mdio(~UBNT_M_WAN_PHYMASK); + -+ div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); -+ freq *= div; -+ -+ ar71xx_cpu_freq = freq; -+ -+ div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; -+ ar71xx_ddr_freq = freq / div; -+ -+ div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; -+ ar71xx_ahb_freq = ar71xx_cpu_freq / div; -+} ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac1, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac2, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = UBNT_M_WAN_PHYMASK; + -+static void __init detect_sys_frequency(void) -+{ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ ar71xx_detect_sys_frequency(); -+ break; ++ ar71xx_add_device_eth(0); + -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ ar724x_detect_sys_frequency(); -+ break; ++ ap91_pci_init(ee, NULL); + -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ ar91xx_detect_sys_frequency(); -+ break; ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_m_leds_gpio), ++ ubnt_m_leds_gpio); + -+ default: -+ BUG(); -+ } ++ ar71xx_register_gpio_keys_polled(-1, UBNT_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ubnt_m_gpio_keys), ++ ubnt_m_gpio_keys); +} + -+const char *get_system_type(void) ++static void __init ubnt_rocket_m_setup(void) +{ -+ return ar71xx_sys_type; ++ ubnt_m_setup(); ++ ar71xx_add_device_usb(); +} + -+unsigned int __cpuinit get_c0_compare_irq(void) -+{ -+ return CP0_LEGACY_COMPARE_IRQ; -+} ++MIPS_MACHINE(AR71XX_MACH_UBNT_BULLET_M, "UBNT-BM", "Ubiquiti Bullet M", ++ ubnt_m_setup); ++MIPS_MACHINE(AR71XX_MACH_UBNT_ROCKET_M, "UBNT-RM", "Ubiquiti Rocket M", ++ ubnt_rocket_m_setup); + -+void __init plat_mem_setup(void) ++/* TODO detect the second ethernet port and use one ++ init function for all Ubiquiti MIMO series products */ ++static void __init ubnt_nano_m_setup(void) +{ -+ set_io_port_base(KSEG1); -+ -+ ar71xx_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, -+ AR71XX_DDR_CTRL_SIZE); -+ -+ ar71xx_pll_base = ioremap_nocache(AR71XX_PLL_BASE, -+ AR71XX_PLL_SIZE); -+ -+ ar71xx_reset_base = ioremap_nocache(AR71XX_RESET_BASE, -+ AR71XX_RESET_SIZE); -+ -+ ar71xx_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); ++ ubnt_m_setup(); + -+ ar71xx_usb_ctrl_base = ioremap_nocache(AR71XX_USB_CTRL_BASE, -+ AR71XX_USB_CTRL_SIZE); ++ ar71xx_eth1_data.has_ar7240_switch = 1; ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; + -+ ar71xx_detect_mem_size(); -+ ar71xx_detect_sys_type(); -+ detect_sys_frequency(); ++ ar71xx_add_device_eth(1); ++} + -+ printk(KERN_INFO -+ "%s, CPU:%u.%03u MHz, AHB:%u.%03u MHz, DDR:%u.%03u MHz\n", -+ ar71xx_sys_type, -+ ar71xx_cpu_freq / 1000000, (ar71xx_cpu_freq / 1000) % 1000, -+ ar71xx_ahb_freq / 1000000, (ar71xx_ahb_freq / 1000) % 1000, -+ ar71xx_ddr_freq / 1000000, (ar71xx_ddr_freq / 1000) % 1000); ++MIPS_MACHINE(AR71XX_MACH_UBNT_NANO_M, "UBNT-NM", "Ubiquiti Nanostation M", ++ ubnt_nano_m_setup); + -+ _machine_restart = ar71xx_restart; -+ _machine_halt = ar71xx_halt; -+ pm_power_off = ar71xx_halt; -+} ++static struct gpio_led ubnt_unifi_leds_gpio[] __initdata = { ++ { ++ .name = "ubnt:orange:dome", ++ .gpio = 1, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:green:dome", ++ .gpio = 0, ++ .active_low = 0, ++ } ++}; + -+void __init plat_time_init(void) ++static void __init ubnt_unifi_setup(void) +{ -+ mips_hpt_frequency = ar71xx_cpu_freq / 2; -+} ++ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + -+__setup("board=", mips_machtype_setup); ++ ar71xx_add_device_m25p80(NULL); + -+static int __init ar71xx_machine_setup(void) -+{ -+ ar71xx_gpio_init(); ++ ar71xx_add_device_mdio(~UBNT_M_WAN_PHYMASK); + -+ ar71xx_add_device_uart(); -+ ar71xx_add_device_wdt(); ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = UBNT_M_WAN_PHYMASK; + -+ mips_machine_setup(); -+ return 0; -+} ++ ar71xx_add_device_eth(0); + -+arch_initcall(ar71xx_machine_setup); ++ ap91_pci_init(ee, NULL); + -+static void __init ar71xx_generic_init(void) -+{ -+ /* Nothing to do */ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_leds_gpio), ++ ubnt_unifi_leds_gpio); +} + -+MIPS_MACHINE(AR71XX_MACH_GENERIC, "Generic", "Generic AR71xx board", -+ ar71xx_generic_init); -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,514 @@ ++MIPS_MACHINE(AR71XX_MACH_UBNT_UNIFI, "UBNT-XM", "Ubiquiti UniFi", ++ ubnt_unifi_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c 2011-08-24 02:41:55.607980283 +0200 +@@ -0,0 +1,290 @@ +/* -+ * Atheros AR71xx SoC specific definitions -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Netgear WNDR3700 board support + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Copyright (C) 2009 Marco Porsch ++ * Copyright (C) 2009-2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#ifndef __ASM_MACH_AR71XX_H -+#define __ASM_MACH_AR71XX_H -+ -+#include -+#include -+#include -+#include -+ -+#ifndef __ASSEMBLER__ -+ -+#define AR71XX_PCI_MEM_BASE 0x10000000 -+#define AR71XX_PCI_MEM_SIZE 0x08000000 -+#define AR71XX_APB_BASE 0x18000000 -+#define AR71XX_GE0_BASE 0x19000000 -+#define AR71XX_GE0_SIZE 0x01000000 -+#define AR71XX_GE1_BASE 0x1a000000 -+#define AR71XX_GE1_SIZE 0x01000000 -+#define AR71XX_EHCI_BASE 0x1b000000 -+#define AR71XX_EHCI_SIZE 0x01000000 -+#define AR71XX_OHCI_BASE 0x1c000000 -+#define AR71XX_OHCI_SIZE 0x01000000 -+#define AR7240_OHCI_BASE 0x1b000000 -+#define AR7240_OHCI_SIZE 0x01000000 -+#define AR71XX_SPI_BASE 0x1f000000 -+#define AR71XX_SPI_SIZE 0x01000000 -+ -+#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000) -+#define AR71XX_DDR_CTRL_SIZE 0x10000 -+#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000) -+#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000) -+#define AR71XX_UART_SIZE 0x10000 -+#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) -+#define AR71XX_USB_CTRL_SIZE 0x10000 -+#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000) -+#define AR71XX_GPIO_SIZE 0x10000 -+#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000) -+#define AR71XX_PLL_SIZE 0x10000 -+#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) -+#define AR71XX_RESET_SIZE 0x10000 -+#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000) -+#define AR71XX_MII_SIZE 0x10000 -+#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000) -+#define AR71XX_SLIC_SIZE 0x10000 -+#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000) -+#define AR71XX_DMA_SIZE 0x10000 -+#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000) -+#define AR71XX_STEREO_SIZE 0x10000 -+ -+#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000) -+#define AR724X_PCI_CRP_SIZE 0x100 -+ -+#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000) -+#define AR724X_PCI_CTRL_SIZE 0x100 -+ -+#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000) -+#define AR91XX_WMAC_SIZE 0x30000 -+ -+#define AR71XX_MEM_SIZE_MIN 0x0200000 -+#define AR71XX_MEM_SIZE_MAX 0x10000000 ++#include ++#include ++#include ++#include ++#include + -+#define AR71XX_CPU_IRQ_BASE 0 -+#define AR71XX_MISC_IRQ_BASE 8 -+#define AR71XX_MISC_IRQ_COUNT 8 -+#define AR71XX_GPIO_IRQ_BASE 16 -+#define AR71XX_GPIO_IRQ_COUNT 32 -+#define AR71XX_PCI_IRQ_BASE 48 -+#define AR71XX_PCI_IRQ_COUNT 8 ++#include + -+#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2) -+#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3) -+#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4) -+#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5) -+#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6) -+#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7) ++#include "machtype.h" ++#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-ap94-pci.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0) -+#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1) -+#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2) -+#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3) -+#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4) -+#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5) -+#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6) -+#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7) ++#define WNDR3700_GPIO_LED_WPS_ORANGE 0 ++#define WNDR3700_GPIO_LED_POWER_ORANGE 1 ++#define WNDR3700_GPIO_LED_POWER_GREEN 2 ++#define WNDR3700_GPIO_LED_WPS_GREEN 4 ++#define WNDR3700_GPIO_LED_WAN_GREEN 6 + -+#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x)) ++#define WNDR3700_GPIO_BTN_WPS 3 ++#define WNDR3700_GPIO_BTN_RESET 8 ++#define WNDR3700_GPIO_BTN_WIFI 11 + -+#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0) -+#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1) -+#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2) -+#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4) ++#define WNDR3700_GPIO_RTL8366_SDA 5 ++#define WNDR3700_GPIO_RTL8366_SCK 7 + -+extern u32 ar71xx_ahb_freq; -+extern u32 ar71xx_cpu_freq; -+extern u32 ar71xx_ddr_freq; ++#define WNDR3700_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WNDR3700_KEYS_DEBOUNCE_INTERVAL (3 * WNDR3700_KEYS_POLL_INTERVAL) + -+enum ar71xx_soc_type { -+ AR71XX_SOC_UNKNOWN, -+ AR71XX_SOC_AR7130, -+ AR71XX_SOC_AR7141, -+ AR71XX_SOC_AR7161, -+ AR71XX_SOC_AR7240, -+ AR71XX_SOC_AR7241, -+ AR71XX_SOC_AR7242, -+ AR71XX_SOC_AR9130, -+ AR71XX_SOC_AR9132 -+}; ++#define WNDR3700_ETH0_MAC_OFFSET 0 ++#define WNDR3700_ETH1_MAC_OFFSET 0x6 + -+extern enum ar71xx_soc_type ar71xx_soc; ++#define WNDR3700_WMAC0_MAC_OFFSET 0 ++#define WNDR3700_WMAC1_MAC_OFFSET 0xc ++#define WNDR3700_CALDATA0_OFFSET 0x1000 ++#define WNDR3700_CALDATA1_OFFSET 0x5000 + -+/* -+ * PLL block -+ */ -+#define AR71XX_PLL_REG_CPU_CONFIG 0x00 -+#define AR71XX_PLL_REG_SEC_CONFIG 0x04 -+#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 -+#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition wndr3700_partitions[] = { ++ { ++ .name = "uboot", ++ .offset = 0, ++ .size = 0x050000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "env", ++ .offset = 0x050000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "rootfs", ++ .offset = 0x070000, ++ .size = 0x720000, ++ }, { ++ .name = "config", ++ .offset = 0x790000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "config_bak", ++ .offset = 0x7a0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "pot", ++ .offset = 0x7b0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "traffic_meter", ++ .offset = 0x7c0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "language", ++ .offset = 0x7d0000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "caldata", ++ .offset = 0x7f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ } ++}; + -+#define AR71XX_PLL_DIV_SHIFT 3 -+#define AR71XX_PLL_DIV_MASK 0x1f -+#define AR71XX_CPU_DIV_SHIFT 16 -+#define AR71XX_CPU_DIV_MASK 0x3 -+#define AR71XX_DDR_DIV_SHIFT 18 -+#define AR71XX_DDR_DIV_MASK 0x3 -+#define AR71XX_AHB_DIV_SHIFT 20 -+#define AR71XX_AHB_DIV_MASK 0x7 ++static struct mtd_partition wndr3700v2_partitions[] = { ++ { ++ .name = "uboot", ++ .offset = 0, ++ .size = 0x050000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "env", ++ .offset = 0x050000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "rootfs", ++ .offset = 0x070000, ++ .size = 0xe40000, ++ }, { ++ .name = "config", ++ .offset = 0xeb0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "config_bak", ++ .offset = 0xec0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "pot", ++ .offset = 0xed0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "traffic_meter", ++ .offset = 0xee0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "language", ++ .offset = 0xef0000, ++ .size = 0x100000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "caldata", ++ .offset = 0xff0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ } ++}; ++#define wndr3700_num_partitions ARRAY_SIZE(wndr3700_partitions) ++#define wndr3700v2_num_partitions ARRAY_SIZE(wndr3700v2_partitions) ++#else ++#define wndr3700_partitions NULL ++#define wndr3700_num_partitions 0 ++#define wndr3700v2_partitions NULL ++#define wndr3700v2_num_partitions 0 ++#endif /* CONFIG_MTD_PARTITIONS */ + -+#define AR71XX_ETH0_PLL_SHIFT 17 -+#define AR71XX_ETH1_PLL_SHIFT 19 ++static struct flash_platform_data wndr3700_flash_data; + -+#define AR724X_PLL_REG_CPU_CONFIG 0x00 -+#define AR724X_PLL_REG_PCIE_CONFIG 0x18 ++static struct gpio_led wndr3700_leds_gpio[] __initdata = { ++ { ++ .name = "wndr3700:green:power", ++ .gpio = WNDR3700_GPIO_LED_POWER_GREEN, ++ .active_low = 1, ++ }, { ++ .name = "wndr3700:orange:power", ++ .gpio = WNDR3700_GPIO_LED_POWER_ORANGE, ++ .active_low = 1, ++ }, { ++ .name = "wndr3700:green:wps", ++ .gpio = WNDR3700_GPIO_LED_WPS_GREEN, ++ .active_low = 1, ++ }, { ++ .name = "wndr3700:orange:wps", ++ .gpio = WNDR3700_GPIO_LED_WPS_ORANGE, ++ .active_low = 1, ++ }, { ++ .name = "wndr3700:green:wan", ++ .gpio = WNDR3700_GPIO_LED_WAN_GREEN, ++ .active_low = 1, ++ } ++}; + -+#define AR724X_PLL_DIV_SHIFT 0 -+#define AR724X_PLL_DIV_MASK 0x3ff -+#define AR724X_PLL_REF_DIV_SHIFT 10 -+#define AR724X_PLL_REF_DIV_MASK 0xf -+#define AR724X_AHB_DIV_SHIFT 19 -+#define AR724X_AHB_DIV_MASK 0x1 -+#define AR724X_DDR_DIV_SHIFT 22 -+#define AR724X_DDR_DIV_MASK 0x3 ++static struct gpio_keys_button wndr3700_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNDR3700_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "wps", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNDR3700_GPIO_BTN_WPS, ++ .active_low = 1, ++ }, { ++ .desc = "wifi", ++ .type = EV_KEY, ++ .code = BTN_2, ++ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNDR3700_GPIO_BTN_WIFI, ++ .active_low = 1, ++ } ++}; + -+#define AR91XX_PLL_REG_CPU_CONFIG 0x00 -+#define AR91XX_PLL_REG_ETH_CONFIG 0x04 -+#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14 -+#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18 ++static struct rtl8366_platform_data wndr3700_rtl8366s_data = { ++ .gpio_sda = WNDR3700_GPIO_RTL8366_SDA, ++ .gpio_sck = WNDR3700_GPIO_RTL8366_SCK, ++}; + -+#define AR91XX_PLL_DIV_SHIFT 0 -+#define AR91XX_PLL_DIV_MASK 0x3ff -+#define AR91XX_DDR_DIV_SHIFT 22 -+#define AR91XX_DDR_DIV_MASK 0x3 -+#define AR91XX_AHB_DIV_SHIFT 19 -+#define AR91XX_AHB_DIV_MASK 0x1 ++static struct platform_device wndr3700_rtl8366s_device = { ++ .name = RTL8366S_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &wndr3700_rtl8366s_data, ++ } ++}; + -+#define AR91XX_ETH0_PLL_SHIFT 20 -+#define AR91XX_ETH1_PLL_SHIFT 22 ++static void __init wndr3700_common_setup(void) ++{ ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + -+extern void __iomem *ar71xx_pll_base; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ++ art + WNDR3700_ETH0_MAC_OFFSET, 0); ++ ar71xx_eth0_pll_data.pll_1000 = 0x11110000; ++ ar71xx_eth0_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+static inline void ar71xx_pll_wr(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_pll_base + reg); -+} ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ++ art + WNDR3700_ETH1_MAC_OFFSET, 0); ++ ar71xx_eth1_pll_data.pll_1000 = 0x11110000; ++ ar71xx_eth1_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = 0x10; + -+static inline u32 ar71xx_pll_rr(unsigned reg) -+{ -+ return __raw_readl(ar71xx_pll_base + reg); -+} ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+/* -+ * USB_CONFIG block -+ */ -+#define USB_CTRL_REG_FLADJ 0x00 -+#define USB_CTRL_REG_CONFIG 0x04 ++ ar71xx_add_device_usb(); + -+extern void __iomem *ar71xx_usb_ctrl_base; ++ ar71xx_add_device_m25p80(&wndr3700_flash_data); + -+static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val) ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wndr3700_leds_gpio), ++ wndr3700_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, WNDR3700_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wndr3700_gpio_keys), ++ wndr3700_gpio_keys); ++ ++ platform_device_register(&wndr3700_rtl8366s_device); ++ platform_device_register_simple("wndr3700-led-usb", -1, NULL, 0); ++ ++ ap94_pci_setup_wmac_led_pin(0, 5); ++ ap94_pci_setup_wmac_led_pin(1, 5); ++ ++ /* 2.4 GHz uses the first fixed antenna group (1, 0, 1, 0) */ ++ ap94_pci_setup_wmac_gpio(0, (0xf << 6), (0xa << 6)); ++ ++ /* 5 GHz uses the second fixed antenna group (0, 1, 1, 0) */ ++ ap94_pci_setup_wmac_gpio(1, (0xf << 6), (0x6 << 6)); ++ ++ ap94_pci_init(art + WNDR3700_CALDATA0_OFFSET, ++ art + WNDR3700_WMAC0_MAC_OFFSET, ++ art + WNDR3700_CALDATA1_OFFSET, ++ art + WNDR3700_WMAC1_MAC_OFFSET); ++} ++ ++static void __init wndr3700_setup(void) +{ -+ __raw_writel(val, ar71xx_usb_ctrl_base + reg); ++ wndr3700_flash_data.parts = wndr3700_partitions, ++ wndr3700_flash_data.nr_parts = wndr3700_num_partitions, ++ wndr3700_common_setup(); +} + -+static inline u32 ar71xx_usb_ctrl_rr(unsigned reg) ++MIPS_MACHINE(AR71XX_MACH_WNDR3700, "WNDR3700", "NETGEAR WNDR3700", ++ wndr3700_setup); ++ ++static void __init wndr3700v2_setup(void) +{ -+ return __raw_readl(ar71xx_usb_ctrl_base + reg); ++ wndr3700_flash_data.parts = wndr3700v2_partitions, ++ wndr3700_flash_data.nr_parts = wndr3700v2_num_partitions, ++ wndr3700_common_setup(); +} + ++MIPS_MACHINE(AR71XX_MACH_WNDR3700V2, "WNDR3700v2", "NETGEAR WNDR3700v2", ++ wndr3700v2_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c 2011-08-24 02:41:55.617990333 +0200 +@@ -0,0 +1,150 @@ +/* -+ * GPIO block ++ * NETGEAR WNR2000 board support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2008-2009 Andy Boyett ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + */ -+#define GPIO_REG_OE 0x00 -+#define GPIO_REG_IN 0x04 -+#define GPIO_REG_OUT 0x08 -+#define GPIO_REG_SET 0x0c -+#define GPIO_REG_CLEAR 0x10 -+#define GPIO_REG_INT_MODE 0x14 -+#define GPIO_REG_INT_TYPE 0x18 -+#define GPIO_REG_INT_POLARITY 0x1c -+#define GPIO_REG_INT_PENDING 0x20 -+#define GPIO_REG_INT_ENABLE 0x24 -+#define GPIO_REG_FUNC 0x28 + -+#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17) -+#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16) -+#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13) -+#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12) -+#define AR71XX_GPIO_FUNC_UART_EN BIT(8) -+#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4) -+#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0) ++#include ++#include + -+#define AR71XX_GPIO_COUNT 16 ++#include + -+#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19) -+#define AR724X_GPIO_FUNC_SPI_EN BIT(18) -+#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14) -+#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13) -+#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12) -+#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11) -+#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10) -+#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9) -+#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) -+#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) -+#define AR724X_GPIO_FUNC_UART_EN BIT(1) -+#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0) ++#include "machtype.h" ++#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" + -+#define AR724X_GPIO_COUNT 18 ++#define WNR2000_GPIO_LED_PWR_GREEN 14 ++#define WNR2000_GPIO_LED_PWR_AMBER 7 ++#define WNR2000_GPIO_LED_WPS 4 ++#define WNR2000_GPIO_LED_WLAN 6 ++#define WNR2000_GPIO_BTN_RESET 21 ++#define WNR2000_GPIO_BTN_WPS 8 + -+#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22) -+#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21) -+#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20) -+#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19) -+#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18) -+#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17) -+#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16) -+#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9) -+#define AR91XX_GPIO_FUNC_UART_EN BIT(8) -+#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4) ++#define WNR2000_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WNR2000_KEYS_DEBOUNCE_INTERVAL (3 * WNR2000_KEYS_POLL_INTERVAL) + -+#define AR91XX_GPIO_COUNT 22 ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition wnr2000_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x050000, ++ .size = 0x240000, ++ }, { ++ .name = "user-config", ++ .offset = 0x290000, ++ .size = 0x010000, ++ }, { ++ .name = "uImage", ++ .offset = 0x2a0000, ++ .size = 0x120000, ++ }, { ++ .name = "language_table", ++ .offset = 0x3c0000, ++ .size = 0x020000, ++ }, { ++ .name = "rootfs_checksum", ++ .offset = 0x3e0000, ++ .size = 0x010000, ++ }, { ++ .name = "art", ++ .offset = 0x3f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+extern void __iomem *ar71xx_gpio_base; ++static struct flash_platform_data wnr2000_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = wnr2000_partitions, ++ .nr_parts = ARRAY_SIZE(wnr2000_partitions), ++#endif ++}; + -+static inline void ar71xx_gpio_wr(unsigned reg, u32 value) -+{ -+ __raw_writel(value, ar71xx_gpio_base + reg); -+} ++static struct gpio_led wnr2000_leds_gpio[] __initdata = { ++ { ++ .name = "wnr2000:green:power", ++ .gpio = WNR2000_GPIO_LED_PWR_GREEN, ++ .active_low = 1, ++ }, { ++ .name = "wnr2000:amber:power", ++ .gpio = WNR2000_GPIO_LED_PWR_AMBER, ++ .active_low = 1, ++ }, { ++ .name = "wnr2000:green:wps", ++ .gpio = WNR2000_GPIO_LED_WPS, ++ .active_low = 1, ++ }, { ++ .name = "wnr2000:blue:wlan", ++ .gpio = WNR2000_GPIO_LED_WLAN, ++ .active_low = 1, ++ } ++}; + -+static inline u32 ar71xx_gpio_rr(unsigned reg) ++static struct gpio_keys_button wnr2000_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNR2000_GPIO_BTN_RESET, ++ }, { ++ .desc = "wps", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNR2000_GPIO_BTN_WPS, ++ } ++}; ++ ++static void __init wnr2000_setup(void) +{ -+ return __raw_readl(ar71xx_gpio_base + reg); -+} ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+void ar71xx_gpio_init(void) __init; -+void ar71xx_gpio_function_enable(u32 mask); -+void ar71xx_gpio_function_disable(u32 mask); -+void ar71xx_gpio_function_setup(u32 set, u32 clear); ++ ar71xx_add_device_mdio(0x0); + -+/* -+ * DDR_CTRL block -+ */ -+#define AR71XX_DDR_REG_PCI_WIN0 0x7c -+#define AR71XX_DDR_REG_PCI_WIN1 0x80 -+#define AR71XX_DDR_REG_PCI_WIN2 0x84 -+#define AR71XX_DDR_REG_PCI_WIN3 0x88 -+#define AR71XX_DDR_REG_PCI_WIN4 0x8c -+#define AR71XX_DDR_REG_PCI_WIN5 0x90 -+#define AR71XX_DDR_REG_PCI_WIN6 0x94 -+#define AR71XX_DDR_REG_PCI_WIN7 0x98 -+#define AR71XX_DDR_REG_FLUSH_GE0 0x9c -+#define AR71XX_DDR_REG_FLUSH_GE1 0xa0 -+#define AR71XX_DDR_REG_FLUSH_USB 0xa4 -+#define AR71XX_DDR_REG_FLUSH_PCI 0xa8 ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.has_ar8216 = 1; + -+#define AR724X_DDR_REG_FLUSH_GE0 0x7c -+#define AR724X_DDR_REG_FLUSH_GE1 0x80 -+#define AR724X_DDR_REG_FLUSH_USB 0x84 -+#define AR724X_DDR_REG_FLUSH_PCIE 0x88 ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = 0x10; + -+#define AR91XX_DDR_REG_FLUSH_GE0 0x7c -+#define AR91XX_DDR_REG_FLUSH_GE1 0x80 -+#define AR91XX_DDR_REG_FLUSH_USB 0x84 -+#define AR91XX_DDR_REG_FLUSH_WMAC 0x88 ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+#define PCI_WIN0_OFFS 0x10000000 -+#define PCI_WIN1_OFFS 0x11000000 -+#define PCI_WIN2_OFFS 0x12000000 -+#define PCI_WIN3_OFFS 0x13000000 -+#define PCI_WIN4_OFFS 0x14000000 -+#define PCI_WIN5_OFFS 0x15000000 -+#define PCI_WIN6_OFFS 0x16000000 -+#define PCI_WIN7_OFFS 0x07000000 ++ ar71xx_add_device_m25p80(&wnr2000_flash_data); + -+extern void __iomem *ar71xx_ddr_base; ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio), ++ wnr2000_leds_gpio); + -+static inline void ar71xx_ddr_wr(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_ddr_base + reg); -+} ++ ar71xx_register_gpio_keys_polled(-1, WNR2000_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wnr2000_gpio_keys), ++ wnr2000_gpio_keys); + -+static inline u32 ar71xx_ddr_rr(unsigned reg) -+{ -+ return __raw_readl(ar71xx_ddr_base + reg); -+} + -+void ar71xx_ddr_flush(u32 reg); ++ ar9xxx_add_device_wmac(eeprom, NULL); ++} + ++MIPS_MACHINE(AR71XX_MACH_WNR2000, "WNR2000", "NETGEAR WNR2000", wnr2000_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.39/arch/mips/ar71xx/mach-wp543.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wp543.c 2011-08-24 02:41:55.617990333 +0200 +@@ -0,0 +1,101 @@ +/* -+ * PCI block ++ * Compex WP543/WPJ543 board support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + */ -+#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000) -+#define AR71XX_PCI_CFG_SIZE 0x100 -+ -+#define PCI_REG_CRP_AD_CBE 0x00 -+#define PCI_REG_CRP_WRDATA 0x04 -+#define PCI_REG_CRP_RDDATA 0x08 -+#define PCI_REG_CFG_AD 0x0c -+#define PCI_REG_CFG_CBE 0x10 -+#define PCI_REG_CFG_WRDATA 0x14 -+#define PCI_REG_CFG_RDDATA 0x18 -+#define PCI_REG_PCI_ERR 0x1c -+#define PCI_REG_PCI_ERR_ADDR 0x20 -+#define PCI_REG_AHB_ERR 0x24 -+#define PCI_REG_AHB_ERR_ADDR 0x28 + -+#define PCI_CRP_CMD_WRITE 0x00010000 -+#define PCI_CRP_CMD_READ 0x00000000 -+#define PCI_CFG_CMD_READ 0x0000000a -+#define PCI_CFG_CMD_WRITE 0x0000000b -+ -+#define PCI_IDSEL_ADL_START 17 ++#include ++#include + -+#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000) -+#define AR724X_PCI_CFG_SIZE 0x1000 ++#include + -+#define AR724X_PCI_REG_APP 0x00 -+#define AR724X_PCI_REG_RESET 0x18 -+#define AR724X_PCI_REG_INT_STATUS 0x4c -+#define AR724X_PCI_REG_INT_MASK 0x50 ++#include "machtype.h" ++#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-pb42-pci.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0) -+#define AR724X_PCI_RESET_LINK_UP BIT(0) ++#define WP543_GPIO_SW6 2 ++#define WP543_GPIO_LED_1 3 ++#define WP543_GPIO_LED_2 4 ++#define WP543_GPIO_LED_WLAN 5 ++#define WP543_GPIO_LED_CONN 6 ++#define WP543_GPIO_LED_DIAG 7 ++#define WP543_GPIO_SW4 8 + -+#define AR724X_PCI_INT_DEV0 BIT(14) ++#define WP543_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WP543_KEYS_DEBOUNCE_INTERVAL (3 * WP543_KEYS_POLL_INTERVAL) + -+/* -+ * RESET block -+ */ -+#define AR71XX_RESET_REG_TIMER 0x00 -+#define AR71XX_RESET_REG_TIMER_RELOAD 0x04 -+#define AR71XX_RESET_REG_WDOG_CTRL 0x08 -+#define AR71XX_RESET_REG_WDOG 0x0c -+#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10 -+#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14 -+#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18 -+#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c -+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20 -+#define AR71XX_RESET_REG_RESET_MODULE 0x24 -+#define AR71XX_RESET_REG_PERFC_CTRL 0x2c -+#define AR71XX_RESET_REG_PERFC0 0x30 -+#define AR71XX_RESET_REG_PERFC1 0x34 -+#define AR71XX_RESET_REG_REV_ID 0x90 -+ -+#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18 -+#define AR91XX_RESET_REG_RESET_MODULE 0x1c -+#define AR91XX_RESET_REG_PERF_CTRL 0x20 -+#define AR91XX_RESET_REG_PERFC0 0x24 -+#define AR91XX_RESET_REG_PERFC1 0x28 -+ -+#define AR724X_RESET_REG_RESET_MODULE 0x1c -+ -+#define WDOG_CTRL_LAST_RESET BIT(31) -+#define WDOG_CTRL_ACTION_MASK 3 -+#define WDOG_CTRL_ACTION_NONE 0 /* no action */ -+#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */ -+#define WDOG_CTRL_ACTION_NMI 2 /* NMI */ -+#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */ -+ -+#define MISC_INT_DMA BIT(7) -+#define MISC_INT_OHCI BIT(6) -+#define MISC_INT_PERFC BIT(5) -+#define MISC_INT_WDOG BIT(4) -+#define MISC_INT_UART BIT(3) -+#define MISC_INT_GPIO BIT(2) -+#define MISC_INT_ERROR BIT(1) -+#define MISC_INT_TIMER BIT(0) -+ -+#define PCI_INT_CORE BIT(4) -+#define PCI_INT_DEV2 BIT(2) -+#define PCI_INT_DEV1 BIT(1) -+#define PCI_INT_DEV0 BIT(0) -+ -+#define RESET_MODULE_EXTERNAL BIT(28) -+#define RESET_MODULE_FULL_CHIP BIT(24) -+#define RESET_MODULE_AMBA2WMAC BIT(22) -+#define RESET_MODULE_CPU_NMI BIT(21) -+#define RESET_MODULE_CPU_COLD BIT(20) -+#define RESET_MODULE_DMA BIT(19) -+#define RESET_MODULE_SLIC BIT(18) -+#define RESET_MODULE_STEREO BIT(17) -+#define RESET_MODULE_DDR BIT(16) -+#define RESET_MODULE_GE1_MAC BIT(13) -+#define RESET_MODULE_GE1_PHY BIT(12) -+#define RESET_MODULE_USBSUS_OVERRIDE BIT(10) -+#define RESET_MODULE_GE0_MAC BIT(9) -+#define RESET_MODULE_GE0_PHY BIT(8) -+#define RESET_MODULE_USB_OHCI_DLL BIT(6) -+#define RESET_MODULE_USB_HOST BIT(5) -+#define RESET_MODULE_USB_PHY BIT(4) -+#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3) -+#define RESET_MODULE_PCI_BUS BIT(1) -+#define RESET_MODULE_PCI_CORE BIT(0) -+ -+#define AR724X_RESET_GE1_MDIO BIT(23) -+#define AR724X_RESET_GE0_MDIO BIT(22) -+#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10) -+#define AR724X_RESET_PCIE_PHY BIT(7) -+#define AR724X_RESET_PCIE BIT(6) -+ -+#define REV_ID_MAJOR_MASK 0xfff0 -+#define REV_ID_MAJOR_AR71XX 0x00a0 -+#define REV_ID_MAJOR_AR913X 0x00b0 -+#define REV_ID_MAJOR_AR7240 0x00c0 -+#define REV_ID_MAJOR_AR7241 0x0100 -+#define REV_ID_MAJOR_AR7242 0x1100 -+ -+#define AR71XX_REV_ID_MINOR_MASK 0x3 -+#define AR71XX_REV_ID_MINOR_AR7130 0x0 -+#define AR71XX_REV_ID_MINOR_AR7141 0x1 -+#define AR71XX_REV_ID_MINOR_AR7161 0x2 -+#define AR71XX_REV_ID_REVISION_MASK 0x3 -+#define AR71XX_REV_ID_REVISION_SHIFT 2 -+ -+#define AR91XX_REV_ID_MINOR_MASK 0x3 -+#define AR91XX_REV_ID_MINOR_AR9130 0x0 -+#define AR91XX_REV_ID_MINOR_AR9132 0x1 -+#define AR91XX_REV_ID_REVISION_MASK 0x3 -+#define AR91XX_REV_ID_REVISION_SHIFT 2 -+ -+#define AR724X_REV_ID_REVISION_MASK 0x3 -+ -+extern void __iomem *ar71xx_reset_base; ++static struct gpio_led wp543_leds_gpio[] __initdata = { ++ { ++ .name = "wp543:green:led1", ++ .gpio = WP543_GPIO_LED_1, ++ .active_low = 1, ++ }, { ++ .name = "wp543:green:led2", ++ .gpio = WP543_GPIO_LED_2, ++ .active_low = 1, ++ }, { ++ .name = "wp543:green:wlan", ++ .gpio = WP543_GPIO_LED_WLAN, ++ .active_low = 1, ++ }, { ++ .name = "wp543:green:conn", ++ .gpio = WP543_GPIO_LED_CONN, ++ .active_low = 1, ++ }, { ++ .name = "wp543:green:diag", ++ .gpio = WP543_GPIO_LED_DIAG, ++ .active_low = 1, ++ } ++}; + -+static inline void ar71xx_reset_wr(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_reset_base + reg); -+} ++static struct gpio_keys_button wp543_gpio_keys[] __initdata = { ++ { ++ .desc = "sw6", ++ .type = EV_KEY, ++ .code = BTN_0, ++ .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WP543_GPIO_SW6, ++ }, { ++ .desc = "sw4", ++ .type = EV_KEY, ++ .code = BTN_1, ++ .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WP543_GPIO_SW4, ++ } ++}; + -+static inline u32 ar71xx_reset_rr(unsigned reg) ++static void __init wp543_setup(void) +{ -+ return __raw_readl(ar71xx_reset_base + reg); -+} -+ -+void ar71xx_device_stop(u32 mask); -+void ar71xx_device_start(u32 mask); -+int ar71xx_device_stopped(u32 mask); -+ -+/* -+ * SPI block -+ */ -+#define SPI_REG_FS 0x00 /* Function Select */ -+#define SPI_REG_CTRL 0x04 /* SPI Control */ -+#define SPI_REG_IOC 0x08 /* SPI I/O Control */ -+#define SPI_REG_RDS 0x0c /* Read Data Shift */ -+ -+#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */ -+ -+#define SPI_CTRL_RD BIT(6) /* Remap Disable */ -+#define SPI_CTRL_DIV_MASK 0x3f ++ ar71xx_add_device_m25p80(NULL); + -+#define SPI_IOC_DO BIT(0) /* Data Out pin */ -+#define SPI_IOC_CLK BIT(8) /* CLK pin */ -+#define SPI_IOC_CS(n) BIT(16 + (n)) -+#define SPI_IOC_CS0 SPI_IOC_CS(0) -+#define SPI_IOC_CS1 SPI_IOC_CS(1) -+#define SPI_IOC_CS2 SPI_IOC_CS(2) -+#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2) ++ ar71xx_add_device_mdio(0xfffffff7); + -+void ar71xx_flash_acquire(void); -+void ar71xx_flash_release(void); ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = 0x08; ++ ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC | ++ RESET_MODULE_GE0_PHY; ++ ar71xx_add_device_eth(0); + -+/* -+ * MII_CTRL block -+ */ -+#define MII_REG_MII0_CTRL 0x00 -+#define MII_REG_MII1_CTRL 0x04 ++ ar71xx_add_device_usb(); + -+#define MII0_CTRL_IF_GMII 0 -+#define MII0_CTRL_IF_MII 1 -+#define MII0_CTRL_IF_RGMII 2 -+#define MII0_CTRL_IF_RMII 3 ++ pb42_pci_init(); + -+#define MII1_CTRL_IF_RGMII 0 -+#define MII1_CTRL_IF_RMII 1 ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio), ++ wp543_leds_gpio); + -+#endif /* __ASSEMBLER__ */ ++ ar71xx_register_gpio_keys_polled(-1, WP543_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wp543_gpio_keys), ++ wp543_gpio_keys); ++} + -+#endif /* __ASM_MACH_AR71XX_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,26 @@ ++MIPS_MACHINE(AR71XX_MACH_WP543, "WP543", "Compex WP543", wp543_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c 2011-08-24 02:41:55.617990333 +0200 +@@ -0,0 +1,161 @@ +/* -+ * AR91xx parallel flash driver platform data definitions ++ * Linksys WRT160NL board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#ifndef __AR91XX_FLASH_H -+#define __AR91XX_FLASH_H ++#include ++#include + -+struct mtd_partition; ++#include + -+struct ar91xx_flash_platform_data { -+ unsigned int width; -+ u8 is_shared:1; -+#ifdef CONFIG_MTD_PARTITIONS -+ unsigned int nr_parts; -+ struct mtd_partition *parts; -+#endif -+}; ++#include "machtype.h" ++#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-usb.h" ++#include "nvram.h" + -+#endif /* __AR91XX_FLASH_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,56 @@ -+/* -+ * Atheros AR71xx specific CPU feature overrides -+ * -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This file was derived from: include/asm-mips/cpu-features.h -+ * Copyright (C) 2003, 2004 Ralf Baechle -+ * Copyright (C) 2004 Maciej W. Rozycki -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+#ifndef __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H -+#define __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H ++#define WRT160NL_GPIO_LED_POWER 14 ++#define WRT160NL_GPIO_LED_WPS_AMBER 9 ++#define WRT160NL_GPIO_LED_WPS_BLUE 8 ++#define WRT160NL_GPIO_LED_WLAN 6 + -+#define cpu_has_tlb 1 -+#define cpu_has_4kex 1 -+#define cpu_has_3k_cache 0 -+#define cpu_has_4k_cache 1 -+#define cpu_has_tx39_cache 0 -+#define cpu_has_sb1_cache 0 -+#define cpu_has_fpu 0 -+#define cpu_has_32fpr 0 -+#define cpu_has_counter 1 -+#define cpu_has_watch 1 -+#define cpu_has_divec 1 ++#define WRT160NL_GPIO_BTN_WPS 7 ++#define WRT160NL_GPIO_BTN_RESET 21 + -+#define cpu_has_prefetch 1 -+#define cpu_has_ejtag 1 -+#define cpu_has_llsc 1 ++#define WRT160NL_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WRT160NL_KEYS_DEBOUNCE_INTERVAL (3 * WRT160NL_KEYS_POLL_INTERVAL) + -+#define cpu_has_mips16 1 -+#define cpu_has_mdmx 0 -+#define cpu_has_mips3d 0 -+#define cpu_has_smartmips 0 -+ -+#define cpu_has_mips32r1 1 -+#define cpu_has_mips32r2 1 -+#define cpu_has_mips64r1 0 -+#define cpu_has_mips64r2 0 ++#define WRT160NL_NVRAM_ADDR 0x1f7e0000 ++#define WRT160NL_NVRAM_SIZE 0x10000 + -+#define cpu_has_dsp 0 -+#define cpu_has_mipsmt 0 ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition wrt160nl_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "kernel", ++ .offset = 0x040000, ++ .size = 0x0e0000, ++ }, { ++ .name = "filesytem", ++ .offset = 0x120000, ++ .size = 0x6c0000, ++ }, { ++ .name = "nvram", ++ .offset = 0x7e0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "ART", ++ .offset = 0x7f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x040000, ++ .size = 0x7a0000, ++ } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+#define cpu_has_64bits 0 -+#define cpu_has_64bit_zero_reg 0 -+#define cpu_has_64bit_gp_regs 0 -+#define cpu_has_64bit_addresses 0 ++static struct flash_platform_data wrt160nl_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = wrt160nl_partitions, ++ .nr_parts = ARRAY_SIZE(wrt160nl_partitions), ++#endif ++}; + -+#define cpu_dcache_line_size() 32 -+#define cpu_icache_line_size() 32 ++static struct gpio_led wrt160nl_leds_gpio[] __initdata = { ++ { ++ .name = "wrt160nl:blue:power", ++ .gpio = WRT160NL_GPIO_LED_POWER, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, { ++ .name = "wrt160nl:amber:wps", ++ .gpio = WRT160NL_GPIO_LED_WPS_AMBER, ++ .active_low = 1, ++ }, { ++ .name = "wrt160nl:blue:wps", ++ .gpio = WRT160NL_GPIO_LED_WPS_BLUE, ++ .active_low = 1, ++ }, { ++ .name = "wrt160nl:blue:wlan", ++ .gpio = WRT160NL_GPIO_LED_WLAN, ++ .active_low = 1, ++ } ++}; + -+#endif /* __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,53 @@ -+/* -+ * Atheros AR71xx GPIO API definitions -+ * -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ ++static struct gpio_keys_button wrt160nl_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WRT160NL_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "wps", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WRT160NL_GPIO_BTN_WPS, ++ .active_low = 1, ++ } ++}; + -+#ifndef __ASM_MACH_AR71XX_GPIO_H -+#define __ASM_MACH_AR71XX_GPIO_H ++static void __init wrt160nl_setup(void) ++{ ++ const char *nvram = (char *) KSEG1ADDR(WRT160NL_NVRAM_ADDR); ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 mac[6]; + -+#define ARCH_NR_GPIOS 64 -+#include ++ if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, ++ "lan_hwaddr=", mac) == 0) { ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ } + -+#include ++ ar71xx_add_device_mdio(0x0); + -+extern unsigned long ar71xx_gpio_count; -+extern void __ar71xx_gpio_set_value(unsigned gpio, int value); -+extern int __ar71xx_gpio_get_value(unsigned gpio); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.phy_mask = 0x01; + -+static inline int gpio_to_irq(unsigned gpio) -+{ -+ return AR71XX_GPIO_IRQ(gpio); -+} ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = 0x10; + -+static inline int irq_to_gpio(unsigned irq) -+{ -+ return irq - AR71XX_GPIO_IRQ_BASE; -+} ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+static inline int gpio_get_value(unsigned gpio) -+{ -+ if (gpio < ar71xx_gpio_count) -+ return __ar71xx_gpio_get_value(gpio); ++ ar71xx_add_device_m25p80(&wrt160nl_flash_data); + -+ return __gpio_get_value(gpio); -+} ++ ar71xx_add_device_usb(); + -+static inline void gpio_set_value(unsigned gpio, int value) -+{ -+ if (gpio < ar71xx_gpio_count) -+ __ar71xx_gpio_set_value(gpio, value); ++ if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, ++ "wl0_hwaddr=", mac) == 0) ++ ar9xxx_add_device_wmac(eeprom, mac); + else -+ __gpio_set_value(gpio, value); -+} -+ -+#define gpio_cansleep __gpio_cansleep ++ ar9xxx_add_device_wmac(eeprom, NULL); + -+#endif /* __ASM_MACH_AR71XX_GPIO_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,17 @@ -+/* -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#ifndef __ASM_MACH_AR71XX_IRQ_H -+#define __ASM_MACH_AR71XX_IRQ_H ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt160nl_leds_gpio), ++ wrt160nl_leds_gpio); + -+#define MIPS_CPU_IRQ_BASE 0 -+#define NR_IRQS 56 ++ ar71xx_register_gpio_keys_polled(-1, WRT160NL_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wrt160nl_gpio_keys), ++ wrt160nl_gpio_keys); + -+#include_next ++} + -+#endif /* __ASM_MACH_AR71XX_IRQ_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,32 @@ ++MIPS_MACHINE(AR71XX_MACH_WRT160NL, "WRT160NL", "Linksys WRT160NL", ++ wrt160nl_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c 2011-08-24 02:41:55.617990333 +0200 +@@ -0,0 +1,164 @@ +/* -+ * Atheros AR71xx specific kernel entry setup ++ * Linksys WRT400N board support + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2009 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. -+ * + */ -+#ifndef __ASM_MACH_AR71XX_KERNEL_ENTRY_H -+#define __ASM_MACH_AR71XX_KERNEL_ENTRY_H + -+ /* -+ * Some bootloaders set the 'Kseg0 coherency algorithm' to -+ * 'Cacheable, noncoherent, write-through, no write allocate' -+ * and this cause performance issues. Let's go and change it to -+ * 'Cacheable, noncoherent, write-back, write allocate' -+ */ -+ .macro kernel_entry_setup -+ mfc0 t0, CP0_CONFIG -+ li t1, ~CONF_CM_CMASK -+ and t0, t1 -+ ori t0, CONF_CM_CACHABLE_NONCOHERENT -+ mtc0 t0, CP0_CONFIG -+ nop -+ .endm ++#include ++#include + -+ .macro smp_slave_setup -+ .endm ++#include + -+#endif /* __ASM_MACH_AR71XX_KERNEL_ENTRY_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,66 @@ -+/* -+ * MikroTik RouterBOARD 750 definitions -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#ifndef _MACH_RB750_H -+#define _MACH_RB750_H ++#include "machtype.h" ++#include "devices.h" ++#include "dev-ap94-pci.h" ++#include "dev-m25p80.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" + -+#include ++#define WRT400N_GPIO_LED_ORANGE 5 ++#define WRT400N_GPIO_LED_GREEN 4 ++#define WRT400N_GPIO_LED_POWER 1 ++#define WRT400N_GPIO_LED_WLAN 0 + -+#define RB750_GPIO_LVC573_LE 0 /* Latch enable on LVC573 */ -+#define RB750_GPIO_NAND_IO0 1 /* NAND I/O 0 */ -+#define RB750_GPIO_NAND_IO1 2 /* NAND I/O 1 */ -+#define RB750_GPIO_NAND_IO2 3 /* NAND I/O 2 */ -+#define RB750_GPIO_NAND_IO3 4 /* NAND I/O 3 */ -+#define RB750_GPIO_NAND_IO4 5 /* NAND I/O 4 */ -+#define RB750_GPIO_NAND_IO5 6 /* NAND I/O 5 */ -+#define RB750_GPIO_NAND_IO6 7 /* NAND I/O 6 */ -+#define RB750_GPIO_NAND_IO7 8 /* NAND I/O 7 */ -+#define RB750_GPIO_NAND_NCE 11 /* NAND Chip Enable (active low) */ -+#define RB750_GPIO_NAND_RDY 12 /* NAND Ready */ -+#define RB750_GPIO_NAND_CLE 14 /* NAND Command Latch Enable */ -+#define RB750_GPIO_NAND_ALE 15 /* NAND Address Latch Enable */ -+#define RB750_GPIO_NAND_NRE 16 /* NAND Read Enable (active low) */ -+#define RB750_GPIO_NAND_NWE 17 /* NAND Write Enable (active low) */ ++#define WRT400N_GPIO_BTN_RESET 8 ++#define WRT400N_GPIO_BTN_WLSEC 3 + -+#define RB750_GPIO_BTN_RESET 1 -+#define RB750_GPIO_SPI_CS0 2 -+#define RB750_GPIO_LED_ACT 12 -+#define RB750_GPIO_LED_PORT1 13 -+#define RB750_GPIO_LED_PORT2 14 -+#define RB750_GPIO_LED_PORT3 15 -+#define RB750_GPIO_LED_PORT4 16 -+#define RB750_GPIO_LED_PORT5 17 ++#define WRT400N_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WRT400N_KEYS_DEBOUNE_INTERVAL (3 * WRT400N_KEYS_POLL_INTERVAL) + -+#define RB750_LED_ACT BIT(RB750_GPIO_LED_ACT) -+#define RB750_LED_PORT1 BIT(RB750_GPIO_LED_PORT1) -+#define RB750_LED_PORT2 BIT(RB750_GPIO_LED_PORT2) -+#define RB750_LED_PORT3 BIT(RB750_GPIO_LED_PORT3) -+#define RB750_LED_PORT4 BIT(RB750_GPIO_LED_PORT4) -+#define RB750_LED_PORT5 BIT(RB750_GPIO_LED_PORT5) ++#define WRT400N_MAC_ADDR_OFFSET 0x120c ++#define WRT400N_CALDATA0_OFFSET 0x1000 ++#define WRT400N_CALDATA1_OFFSET 0x5000 + -+#define RB750_LVC573_LE BIT(RB750_GPIO_LVC573_LE) ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition wrt400n_partitions[] = { ++ { ++ .name = "uboot", ++ .offset = 0, ++ .size = 0x030000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "env", ++ .offset = 0x030000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "linux", ++ .offset = 0x040000, ++ .size = 0x140000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x180000, ++ .size = 0x630000, ++ }, { ++ .name = "nvram", ++ .offset = 0x7b0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "factory", ++ .offset = 0x7c0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "language", ++ .offset = 0x7d0000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "caldata", ++ .offset = 0x7f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x040000, ++ .size = 0x770000, ++ } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+#define RB750_LED_BITS (RB750_LED_PORT1 | RB750_LED_PORT2 | RB750_LED_PORT3 | \ -+ RB750_LED_PORT4 | RB750_LED_PORT5 | RB750_LED_ACT) ++static struct flash_platform_data wrt400n_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = wrt400n_partitions, ++ .nr_parts = ARRAY_SIZE(wrt400n_partitions), ++#endif ++}; + -+struct rb750_led_data { -+ char *name; -+ char *default_trigger; -+ u32 mask; -+ int active_low; ++static struct gpio_led wrt400n_leds_gpio[] __initdata = { ++ { ++ .name = "wrt400n:green:status", ++ .gpio = WRT400N_GPIO_LED_GREEN, ++ .active_low = 1, ++ }, { ++ .name = "wrt400n:amber:aoss", ++ .gpio = WRT400N_GPIO_LED_ORANGE, ++ .active_low = 1, ++ }, { ++ .name = "wrt400n:green:wlan", ++ .gpio = WRT400N_GPIO_LED_WLAN, ++ .active_low = 1, ++ }, { ++ .name = "wrt400n:green:power", ++ .gpio = WRT400N_GPIO_LED_POWER, ++ .active_low = 1, ++ } +}; + -+struct rb750_led_platform_data { -+ int num_leds; -+ struct rb750_led_data *leds; ++static struct gpio_keys_button wrt400n_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL, ++ .gpio = WRT400N_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "wlsec", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL, ++ .gpio = WRT400N_GPIO_BTN_WLSEC, ++ .active_low = 1, ++ } +}; + -+int rb750_latch_change(u32 mask_clr, u32 mask_set); ++static void __init wrt400n_setup(void) ++{ ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *mac = art + WRT400N_MAC_ADDR_OFFSET; + -+#endif /* _MACH_RB750_H */ -\ No newline at end of file -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h -+ * Copyright (C) 2003, 2004 Ralf Baechle -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ ar71xx_add_device_mdio(0x0); + -+#ifndef __ASM_MACH_AR71XX_MANGLE_PORT_H -+#define __ASM_MACH_AR71XX_MANGLE_PORT_H ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 1); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+#define __swizzle_addr_b(port) ((port) ^ 3) -+#define __swizzle_addr_w(port) ((port) ^ 2) -+#define __swizzle_addr_l(port) (port) -+#define __swizzle_addr_q(port) (port) ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 2); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = 0x10; + -+#if defined(CONFIG_SWAP_IO_SPACE) ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+# define ioswabb(a, x) (x) -+# define __mem_ioswabb(a, x) (x) -+# define ioswabw(a, x) le16_to_cpu(x) -+# define __mem_ioswabw(a, x) (x) -+# define ioswabl(a, x) le32_to_cpu(x) -+# define __mem_ioswabl(a, x) (x) -+# define ioswabq(a, x) le64_to_cpu(x) -+# define __mem_ioswabq(a, x) (x) ++ ar71xx_add_device_m25p80(&wrt400n_flash_data); + -+#else ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt400n_leds_gpio), ++ wrt400n_leds_gpio); + -+# define ioswabb(a, x) (x) -+# define __mem_ioswabb(a, x) (x) -+# define ioswabw(a, x) (x) -+# define __mem_ioswabw(a, x) cpu_to_le16(x) -+# define ioswabl(a, x) (x) -+# define __mem_ioswabl(a, x) cpu_to_le32(x) -+# define ioswabq(a, x) (x) -+# define __mem_ioswabq(a, x) cpu_to_le64(x) ++ ar71xx_register_gpio_keys_polled(-1, WRT400N_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wrt400n_gpio_keys), ++ wrt400n_gpio_keys); + -+#endif ++ ap94_pci_init(art + WRT400N_CALDATA0_OFFSET, NULL, ++ art + WRT400N_CALDATA1_OFFSET, NULL); ++} + -+#endif /* __ASM_MACH_AR71XX_MANGLE_PORT_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,39 @@ ++MIPS_MACHINE(AR71XX_MACH_WRT400N, "WRT400N", "Linksys WRT400N", wrt400n_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-ag300h.c linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-ag300h.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-ag300h.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-ag300h.c 2011-08-24 02:41:55.628193451 +0200 +@@ -0,0 +1,231 @@ +/* -+ * Atheros AR71xx SoC specific PCI definitions ++ * Buffalo WZR-HP-AG300H board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2011 Felix Fietkau + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#ifndef __ASM_MACH_AR71XX_PCI_H -+#define __ASM_MACH_AR71XX_PCI_H ++#include ++#include ++#include ++#include + -+struct pci_dev; ++#include ++#include ++#include + -+struct ar71xx_pci_irq { -+ int irq; -+ u8 slot; -+ u8 pin; ++#include "machtype.h" ++#include "devices.h" ++#include "dev-ap94-pci.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-m25p80.h" ++#include "dev-usb.h" ++ ++#define WZRHPAG300H_MAC_OFFSET 0x20c ++#define WZRHPAG300H_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPAG300H_KEYS_POLL_INTERVAL) ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition wzrhpag300h_flash_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x0040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "u-boot-env", ++ .offset = 0x0040000, ++ .size = 0x0010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "art", ++ .offset = 0x0050000, ++ .size = 0x0010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "kernel", ++ .offset = 0x0060000, ++ .size = 0x0100000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x0160000, ++ .size = 0x1e90000, ++ }, { ++ .name = "user_property", ++ .offset = 0x1ff0000, ++ .size = 0x0010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x0060000, ++ .size = 0x1f90000, ++ } +}; + -+extern int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev); -+extern unsigned ar71xx_pci_nr_irqs __initdata; -+extern struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+int ar71xx_pcibios_map_irq(const struct pci_dev *dev, -+ uint8_t slot, uint8_t pin) __init; -+int ar71xx_pcibios_init(void) __init; ++static struct mtd_info *concat_devs[2] = { NULL, NULL }; ++static struct work_struct mtd_concat_work; + -+int ar71xx_pci_be_handler(int is_fixup); ++static void mtd_concat_add_work(struct work_struct *work) ++{ ++ struct mtd_info *mtd; + -+int ar724x_pcibios_map_irq(const struct pci_dev *dev, -+ uint8_t slot, uint8_t pin) __init; -+int ar724x_pcibios_init(void) __init; ++ mtd = mtd_concat_create(concat_devs, ARRAY_SIZE(concat_devs), "flash"); + -+int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) __init; ++#ifdef CONFIG_MTD_PARTITIONS ++ add_mtd_partitions(mtd, wzrhpag300h_flash_partitions, ++ ARRAY_SIZE(wzrhpag300h_flash_partitions)); ++#else ++ add_mtd_device(mtd); ++#endif ++} + -+#endif /* __ASM_MACH_AR71XX_PCI_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,61 @@ -+/* -+ * Atheros AR71xx SoC specific platform data definitions -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++static void mtd_concat_add(struct mtd_info *mtd) ++{ ++ static bool registered = false; + -+#ifndef __ASM_MACH_AR71XX_PLATFORM_H -+#define __ASM_MACH_AR71XX_PLATFORM_H ++ if (registered) ++ return; + -+#include -+#include -+#include -+#include ++ if (!strcmp(mtd->name, "spi0.0")) ++ concat_devs[0] = mtd; ++ else if (!strcmp(mtd->name, "spi0.1")) ++ concat_devs[1] = mtd; ++ else ++ return; + -+struct ag71xx_platform_data { -+ phy_interface_t phy_if_mode; -+ u32 phy_mask; -+ int speed; -+ int duplex; -+ u32 reset_bit; -+ u32 mii_if; -+ u8 mac_addr[ETH_ALEN]; -+ struct device *mii_bus_dev; ++ if (!concat_devs[0] || !concat_devs[1]) ++ return; + -+ u8 has_gbit:1; -+ u8 is_ar91xx:1; -+ u8 is_ar724x:1; -+ u8 has_ar8216:1; ++ registered = true; ++ INIT_WORK(&mtd_concat_work, mtd_concat_add_work); ++ schedule_work(&mtd_concat_work); ++} ++ ++static void mtd_concat_remove(struct mtd_info *mtd) ++{ ++} + -+ void (* ddr_flush)(void); -+ void (* set_pll)(int speed); ++static void add_mtd_concat_notifier(void) ++{ ++ static struct mtd_notifier not = { ++ .add = mtd_concat_add, ++ .remove = mtd_concat_remove, ++ }; + -+ u32 fifo_cfg1; -+ u32 fifo_cfg2; -+ u32 fifo_cfg3; -+}; ++ register_mtd_user(¬); ++} + -+struct ag71xx_mdio_platform_data { -+ u32 phy_mask; -+ int is_ar7240; ++static struct gpio_led wzrhpag300h_leds_gpio[] __initdata = { ++ { ++ .name = "wzr-hp-ag300h:red:diag", ++ .gpio = 1, ++ .active_low = 1, ++ }, +}; + -+struct ar71xx_ehci_platform_data { -+ u8 is_ar91xx; ++ ++static struct gpio_keys_button wzrhpag300h_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = 11, ++ .active_low = 1, ++ }, { ++ .desc = "usb", ++ .type = EV_KEY, ++ .code = BTN_2, ++ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = 3, ++ .active_low = 1, ++ }, { ++ .desc = "aoss", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = 5, ++ .active_low = 1, ++ }, { ++ .desc = "router_auto", ++ .type = EV_KEY, ++ .code = BTN_6, ++ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = 6, ++ .active_low = 1, ++ }, { ++ .desc = "router_off", ++ .type = EV_KEY, ++ .code = BTN_5, ++ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = 7, ++ .active_low = 1, ++ } +}; + -+struct ar71xx_spi_platform_data { -+ unsigned bus_num; -+ unsigned num_chipselect; -+ u32 (*get_ioc_base)(u8 chip_select, int cs_high, int is_on); ++static struct spi_board_info ar71xx_spi_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "m25p80", ++ }, ++ { ++ .bus_num = 0, ++ .chip_select = 1, ++ .max_speed_hz = 25000000, ++ .modalias = "m25p80", ++ } +}; + -+#define AR71XX_SPI_CS_INACTIVE 0 -+#define AR71XX_SPI_CS_ACTIVE 1 ++static void __init wzrhpag300h_setup(void) ++{ ++ u8 *eeprom1 = (u8 *) KSEG1ADDR(0x1f051000); ++ u8 *eeprom2 = (u8 *) KSEG1ADDR(0x1f055000); ++ u8 *mac1 = eeprom1 + WZRHPAG300H_MAC_OFFSET; ++ u8 *mac2 = eeprom2 + WZRHPAG300H_MAC_OFFSET; + -+#endif /* __ASM_MACH_AR71XX_PLATFORM_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,25 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle -+ */ -+#ifndef __ASM_MACH_AR71XX_WAR_H -+#define __ASM_MACH_AR71XX_WAR_H ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac1, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac2, 1); + -+#define R4600_V1_INDEX_ICACHEOP_WAR 0 -+#define R4600_V1_HIT_CACHEOP_WAR 0 -+#define R4600_V2_HIT_CACHEOP_WAR 0 -+#define R5432_CP0_INTERRUPT_WAR 0 -+#define BCM1250_M3_WAR 0 -+#define SIBYTE_1956_WAR 0 -+#define MIPS4K_ICACHE_REFILL_WAR 0 -+#define MIPS_CACHE_SYNC_WAR 0 -+#define TX49XX_ICACHE_INDEX_INV_WAR 0 -+#define RM9000_CDEX_SMP_WAR 0 -+#define ICACHE_REFILLS_WORKAROUND_WAR 0 -+#define R10000_LLSC_WAR 0 -+#define MIPS34K_MISSED_ITLB_WAR 0 ++ ar71xx_add_device_mdio(~(BIT(0) | BIT(4))); + -+#endif /* __ASM_MACH_AR71XX_WAR_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/time.h linux-2.6.39/arch/mips/include/asm/time.h ---- linux-2.6.39.orig/arch/mips/include/asm/time.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/include/asm/time.h 2011-05-27 14:36:51.000000000 +0200 -@@ -52,6 +52,7 @@ - */ - #ifdef CONFIG_CEVT_R4K_LIB - extern unsigned int __weak get_c0_compare_int(void); -+extern unsigned int __weak get_c0_compare_irq(void); - extern int r4k_clockevent_init(void); - #endif - -diff -Nur linux-2.6.39.orig/arch/mips/kernel/Makefile linux-2.6.39/arch/mips/kernel/Makefile ---- linux-2.6.39.orig/arch/mips/kernel/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/kernel/Makefile 2011-05-27 14:36:51.000000000 +0200 -@@ -94,6 +94,7 @@ - - obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -+obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o - obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o - obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o - -diff -Nur linux-2.6.39.orig/arch/mips/kernel/traps.c linux-2.6.39/arch/mips/kernel/traps.c ---- linux-2.6.39.orig/arch/mips/kernel/traps.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/kernel/traps.c 2011-05-27 14:36:51.000000000 +0200 -@@ -46,6 +46,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1576,6 +1577,8 @@ - if (cpu_has_mips_r2) { - cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; - cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; -+ if (get_c0_compare_irq) -+ cp0_compare_irq = get_c0_compare_irq(); - cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7; - if (cp0_perfcount_irq == cp0_compare_irq) - cp0_perfcount_irq = -1; -diff -Nur linux-2.6.39.orig/arch/mips/pci/Makefile linux-2.6.39/arch/mips/pci/Makefile ---- linux-2.6.39.orig/arch/mips/pci/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/pci/Makefile 2011-05-27 14:36:51.000000000 +0200 -@@ -18,6 +18,7 @@ - obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o - obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ - ops-bcm63xx.o -+obj-$(CONFIG_ATHEROS_AR71XX) += pci-ar71xx.o pci-ar724x.o - - # - # These are still pretty much in the old state, watch, go blind. -diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c linux-2.6.39/arch/mips/pci/pci-ar71xx.c ---- linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/pci/pci-ar71xx.c 2011-06-01 14:02:22.000000000 +0200 -@@ -0,0 +1,408 @@ ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = BIT(0); ++ ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = BIT(4); ++ ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); ++ ++ ar71xx_add_device_usb(); ++ gpio_request(2, "usb"); ++ gpio_direction_output(2, 1); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpag300h_leds_gpio), ++ wzrhpag300h_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, WZRHPAG300H_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wzrhpag300h_gpio_keys), ++ wzrhpag300h_gpio_keys); ++ ++ ar71xx_add_device_spi(NULL, ar71xx_spi_info, ++ ARRAY_SIZE(ar71xx_spi_info)); ++ ++ add_mtd_concat_notifier(); ++ ++ ap94_pci_init(eeprom1, mac1, eeprom2, mac2); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_WZR_HP_AG300H, "WZR-HP-AG300H", ++ "Buffalo WZR-HP-AG300H", wzrhpag300h_setup); ++ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 2011-08-24 02:41:55.649418561 +0200 +@@ -0,0 +1,292 @@ +/* -+ * Atheros AR71xx PCI host controller driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Buffalo WZR-HP-G300NH board support + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Copyright (C) 2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#include ++#include ++#include ++#include ++#include + ++#include +#include -+#include -+ -+#undef DEBUG -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+#define AR71XX_PCI_DELAY 100 /* msecs */ -+ -+#if 0 -+#define PCI_IDSEL_BASE PCI_IDSEL_ADL_START -+#else -+#define PCI_IDSEL_BASE 0 -+#endif ++#include + -+static void __iomem *ar71xx_pcicfg_base; -+static DEFINE_SPINLOCK(ar71xx_pci_lock); -+static int ar71xx_pci_fixup_enable; ++#include "machtype.h" ++#include "devices.h" ++#include "dev-ar9xxx-wmac.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+static inline void ar71xx_pci_delay(void) -+{ -+ mdelay(AR71XX_PCI_DELAY); -+} ++#define WZRHPG300NH_GPIO_LED_USB 0 ++#define WZRHPG300NH_GPIO_LED_DIAG 1 ++#define WZRHPG300NH_GPIO_LED_WIRELESS 6 ++#define WZRHPG300NH_GPIO_LED_SECURITY 17 ++#define WZRHPG300NH_GPIO_LED_ROUTER 18 + -+/* Byte lane enable bits */ -+static u8 ble_table[4][4] = { -+ {0x0, 0xf, 0xf, 0xf}, -+ {0xe, 0xd, 0xb, 0x7}, -+ {0xc, 0xf, 0x3, 0xf}, -+ {0xf, 0xf, 0xf, 0xf}, -+}; ++#define WZRHPG300NH_GPIO_RTL8366_SDA 19 ++#define WZRHPG300NH_GPIO_RTL8366_SCK 20 + -+static inline u32 ar71xx_pci_get_ble(int where, int size, int local) -+{ -+ u32 t; ++#define WZRHPG300NH_GPIO_74HC153_S0 9 ++#define WZRHPG300NH_GPIO_74HC153_S1 11 ++#define WZRHPG300NH_GPIO_74HC153_1Y 12 ++#define WZRHPG300NH_GPIO_74HC153_2Y 14 + -+ t = ble_table[size & 3][where & 3]; -+ BUG_ON(t == 0xf); -+ t <<= (local) ? 20 : 4; -+ return t; -+} ++#define WZRHPG300NH_GPIO_EXP_BASE 32 ++#define WZRHPG300NH_GPIO_BTN_AOSS (WZRHPG300NH_GPIO_EXP_BASE + 0) ++#define WZRHPG300NH_GPIO_BTN_RESET (WZRHPG300NH_GPIO_EXP_BASE + 1) ++#define WZRHPG300NH_GPIO_BTN_ROUTER_ON (WZRHPG300NH_GPIO_EXP_BASE + 2) ++#define WZRHPG300NH_GPIO_BTN_QOS_ON (WZRHPG300NH_GPIO_EXP_BASE + 3) ++#define WZRHPG300NH_GPIO_BTN_USB (WZRHPG300NH_GPIO_EXP_BASE + 5) ++#define WZRHPG300NH_GPIO_BTN_ROUTER_AUTO (WZRHPG300NH_GPIO_EXP_BASE + 6) ++#define WZRHPG300NH_GPIO_BTN_QOS_OFF (WZRHPG300NH_GPIO_EXP_BASE + 7) + -+static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn, -+ int where) -+{ -+ u32 ret; ++#define WZRHPG300NH_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPG300NH_KEYS_POLL_INTERVAL) + -+ if (!bus->number) { -+ /* type 0 */ -+ ret = (1 << (PCI_IDSEL_BASE + PCI_SLOT(devfn))) -+ | (PCI_FUNC(devfn) << 8) | (where & ~3); -+ } else { -+ /* type 1 */ -+ ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11) -+ | (PCI_FUNC(devfn) << 8) | (where & ~3) | 1; -+ } ++#define WZRHPG300NH_MAC_OFFSET 0x20c + -+ return ret; -+} ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition wzrhpg300nh_flash_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x0040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "u-boot-env", ++ .offset = 0x0040000, ++ .size = 0x0020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "kernel", ++ .offset = 0x0060000, ++ .size = 0x0100000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x0160000, ++ .size = 0x1e60000, ++ }, { ++ .name = "user_property", ++ .offset = 0x1fc0000, ++ .size = 0x0020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "art", ++ .offset = 0x1fe0000, ++ .size = 0x0020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x0060000, ++ .size = 0x1f60000, ++ } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+int ar71xx_pci_be_handler(int is_fixup) -+{ -+ void __iomem *base = ar71xx_pcicfg_base; -+ u32 pci_err; -+ u32 ahb_err; ++static struct ar91xx_flash_platform_data wzrhpg300nh_flash_data = { ++ .width = 2, ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = wzrhpg300nh_flash_partitions, ++ .nr_parts = ARRAY_SIZE(wzrhpg300nh_flash_partitions), ++#endif ++}; + -+ pci_err = __raw_readl(base + PCI_REG_PCI_ERR) & 3; -+ if (pci_err) { -+ if (!is_fixup) -+ printk(KERN_ALERT "PCI error %d at PCI addr 0x%x\n", -+ pci_err, -+ __raw_readl(base + PCI_REG_PCI_ERR_ADDR)); ++#define WZRHPG300NH_FLASH_BASE 0x1e000000 ++#define WZRHPG300NH_FLASH_SIZE (32 * 1024 * 1024) + -+ __raw_writel(pci_err, base + PCI_REG_PCI_ERR); -+ } ++static struct resource wzrhpg300nh_flash_resources[] = { ++ [0] = { ++ .start = WZRHPG300NH_FLASH_BASE, ++ .end = WZRHPG300NH_FLASH_BASE + WZRHPG300NH_FLASH_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; + -+ ahb_err = __raw_readl(base + PCI_REG_AHB_ERR) & 1; -+ if (ahb_err) { -+ if (!is_fixup) -+ printk(KERN_ALERT "AHB error at AHB address 0x%x\n", -+ __raw_readl(base + PCI_REG_AHB_ERR_ADDR)); ++static struct platform_device wzrhpg300nh_flash_device = { ++ .name = "ar91xx-flash", ++ .id = -1, ++ .resource = wzrhpg300nh_flash_resources, ++ .num_resources = ARRAY_SIZE(wzrhpg300nh_flash_resources), ++ .dev = { ++ .platform_data = &wzrhpg300nh_flash_data, ++ } ++}; + -+ __raw_writel(ahb_err, base + PCI_REG_AHB_ERR); ++static struct gpio_led wzrhpg300nh_leds_gpio[] __initdata = { ++ { ++ .name = "wzr-hp-g300nh:orange:security", ++ .gpio = WZRHPG300NH_GPIO_LED_SECURITY, ++ .active_low = 1, ++ }, { ++ .name = "wzr-hp-g300nh:green:wireless", ++ .gpio = WZRHPG300NH_GPIO_LED_WIRELESS, ++ .active_low = 1, ++ }, { ++ .name = "wzr-hp-g300nh:green:router", ++ .gpio = WZRHPG300NH_GPIO_LED_ROUTER, ++ .active_low = 1, ++ }, { ++ .name = "wzr-hp-g300nh:red:diag", ++ .gpio = WZRHPG300NH_GPIO_LED_DIAG, ++ .active_low = 1, ++ }, { ++ .name = "wzr-hp-g300nh:blue:usb", ++ .gpio = WZRHPG300NH_GPIO_LED_USB, ++ .active_low = 1, + } ++}; + -+ return ((ahb_err | pci_err) ? 1 : 0); -+} ++static struct gpio_keys_button wzrhpg300nh_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "aoss", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_AOSS, ++ .active_low = 1, ++ }, { ++ .desc = "usb", ++ .type = EV_KEY, ++ .code = BTN_2, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_USB, ++ .active_low = 1, ++ }, { ++ .desc = "qos_on", ++ .type = EV_KEY, ++ .code = BTN_3, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_QOS_ON, ++ .active_low = 0, ++ }, { ++ .desc = "qos_off", ++ .type = EV_KEY, ++ .code = BTN_4, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_QOS_OFF, ++ .active_low = 0, ++ }, { ++ .desc = "router_on", ++ .type = EV_KEY, ++ .code = BTN_5, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_ON, ++ .active_low = 0, ++ }, { ++ .desc = "router_auto", ++ .type = EV_KEY, ++ .code = BTN_6, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_AUTO, ++ .active_low = 0, ++ } ++}; + -+static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus, -+ unsigned int devfn, int where, int size, u32 cmd) -+{ -+ void __iomem *base = ar71xx_pcicfg_base; -+ u32 addr; ++static struct nxp_74hc153_platform_data wzrhpg300nh_74hc153_data = { ++ .gpio_base = WZRHPG300NH_GPIO_EXP_BASE, ++ .gpio_pin_s0 = WZRHPG300NH_GPIO_74HC153_S0, ++ .gpio_pin_s1 = WZRHPG300NH_GPIO_74HC153_S1, ++ .gpio_pin_1y = WZRHPG300NH_GPIO_74HC153_1Y, ++ .gpio_pin_2y = WZRHPG300NH_GPIO_74HC153_2Y, ++}; + -+ addr = ar71xx_pci_bus_addr(bus, devfn, where); ++static struct platform_device wzrhpg300nh_74hc153_device = { ++ .name = NXP_74HC153_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &wzrhpg300nh_74hc153_data, ++ } ++}; + -+ DBG("PCI: set cfgaddr: %02x:%02x.%01x/%02x:%01d, addr=%08x\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), -+ where, size, addr); ++static struct rtl8366_platform_data wzrhpg300nh_rtl8366_data = { ++ .gpio_sda = WZRHPG300NH_GPIO_RTL8366_SDA, ++ .gpio_sck = WZRHPG300NH_GPIO_RTL8366_SCK, ++}; + -+ __raw_writel(addr, base + PCI_REG_CFG_AD); -+ __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0), -+ base + PCI_REG_CFG_CBE); ++static struct platform_device wzrhpg300nh_rtl8366s_device = { ++ .name = RTL8366S_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &wzrhpg300nh_rtl8366_data, ++ } ++}; + -+ return ar71xx_pci_be_handler(1); -+} ++static struct platform_device wzrhpg300nh_rtl8366rb_device = { ++ .name = RTL8366RB_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &wzrhpg300nh_rtl8366_data, ++ } ++}; + -+static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 *value) ++static void __init wzrhpg300nh_setup(void) +{ -+ void __iomem *base = ar71xx_pcicfg_base; -+ static u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0}; -+ unsigned long flags; -+ u32 data; -+ int ret; ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 *mac = eeprom + WZRHPG300NH_MAC_OFFSET; ++ bool hasrtl8366rb = false; + -+ ret = PCIBIOS_SUCCESSFUL; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); + -+ DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d\n", bus->number, -+ PCI_SLOT(devfn), PCI_FUNC(devfn), where, size); ++ if (rtl8366_smi_detect(&wzrhpg300nh_rtl8366_data) == RTL8366_TYPE_RB) ++ hasrtl8366rb = true; + -+ spin_lock_irqsave(&ar71xx_pci_lock, flags); ++ if (hasrtl8366rb) { ++ ar71xx_eth0_pll_data.pll_1000 = 0x1f000000; ++ ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev; ++ ar71xx_eth1_pll_data.pll_1000 = 0x100; ++ ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev; ++ } else { ++ ar71xx_eth0_pll_data.pll_1000 = 0x1e000100; ++ ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; ++ ar71xx_eth1_pll_data.pll_1000 = 0x1e000100; ++ ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; ++ } + -+ if (bus->number == 0 && devfn == 0) { -+ u32 t; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+ t = PCI_CRP_CMD_READ | (where & ~3); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = 0x10; + -+ __raw_writel(t, base + PCI_REG_CRP_AD_CBE); -+ data = __raw_readl(base + PCI_REG_CRP_RDDATA); ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ DBG("PCI: rd local cfg, ad_cbe:%08x, data:%08x\n", t, data); ++ ar71xx_add_device_usb(); ++ ar9xxx_add_device_wmac(eeprom, NULL); + -+ } else { -+ int err; ++ platform_device_register(&wzrhpg300nh_74hc153_device); ++ platform_device_register(&wzrhpg300nh_flash_device); + -+ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, -+ PCI_CFG_CMD_READ); ++ if (hasrtl8366rb) ++ platform_device_register(&wzrhpg300nh_rtl8366rb_device); ++ else ++ platform_device_register(&wzrhpg300nh_rtl8366s_device); + -+ if (err == 0) { -+ data = __raw_readl(base + PCI_REG_CFG_RDDATA); -+ } else { -+ ret = PCIBIOS_DEVICE_NOT_FOUND; -+ data = ~0; -+ } -+ } ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh_leds_gpio), ++ wzrhpg300nh_leds_gpio); + -+ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); ++ ar71xx_register_gpio_keys_polled(-1, WZRHPG300NH_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wzrhpg300nh_gpio_keys), ++ wzrhpg300nh_gpio_keys); + -+ DBG("PCI: read config: data=%08x raw=%08x\n", -+ (data >> (8 * (where & 3))) & mask[size & 7], data); ++} + -+ *value = (data >> (8 * (where & 3))) & mask[size & 7]; ++MIPS_MACHINE(AR71XX_MACH_WZR_HP_G300NH, "WZR-HP-G300NH", ++ "Buffalo WZR-HP-G300NH", wzrhpg300nh_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-zcn-1523h.c linux-2.6.39/arch/mips/ar71xx/mach-zcn-1523h.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-zcn-1523h.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-zcn-1523h.c 2011-08-24 02:41:55.649418561 +0200 +@@ -0,0 +1,214 @@ ++/* ++ * Zcomax ZCN-1523H-2-8/5-16 board support ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ return ret; -+} ++#include ++#include + -+static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 value) -+{ -+ void __iomem *base = ar71xx_pcicfg_base; -+ unsigned long flags; -+ int ret; ++#include + -+ DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d value=%08x\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), -+ where, size, value); -+ -+ value = value << (8 * (where & 3)); -+ ret = PCIBIOS_SUCCESSFUL; -+ -+ spin_lock_irqsave(&ar71xx_pci_lock, flags); -+ if (bus->number == 0 && devfn == 0) { -+ u32 t; ++#include "machtype.h" ++#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-ap91-pci.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" + -+ t = PCI_CRP_CMD_WRITE | (where & ~3); -+ t |= ar71xx_pci_get_ble(where, size, 1); ++#define ZCN_1523H_GPIO_BTN_RESET 0 ++#define ZCN_1523H_GPIO_LED_INIT 11 ++#define ZCN_1523H_GPIO_LED_LAN1 17 + -+ DBG("PCI: wr local cfg, ad_cbe:%08x, value:%08x\n", t, value); ++#define ZCN_1523H_2_GPIO_LED_WEAK 13 ++#define ZCN_1523H_2_GPIO_LED_MEDIUM 14 ++#define ZCN_1523H_2_GPIO_LED_STRONG 15 + -+ __raw_writel(t, base + PCI_REG_CRP_AD_CBE); -+ __raw_writel(value, base + PCI_REG_CRP_WRDATA); -+ } else { -+ int err; ++#define ZCN_1523H_5_GPIO_LED_UNKNOWN 1 ++#define ZCN_1523H_5_GPIO_LED_LAN2 13 ++#define ZCN_1523H_5_GPIO_LED_WEAK 14 ++#define ZCN_1523H_5_GPIO_LED_MEDIUM 15 ++#define ZCN_1523H_5_GPIO_LED_STRONG 16 + -+ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, -+ PCI_CFG_CMD_WRITE); ++#define ZCN_1523H_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define ZCN_1523H_KEYS_DEBOUNCE_INTERVAL (3 * ZCN_1523H_KEYS_POLL_INTERVAL) + -+ if (err == 0) -+ __raw_writel(value, base + PCI_REG_CFG_WRDATA); -+ else -+ ret = PCIBIOS_DEVICE_NOT_FOUND; ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition zcn_1523h_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "rootfs", ++ .offset = 0x050000, ++ .size = 0x610000, ++ }, { ++ .name = "kernel", ++ .offset = 0x660000, ++ .size = 0x170000, ++ }, { ++ .name = "configure", ++ .offset = 0x7d0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "mfg", ++ .offset = 0x7e0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "eeprom", ++ .offset = 0x7f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x050000, ++ .size = 0x780000, + } -+ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); -+ -+ return ret; -+} -+ -+static void ar71xx_pci_fixup(struct pci_dev *dev) -+{ -+ u32 t; -+ -+ if (!ar71xx_pci_fixup_enable) -+ return; -+ -+ if (dev->bus->number != 0 || dev->devfn != 0) -+ return; -+ -+ DBG("PCI: fixup host controller %s (%04x:%04x)\n", pci_name(dev), -+ dev->vendor, dev->device); -+ -+ /* setup COMMAND register */ -+ t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE -+ | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; -+ -+ pci_write_config_word(dev, PCI_COMMAND, t); -+} -+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar71xx_pci_fixup); -+ -+int __init ar71xx_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, -+ uint8_t pin) -+{ -+ int irq = -1; -+ int i; -+ -+ slot -= PCI_IDSEL_ADL_START - PCI_IDSEL_BASE; -+ -+ for (i = 0; i < ar71xx_pci_nr_irqs; i++) { -+ struct ar71xx_pci_irq *entry; ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+ entry = &ar71xx_pci_irq_map[i]; -+ if (entry->slot == slot && entry->pin == pin) { -+ irq = entry->irq; -+ break; -+ } -+ } ++static struct flash_platform_data zcn_1523h_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = zcn_1523h_partitions, ++ .nr_parts = ARRAY_SIZE(zcn_1523h_partitions), ++#endif ++}; + -+ if (irq < 0) { -+ printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n", -+ pin, pci_name((struct pci_dev *)dev)); -+ } else { -+ printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n", -+ irq, pin, pci_name((struct pci_dev *)dev)); ++static struct gpio_keys_button zcn_1523h_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = ZCN_1523H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = ZCN_1523H_GPIO_BTN_RESET, ++ .active_low = 1, + } -+ -+ return irq; -+} -+ -+static struct pci_ops ar71xx_pci_ops = { -+ .read = ar71xx_pci_read_config, -+ .write = ar71xx_pci_write_config, +}; + -+static struct resource ar71xx_pci_io_resource = { -+ .name = "PCI IO space", -+ .start = 0, -+ .end = 0, -+ .flags = IORESOURCE_IO, ++static struct gpio_led zcn_1523h_leds_gpio[] __initdata = { ++ { ++ .name = "zcn-1523h:amber:init", ++ .gpio = ZCN_1523H_GPIO_LED_INIT, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:green:lan1", ++ .gpio = ZCN_1523H_GPIO_LED_LAN1, ++ .active_low = 1, ++ } +}; + -+static struct resource ar71xx_pci_mem_resource = { -+ .name = "PCI memory space", -+ .start = AR71XX_PCI_MEM_BASE, -+ .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, -+ .flags = IORESOURCE_MEM ++static struct gpio_led zcn_1523h_2_leds_gpio[] __initdata = { ++ { ++ .name = "zcn-1523h:red:weak", ++ .gpio = ZCN_1523H_2_GPIO_LED_WEAK, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:amber:medium", ++ .gpio = ZCN_1523H_2_GPIO_LED_MEDIUM, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:green:strong", ++ .gpio = ZCN_1523H_2_GPIO_LED_STRONG, ++ .active_low = 1, ++ } +}; + -+static struct pci_controller ar71xx_pci_controller = { -+ .pci_ops = &ar71xx_pci_ops, -+ .mem_resource = &ar71xx_pci_mem_resource, -+ .io_resource = &ar71xx_pci_io_resource, ++static struct gpio_led zcn_1523h_5_leds_gpio[] __initdata = { ++ { ++ .name = "zcn-1523h:red:weak", ++ .gpio = ZCN_1523H_5_GPIO_LED_WEAK, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:amber:medium", ++ .gpio = ZCN_1523H_5_GPIO_LED_MEDIUM, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:green:strong", ++ .gpio = ZCN_1523H_5_GPIO_LED_STRONG, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:green:lan2", ++ .gpio = ZCN_1523H_5_GPIO_LED_LAN2, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:amber:unknown", ++ .gpio = ZCN_1523H_5_GPIO_LED_UNKNOWN, ++ } +}; + -+static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) ++static void __init zcn_1523h_generic_setup(void) +{ -+ void __iomem *base = ar71xx_reset_base; -+ u32 pending; -+ -+ pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) & -+ __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f7e0004); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + -+ if (pending & PCI_INT_DEV0) -+ generic_handle_irq(AR71XX_PCI_IRQ_DEV0); ++ ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + -+ else if (pending & PCI_INT_DEV1) -+ generic_handle_irq(AR71XX_PCI_IRQ_DEV1); ++ ar71xx_add_device_m25p80(&zcn_1523h_flash_data); + -+ else if (pending & PCI_INT_DEV2) -+ generic_handle_irq(AR71XX_PCI_IRQ_DEV2); ++ ar71xx_add_device_leds_gpio(0, ARRAY_SIZE(zcn_1523h_leds_gpio), ++ zcn_1523h_leds_gpio); + -+ else if (pending & PCI_INT_CORE) -+ generic_handle_irq(AR71XX_PCI_IRQ_CORE); ++ ar71xx_register_gpio_keys_polled(-1, ZCN_1523H_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(zcn_1523h_gpio_keys), ++ zcn_1523h_gpio_keys); + -+ else -+ spurious_interrupt(); -+} ++ ap91_pci_init(ee, mac); + -+static void ar71xx_pci_irq_unmask(struct irq_data *d) -+{ -+ void __iomem *base = ar71xx_reset_base; -+ u32 t; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); + -+ d->irq -= AR71XX_PCI_IRQ_BASE; ++ /* LAN1 port */ ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); -+ __raw_writel(t | (1 << d->irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ /* LAN2 port */ ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; + -+ /* flush write */ -+ (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ ar71xx_add_device_mdio(0x0); ++ ar71xx_add_device_eth(0); +} + -+static void ar71xx_pci_irq_mask(struct irq_data *d) ++static void __init zcn_1523h_2_setup(void) +{ -+ void __iomem *base = ar71xx_reset_base; -+ u32 t; ++ zcn_1523h_generic_setup(); ++ ap91_pci_setup_wmac_gpio(BIT(9), 0); + -+ d->irq -= AR71XX_PCI_IRQ_BASE; -+ -+ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); -+ __raw_writel(t & ~(1 << d->irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); -+ -+ /* flush write */ -+ (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ ar71xx_add_device_leds_gpio(1, ARRAY_SIZE(zcn_1523h_2_leds_gpio), ++ zcn_1523h_2_leds_gpio); +} + -+static struct irq_chip ar71xx_pci_irq_chip = { -+ .name = "AR71XX PCI ", -+ .irq_mask = ar71xx_pci_irq_mask, -+ .irq_unmask = ar71xx_pci_irq_unmask, -+ .irq_mask_ack = ar71xx_pci_irq_mask, -+}; ++MIPS_MACHINE(AR71XX_MACH_ZCN_1523H_2, "ZCN-1523H-2", "Zcomax ZCN-1523H-2", ++ zcn_1523h_2_setup); + -+static void __init ar71xx_pci_irq_init(void) ++static void __init zcn_1523h_5_setup(void) +{ -+ void __iomem *base = ar71xx_reset_base; -+ int i; -+ -+ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE); -+ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS); -+ -+ for (i = AR71XX_PCI_IRQ_BASE; -+ i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) { -+ irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip, -+ handle_level_irq); -+ } ++ zcn_1523h_generic_setup(); ++ ap91_pci_setup_wmac_gpio(BIT(8), 0); + -+ irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar71xx_pci_irq_handler); ++ ar71xx_add_device_leds_gpio(1, ARRAY_SIZE(zcn_1523h_5_leds_gpio), ++ zcn_1523h_5_leds_gpio); ++ ar71xx_add_device_eth(1); +} + -+int __init ar71xx_pcibios_init(void) -+{ -+ void __iomem *ddr_base = ar71xx_ddr_base; -+ -+ ar71xx_device_stop(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE); -+ ar71xx_pci_delay(); ++MIPS_MACHINE(AR71XX_MACH_ZCN_1523H_5, "ZCN-1523H-5", "Zcomax ZCN-1523H-5", ++ zcn_1523h_5_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Makefile linux-2.6.39/arch/mips/ar71xx/Makefile +--- linux-2.6.39.orig/arch/mips/ar71xx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/Makefile 2011-08-24 02:41:55.677990354 +0200 +@@ -0,0 +1,67 @@ ++# ++# Makefile for the Atheros AR71xx SoC specific parts of the kernel ++# ++# Copyright (C) 2008-2009 Gabor Juhos ++# Copyright (C) 2008 Imre Kaloz ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License version 2 as published ++# by the Free Software Foundation. + -+ ar71xx_device_start(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE); -+ ar71xx_pci_delay(); ++obj-y := prom.o irq.o setup.o devices.o gpio.o ar71xx.o + -+ ar71xx_pcicfg_base = ioremap_nocache(AR71XX_PCI_CFG_BASE, -+ AR71XX_PCI_CFG_SIZE); -+ if (ar71xx_pcicfg_base == NULL) -+ return -ENOMEM; ++obj-$(CONFIG_EARLY_PRINTK) += early_printk.o ++obj-$(CONFIG_PCI) += pci.o + -+ __raw_writel(PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0); -+ __raw_writel(PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1); -+ __raw_writel(PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2); -+ __raw_writel(PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3); -+ __raw_writel(PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4); -+ __raw_writel(PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5); -+ __raw_writel(PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6); -+ __raw_writel(PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7); -+ -+ ar71xx_pci_delay(); -+ -+ /* clear bus errors */ -+ (void)ar71xx_pci_be_handler(1); ++obj-$(CONFIG_AR71XX_DEV_AP91_PCI) += dev-ap91-pci.o ++obj-$(CONFIG_AR71XX_DEV_AP94_PCI) += dev-ap94-pci.o ++obj-$(CONFIG_AR71XX_DEV_AR9XXX_WMAC) += dev-ar9xxx-wmac.o ++obj-$(CONFIG_AR71XX_DEV_DB120_PCI) += dev-db120-pci.o ++obj-$(CONFIG_AR71XX_DEV_DSA) += dev-dsa.o ++obj-$(CONFIG_AR71XX_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o ++obj-$(CONFIG_AR71XX_DEV_LEDS_GPIO) += dev-leds-gpio.o ++obj-$(CONFIG_AR71XX_DEV_M25P80) += dev-m25p80.o ++obj-$(CONFIG_AR71XX_DEV_PB42_PCI) += dev-pb42-pci.o ++obj-$(CONFIG_AR71XX_DEV_PB9X_PCI) += dev-pb9x-pci.o ++obj-$(CONFIG_AR71XX_DEV_USB) += dev-usb.o + -+ ar71xx_pci_fixup_enable = 1; -+ ar71xx_pci_irq_init(); -+ register_pci_controller(&ar71xx_pci_controller); ++obj-$(CONFIG_AR71XX_NVRAM) += nvram.o ++obj-$(CONFIG_AR71XX_PCI_ATH9K_FIXUP) += pci-ath9k-fixup.o + -+ return 0; -+} -diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c linux-2.6.39/arch/mips/pci/pci-ar724x.c ---- linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/pci/pci-ar724x.c 2011-06-01 14:02:22.000000000 +0200 -@@ -0,0 +1,394 @@ ++obj-$(CONFIG_AR71XX_MACH_AP121) += mach-ap121.o ++obj-$(CONFIG_AR71XX_MACH_AP81) += mach-ap81.o ++obj-$(CONFIG_AR71XX_MACH_AP83) += mach-ap83.o ++obj-$(CONFIG_AR71XX_MACH_AP96) += mach-ap96.o ++obj-$(CONFIG_AR71XX_MACH_AW_NR580) += mach-aw-nr580.o ++obj-$(CONFIG_AR71XX_MACH_DB120) += mach-db120.o ++obj-$(CONFIG_AR71XX_MACH_DIR_600_A1) += mach-dir-600-a1.o ++obj-$(CONFIG_AR71XX_MACH_DIR_615_C1) += mach-dir-615-c1.o ++obj-$(CONFIG_AR71XX_MACH_DIR_825_B1) += mach-dir-825-b1.o ++obj-$(CONFIG_AR71XX_MACH_EAP7660D) += mach-eap7660d.o ++obj-$(CONFIG_AR71XX_MACH_JA76PF) += mach-ja76pf.o ++obj-$(CONFIG_AR71XX_MACH_JWAP003) += mach-jwap003.o ++obj-$(CONFIG_AR71XX_MACH_MZK_W04NU) += mach-mzk-w04nu.o ++obj-$(CONFIG_AR71XX_MACH_MZK_W300NH) += mach-mzk-w300nh.o ++obj-$(CONFIG_AR71XX_MACH_NBG460N) += mach-nbg460n.o ++obj-$(CONFIG_AR71XX_MACH_PB42) += mach-pb42.o ++obj-$(CONFIG_AR71XX_MACH_PB44) += mach-pb44.o ++obj-$(CONFIG_AR71XX_MACH_PB92) += mach-pb92.o ++obj-$(CONFIG_AR71XX_MACH_RB4XX) += mach-rb4xx.o ++obj-$(CONFIG_AR71XX_MACH_RB750) += mach-rb750.o ++obj-$(CONFIG_AR71XX_MACH_TEW_632BRP) += mach-tew-632brp.o ++obj-$(CONFIG_AR71XX_MACH_TL_MR3X20) += mach-tl-mr3x20.o ++obj-$(CONFIG_AR71XX_MACH_TL_WA901ND) += mach-tl-wa901nd.o ++obj-$(CONFIG_AR71XX_MACH_TL_WA901ND_V2) += mach-tl-wa901nd-v2.o ++obj-$(CONFIG_AR71XX_MACH_TL_WR741ND) += mach-tl-wr741nd.o ++obj-$(CONFIG_AR71XX_MACH_TL_WR841N_V1) += mach-tl-wr841n.o ++obj-$(CONFIG_AR71XX_MACH_TL_WR941ND) += mach-tl-wr941nd.o ++obj-$(CONFIG_AR71XX_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o ++obj-$(CONFIG_AR71XX_MACH_UBNT) += mach-ubnt.o ++obj-$(CONFIG_AR71XX_MACH_WNDR3700) += mach-wndr3700.o ++obj-$(CONFIG_AR71XX_MACH_WNR2000) += mach-wnr2000.o ++obj-$(CONFIG_AR71XX_MACH_WP543) += mach-wp543.o ++obj-$(CONFIG_AR71XX_MACH_WRT160NL) += mach-wrt160nl.o ++obj-$(CONFIG_AR71XX_MACH_WRT400N) += mach-wrt400n.o ++obj-$(CONFIG_AR71XX_MACH_WZR_HP_G300NH) += mach-wzr-hp-g300nh.o ++obj-$(CONFIG_AR71XX_MACH_WZR_HP_AG300H) += mach-wzr-hp-ag300h.o ++obj-$(CONFIG_AR71XX_MACH_ZCN_1523H) += mach-zcn-1523h.o +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.c linux-2.6.39/arch/mips/ar71xx/nvram.c +--- linux-2.6.39.orig/arch/mips/ar71xx/nvram.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/nvram.c 2011-08-24 02:41:55.677990354 +0200 +@@ -0,0 +1,75 @@ +/* -+ * Atheros AR724x PCI host controller driver -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos ++ * Atheros AR71xx minimal nvram support + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include ++#include ++#include ++#include ++#include ++#include + -+#undef DEBUG -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_INFO fmt, ## args) -+#else -+#define DBG(fmt, args...) -+#endif ++#include "nvram.h" + -+static void __iomem *ar724x_pci_localcfg_base; -+static void __iomem *ar724x_pci_devcfg_base; -+static void __iomem *ar724x_pci_ctrl_base; -+static int ar724x_pci_fixup_enable; ++char *nvram_find_var(const char *name, const char *buf, unsigned buf_len) ++{ ++ unsigned len = strlen(name); ++ char *cur, *last; + -+static DEFINE_SPINLOCK(ar724x_pci_lock); ++ if (buf_len == 0 || len == 0) ++ return NULL; + -+static void ar724x_pci_read(void __iomem *base, int where, int size, u32 *value) -+{ -+ unsigned long flags; -+ u32 data; ++ if (buf_len < len) ++ return NULL; + -+ spin_lock_irqsave(&ar724x_pci_lock, flags); -+ data = __raw_readl(base + (where & ~3)); ++ if (len == 1) ++ return memchr(buf, (int) *name, buf_len); + -+ switch (size) { -+ case 1: -+ if (where & 1) -+ data >>= 8; -+ if (where & 2) -+ data >>= 16; -+ data &= 0xFF; -+ break; -+ case 2: -+ if (where & 2) -+ data >>= 16; -+ data &= 0xFFFF; -+ break; -+ } ++ last = (char *) buf + buf_len - len; ++ for (cur = (char *) buf; cur <= last; cur++) ++ if (cur[0] == name[0] && memcmp(cur, name, len) == 0) ++ return cur + len; + -+ *value = data; -+ spin_unlock_irqrestore(&ar724x_pci_lock, flags); ++ return NULL; +} + -+static void ar724x_pci_write(void __iomem *base, int where, int size, u32 value) ++int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, ++ const char *name, char *mac) +{ -+ unsigned long flags; -+ u32 data; -+ int s; ++ char *buf; ++ char *mac_str; ++ int ret; ++ int t; + -+ spin_lock_irqsave(&ar724x_pci_lock, flags); -+ data = __raw_readl(base + (where & ~3)); ++ buf = vmalloc(nvram_len); ++ if (!buf) ++ return -ENOMEM; + -+ switch (size) { -+ case 1: -+ s = ((where & 3) << 3); -+ data &= ~(0xFF << s); -+ data |= ((value & 0xFF) << s); -+ break; -+ case 2: -+ s = ((where & 2) << 3); -+ data &= ~(0xFFFF << s); -+ data |= ((value & 0xFFFF) << s); -+ break; -+ case 4: -+ data = value; -+ break; ++ memcpy(buf, nvram, nvram_len); ++ buf[nvram_len - 1] = '\0'; ++ ++ mac_str = nvram_find_var(name, buf, nvram_len); ++ if (!mac_str) { ++ ret = -EINVAL; ++ goto free; + } + -+ __raw_writel(data, base + (where & ~3)); -+ /* flush write */ -+ (void)__raw_readl(base + (where & ~3)); -+ spin_unlock_irqrestore(&ar724x_pci_lock, flags); -+} ++ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", ++ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); + -+static int ar724x_pci_read_config(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 *value) -+{ ++ if (t != 6) { ++ ret = -EINVAL; ++ goto free; ++ } + -+ if (bus->number != 0 || devfn != 0) -+ return PCIBIOS_DEVICE_NOT_FOUND; ++ ret = 0; + -+ ar724x_pci_read(ar724x_pci_devcfg_base, where, size, value); ++free: ++ vfree(buf); ++ return ret; ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.h linux-2.6.39/arch/mips/ar71xx/nvram.h +--- linux-2.6.39.orig/arch/mips/ar71xx/nvram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/nvram.h 2011-08-24 02:41:55.687991145 +0200 +@@ -0,0 +1,19 @@ ++/* ++ * Atheros AR71xx minimal nvram support ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d, value=%08x\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), -+ where, size, *value); ++#ifndef _AR71XX_NVRAM_H ++#define _AR71XX_NVRAM_H + -+ /* -+ * WAR for BAR issue - We are unable to access the PCI device space -+ * if we set the BAR with proper base address -+ */ -+ if ((where == 0x10) && (size == 4)) { -+ if (ar71xx_soc == AR71XX_SOC_AR7240) -+ ar724x_pci_write(ar724x_pci_devcfg_base, where, size, 0xffff); -+ else -+ ar724x_pci_write(ar724x_pci_devcfg_base, where, size, 0x1000ffff); -+ } ++char *nvram_find_var(const char *name, const char *buf, ++ unsigned buf_len) __init; ++int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, ++ const char *name, char *mac) __init; + -+ return PCIBIOS_SUCCESSFUL; -+} ++#endif /* _AR71XX_NVRAM_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.c linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.c +--- linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.c 2011-08-24 02:41:55.697990606 +0200 +@@ -0,0 +1,123 @@ ++/* ++ * Atheros AP94 reference board PCI initialization ++ * ++ * Copyright (C) 2009-2010 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+static int ar724x_pci_write_config(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 value) -+{ -+ if (bus->number != 0 || devfn != 0) -+ return PCIBIOS_DEVICE_NOT_FOUND; ++#include ++#include + -+ DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d, value=%08x\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), -+ where, size, value); ++#include ++#include + -+ ar724x_pci_write(ar724x_pci_devcfg_base, where, size, value); ++struct ath9k_fixup { ++ u16 *cal_data; ++ unsigned slot; ++}; + -+ return PCIBIOS_SUCCESSFUL; -+} ++static int ath9k_num_fixups; ++static struct ath9k_fixup ath9k_fixups[2]; + -+static void ar724x_pci_fixup(struct pci_dev *dev) ++static void ath9k_pci_fixup(struct pci_dev *dev) +{ ++ void __iomem *mem; ++ u16 *cal_data = NULL; + u16 cmd; ++ u32 bar0; ++ u32 val; ++ unsigned i; + -+ if (!ar724x_pci_fixup_enable) ++ for (i = 0; i < ath9k_num_fixups; i++) { ++ if (ath9k_fixups[i].cal_data == NULL) ++ continue; ++ ++ if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn)) ++ continue; ++ ++ cal_data = ath9k_fixups[i].cal_data; ++ break; ++ } ++ ++ if (cal_data == NULL) + return; + -+ if (dev->bus->number != 0 || dev->devfn != 0) ++ if (*cal_data != 0xa55a) { ++ pr_err("pci %s: invalid calibration data\n", pci_name(dev)); + return; ++ } + -+ /* setup COMMAND register */ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | -+ PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | -+ PCI_COMMAND_FAST_BACK; ++ pr_info("pci %s: fixup device configuration\n", pci_name(dev)); + -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+} -+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar724x_pci_fixup); ++ mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000); ++ if (!mem) { ++ pr_err("pci %s: ioremap error\n", pci_name(dev)); ++ return; ++ } + -+int __init ar724x_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, -+ uint8_t pin) -+{ -+ int irq = -1; -+ int i; ++ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); + -+ for (i = 0; i < ar71xx_pci_nr_irqs; i++) { -+ struct ar71xx_pci_irq *entry; -+ entry = &ar71xx_pci_irq_map[i]; ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7161: ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, ++ AR71XX_PCI_MEM_BASE); ++ break; ++ case AR71XX_SOC_AR7240: ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff); ++ break; + -+ if (entry->slot == slot && entry->pin == pin) { -+ irq = entry->irq; -+ break; -+ } ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff); ++ break; ++ ++ default: ++ BUG(); + } + -+ if (irq < 0) -+ printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n", -+ pin, pci_name((struct pci_dev *)dev)); -+ else -+ printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n", -+ irq, pin, pci_name((struct pci_dev *)dev)); ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; ++ pci_write_config_word(dev, PCI_COMMAND, cmd); + -+ return irq; -+} ++ /* set pointer to first reg address */ ++ cal_data += 3; ++ while (*cal_data != 0xffff) { ++ u32 reg; ++ reg = *cal_data++; ++ val = *cal_data++; ++ val |= (*cal_data++) << 16; + -+static struct pci_ops ar724x_pci_ops = { -+ .read = ar724x_pci_read_config, -+ .write = ar724x_pci_write_config, -+}; ++ __raw_writel(val, mem + reg); ++ udelay(100); ++ } + -+static struct resource ar724x_pci_io_resource = { -+ .name = "PCI IO space", -+ .start = 0, -+ .end = 0, -+ .flags = IORESOURCE_IO, -+}; ++ pci_read_config_dword(dev, PCI_VENDOR_ID, &val); ++ dev->vendor = val & 0xffff; ++ dev->device = (val >> 16) & 0xffff; + -+static struct resource ar724x_pci_mem_resource = { -+ .name = "PCI memory space", -+ .start = AR71XX_PCI_MEM_BASE, -+ .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, -+ .flags = IORESOURCE_MEM -+}; ++ pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); ++ dev->revision = val & 0xff; ++ dev->class = val >> 8; /* upper 3 bytes */ + -+static struct pci_controller ar724x_pci_controller = { -+ .pci_ops = &ar724x_pci_ops, -+ .mem_resource = &ar724x_pci_mem_resource, -+ .io_resource = &ar724x_pci_io_resource, -+}; ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); ++ pci_write_config_word(dev, PCI_COMMAND, cmd); + -+static void __init ar724x_pci_reset(void) -+{ -+ ar71xx_device_stop(AR724X_RESET_PCIE); -+ ar71xx_device_stop(AR724X_RESET_PCIE_PHY); -+ ar71xx_device_stop(AR724X_RESET_PCIE_PHY_SERIAL); -+ udelay(100); ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); + -+ ar71xx_device_start(AR724X_RESET_PCIE_PHY_SERIAL); -+ udelay(100); -+ ar71xx_device_start(AR724X_RESET_PCIE_PHY); -+ ar71xx_device_start(AR724X_RESET_PCIE); ++ iounmap(mem); +} ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup); + -+static int __init ar724x_pci_setup(void) ++void __init pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) +{ -+ void __iomem *base = ar724x_pci_ctrl_base; -+ u32 t; ++ if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups)) ++ return; + -+ /* setup COMMAND register */ -+ t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | -+ PCI_COMMAND_PARITY|PCI_COMMAND_SERR|PCI_COMMAND_FAST_BACK; ++ ath9k_fixups[ath9k_num_fixups].slot = slot; ++ ath9k_fixups[ath9k_num_fixups].cal_data = cal_data; ++ ath9k_num_fixups++; ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.h linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.h +--- linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.h 2011-08-24 02:41:55.697990606 +0200 +@@ -0,0 +1,6 @@ ++#ifndef _PCI_ATH9K_FIXUP ++#define _PCI_ATH9K_FIXUP + -+ ar724x_pci_write(ar724x_pci_localcfg_base, PCI_COMMAND, 4, t); -+ ar724x_pci_write(ar724x_pci_localcfg_base, 0x20, 4, 0x1ff01000); -+ ar724x_pci_write(ar724x_pci_localcfg_base, 0x24, 4, 0x1ff01000); ++void pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) __init; + -+ t = __raw_readl(base + AR724X_PCI_REG_RESET); -+ if (t != 0x7) { -+ udelay(100000); -+ __raw_writel(0, base + AR724X_PCI_REG_RESET); -+ udelay(100); -+ __raw_writel(4, base + AR724X_PCI_REG_RESET); -+ udelay(100000); -+ } ++#endif /* _PCI_ATH9K_FIXUP */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci.c linux-2.6.39/arch/mips/ar71xx/pci.c +--- linux-2.6.39.orig/arch/mips/ar71xx/pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/pci.c 2011-08-24 02:41:55.697990606 +0200 +@@ -0,0 +1,97 @@ ++/* ++ * Atheros AR71xx PCI setup code ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ if (ar71xx_soc == AR71XX_SOC_AR7240) -+ t = AR724X_PCI_APP_LTSSM_ENABLE; -+ else -+ t = 0x1ffc1; -+ __raw_writel(t, base + AR724X_PCI_REG_APP); -+ /* flush write */ -+ (void) __raw_readl(base + AR724X_PCI_REG_APP); -+ udelay(1000); ++#include + -+ t = __raw_readl(base + AR724X_PCI_REG_RESET); -+ if ((t & AR724X_PCI_RESET_LINK_UP) == 0x0) { -+ printk(KERN_WARNING "PCI: no PCIe module found\n"); -+ return -ENODEV; -+ } ++#include + -+ if (ar71xx_soc == AR71XX_SOC_AR7241 || ar71xx_soc == AR71XX_SOC_AR7242) { -+ t = __raw_readl(base + AR724X_PCI_REG_APP); -+ t |= BIT(16); -+ __raw_writel(t, base + AR724X_PCI_REG_APP); -+ } ++#include ++#include + -+ return 0; -+} ++unsigned ar71xx_pci_nr_irqs __initdata; ++struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata; + -+static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) -+{ -+ void __iomem *base = ar724x_pci_ctrl_base; -+ u32 pending; ++int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev); + -+ pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & -+ __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++static int ar71xx_be_handler(struct pt_regs *regs, int is_fixup) ++{ ++ int err = 0; + -+ if (pending & AR724X_PCI_INT_DEV0) -+ generic_handle_irq(AR71XX_PCI_IRQ_DEV0); ++ err = ar71xx_pci_be_handler(is_fixup); + -+ else -+ spurious_interrupt(); ++ return (is_fixup && !err) ? MIPS_BE_FIXUP : MIPS_BE_FATAL; +} + -+static void ar724x_pci_irq_unmask(struct irq_data *d) ++int pcibios_plat_dev_init(struct pci_dev *dev) +{ -+ void __iomem *base = ar724x_pci_ctrl_base; -+ u32 t; -+ -+ switch (d->irq) { -+ case AR71XX_PCI_IRQ_DEV0: -+ d->irq -= AR71XX_PCI_IRQ_BASE; ++ if (ar71xx_pci_plat_dev_init) ++ return ar71xx_pci_plat_dev_init(dev); + -+ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); -+ __raw_writel(t | AR724X_PCI_INT_DEV0, -+ base + AR724X_PCI_REG_INT_MASK); -+ /* flush write */ -+ (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK); -+ } ++ return 0; +} + -+static void ar724x_pci_irq_mask(struct irq_data *d) ++int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) +{ -+ void __iomem *base = ar724x_pci_ctrl_base; -+ u32 t; -+ -+ switch (d->irq) { -+ case AR71XX_PCI_IRQ_DEV0: -+ d->irq -= AR71XX_PCI_IRQ_BASE; -+ -+ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); -+ __raw_writel(t & ~AR724X_PCI_INT_DEV0, -+ base + AR724X_PCI_REG_INT_MASK); ++ int ret = 0; + -+ /* flush write */ -+ (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ ret = ar71xx_pcibios_map_irq(dev, slot, pin); ++ break; + -+ t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS); -+ __raw_writel(t | AR724X_PCI_INT_DEV0, -+ base + AR724X_PCI_REG_INT_STATUS); ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ret = ar724x_pcibios_map_irq(dev, slot, pin); ++ break; + -+ /* flush write */ -+ (void) __raw_readl(base + AR724X_PCI_REG_INT_STATUS); ++ default: ++ break; + } -+} + -+static struct irq_chip ar724x_pci_irq_chip = { -+ .name = "AR724X PCI ", -+ .irq_mask = ar724x_pci_irq_mask, -+ .irq_unmask = ar724x_pci_irq_unmask, -+ .irq_mask_ack = ar724x_pci_irq_mask, -+}; ++ return ret; ++} + -+static void __init ar724x_pci_irq_init(void) ++int __init ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) +{ -+ void __iomem *base = ar724x_pci_ctrl_base; -+ u32 t; -+ int i; ++ int ret = 0; + -+ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); -+ if (t & (AR724X_RESET_PCIE | AR724X_RESET_PCIE_PHY | -+ AR724X_RESET_PCIE_PHY_SERIAL)) { -+ return; -+ } ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ board_be_handler = ar71xx_be_handler; ++ ret = ar71xx_pcibios_init(); ++ break; + -+ __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); -+ __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ret = ar724x_pcibios_init(); ++ break; + -+ for (i = AR71XX_PCI_IRQ_BASE; -+ i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) { -+ irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, -+ handle_level_irq); ++ default: ++ return 0; + } + -+ irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar724x_pci_irq_handler); -+} -+ -+int __init ar724x_pcibios_init(void) -+{ -+ int ret = -ENOMEM; -+ -+ ar724x_pci_localcfg_base = ioremap_nocache(AR724X_PCI_CRP_BASE, -+ AR724X_PCI_CRP_SIZE); -+ if (ar724x_pci_localcfg_base == NULL) -+ goto err; -+ -+ ar724x_pci_devcfg_base = ioremap_nocache(AR724X_PCI_CFG_BASE, -+ AR724X_PCI_CFG_SIZE); -+ if (ar724x_pci_devcfg_base == NULL) -+ goto err_unmap_localcfg; -+ -+ ar724x_pci_ctrl_base = ioremap_nocache(AR724X_PCI_CTRL_BASE, -+ AR724X_PCI_CTRL_SIZE); -+ if (ar724x_pci_ctrl_base == NULL) -+ goto err_unmap_devcfg; -+ -+ ar724x_pci_reset(); -+ ret = ar724x_pci_setup(); -+ if (ret) -+ goto err_unmap_ctrl; -+ -+ ar724x_pci_fixup_enable = 1; -+ ar724x_pci_irq_init(); -+ register_pci_controller(&ar724x_pci_controller); -+ -+ return 0; ++ ar71xx_pci_nr_irqs = nr_irqs; ++ ar71xx_pci_irq_map = map; + -+ err_unmap_ctrl: -+ iounmap(ar724x_pci_ctrl_base); -+ err_unmap_devcfg: -+ iounmap(ar724x_pci_devcfg_base); -+ err_unmap_localcfg: -+ iounmap(ar724x_pci_localcfg_base); -+ err: + return ret; +} -diff -Nur linux-2.6.39.orig/drivers/char/Kconfig linux-2.6.39/drivers/char/Kconfig ---- linux-2.6.39.orig/drivers/char/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/char/Kconfig 2011-05-27 14:36:51.000000000 +0200 -@@ -511,6 +511,14 @@ - pc8736x_gpio drivers. If those drivers are built as - modules, this one will be too, named nsc_gpio - -+config GPIO_DEVICE -+ tristate "GPIO device support" -+ depends on GENERIC_GPIO -+ help -+ Say Y to enable Linux GPIO device support. This allows control of -+ GPIO pins using a character device -+ -+ - config RAW_DRIVER - tristate "RAW driver (/dev/raw/rawN)" - depends on BLOCK -diff -Nur linux-2.6.39.orig/drivers/char/Makefile linux-2.6.39/drivers/char/Makefile ---- linux-2.6.39.orig/drivers/char/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/char/Makefile 2011-05-27 14:36:51.000000000 +0200 -@@ -47,6 +47,7 @@ - obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o - obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o - obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o -+obj-$(CONFIG_GPIO_DEVICE) += gpio_dev.o - obj-$(CONFIG_GPIO_TB0219) += tb0219.o - obj-$(CONFIG_TELCLOCK) += tlclk.o - -diff -Nur linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c linux-2.6.39/drivers/gpio/nxp_74hc153.c ---- linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/gpio/nxp_74hc153.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,246 @@ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/prom.c linux-2.6.39/arch/mips/ar71xx/prom.c +--- linux-2.6.39.orig/arch/mips/ar71xx/prom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/prom.c 2011-08-24 02:41:55.737990425 +0200 +@@ -0,0 +1,189 @@ +/* -+ * NXP 74HC153 - Dual 4-input multiplexer GPIO driver ++ * Atheros AR71xx SoC specific prom routines + * -+ * Copyright (C) 2010 Gabor Juhos ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + */ + -+#include ++#include +#include -+#include -+#include -+#include ++#include ++#include + -+#define NXP_74HC153_NUM_GPIOS 8 -+#define NXP_74HC153_S0_MASK 0x1 -+#define NXP_74HC153_S1_MASK 0x2 -+#define NXP_74HC153_BANK_MASK 0x4 ++#include ++#include ++#include + -+struct nxp_74hc153_chip { -+ struct device *parent; -+ struct gpio_chip gpio_chip; -+ struct mutex lock; -+}; ++#include + -+static struct nxp_74hc153_chip *gpio_to_nxp(struct gpio_chip *gc) ++static inline int is_valid_ram_addr(void *addr) +{ -+ return container_of(gc, struct nxp_74hc153_chip, gpio_chip); -+} ++ if (((u32) addr > KSEG0) && ++ ((u32) addr < (KSEG0 + AR71XX_MEM_SIZE_MAX))) ++ return 1; ++ ++ if (((u32) addr > KSEG1) && ++ ((u32) addr < (KSEG1 + AR71XX_MEM_SIZE_MAX))) ++ return 1; + -+static int nxp_74hc153_direction_input(struct gpio_chip *gc, unsigned offset) -+{ + return 0; +} + -+static int nxp_74hc153_direction_output(struct gpio_chip *gc, -+ unsigned offset, int val) ++static void __init ar71xx_prom_append_cmdline(const char *name, ++ const char *value) +{ -+ return -EINVAL; ++ char buf[COMMAND_LINE_SIZE]; ++ ++ snprintf(buf, sizeof(buf), " %s=%s", name, value); ++ strlcat(arcs_cmdline, buf, sizeof(arcs_cmdline)); +} + -+static int nxp_74hc153_get_value(struct gpio_chip *gc, unsigned offset) ++static const char * __init ar71xx_prom_find_env(char **envp, const char *name) +{ -+ struct nxp_74hc153_chip *nxp; -+ struct nxp_74hc153_platform_data *pdata; -+ unsigned s0; -+ unsigned s1; -+ unsigned pin; -+ int ret; ++ const char *ret = NULL; ++ int len; ++ char **p; + -+ nxp = gpio_to_nxp(gc); -+ pdata = nxp->parent->platform_data; ++ if (!is_valid_ram_addr(envp)) ++ return NULL; + -+ s0 = !!(offset & NXP_74HC153_S0_MASK); -+ s1 = !!(offset & NXP_74HC153_S1_MASK); -+ pin = (offset & NXP_74HC153_BANK_MASK) ? pdata->gpio_pin_2y -+ : pdata->gpio_pin_1y; ++ len = strlen(name); ++ for (p = envp; is_valid_ram_addr(*p); p++) { ++ if (strncmp(name, *p, len) == 0 && (*p)[len] == '=') { ++ ret = *p + len + 1; ++ break; ++ } + -+ mutex_lock(&nxp->lock); -+ gpio_set_value(pdata->gpio_pin_s0, s0); -+ gpio_set_value(pdata->gpio_pin_s1, s1); -+ ret = gpio_get_value(pin); -+ mutex_unlock(&nxp->lock); ++ /* RedBoot env comes in pointer pairs - key, value */ ++ if (strncmp(name, *p, len) == 0 && (*p)[len] == 0) ++ if (is_valid_ram_addr(*(++p))) { ++ ret = *p; ++ break; ++ } ++ } + + return ret; +} + -+static void nxp_74hc153_set_value(struct gpio_chip *gc, -+ unsigned offset, int val) -+{ -+ /* not supported */ -+} -+ -+static int __devinit nxp_74hc153_probe(struct platform_device *pdev) ++static int __init ar71xx_prom_init_myloader(void) +{ -+ struct nxp_74hc153_platform_data *pdata; -+ struct nxp_74hc153_chip *nxp; -+ struct gpio_chip *gc; -+ int err; ++ struct myloader_info *mylo; ++ char mac_buf[32]; ++ char *mac; + -+ pdata = pdev->dev.platform_data; -+ if (pdata == NULL) { -+ dev_dbg(&pdev->dev, "no platform data specified\n"); -+ return -EINVAL; -+ } ++ mylo = myloader_get_info(); ++ if (!mylo) ++ return 0; + -+ nxp = kzalloc(sizeof(struct nxp_74hc153_chip), GFP_KERNEL); -+ if (nxp == NULL) { -+ dev_err(&pdev->dev, "no memory for private data\n"); -+ return -ENOMEM; ++ switch (mylo->did) { ++ case DEVID_COMPEX_WP543: ++ ar71xx_prom_append_cmdline("board", "WP543"); ++ break; ++ default: ++ printk(KERN_WARNING "prom: unknown device id: %x\n", ++ mylo->did); ++ return 0; + } + -+ err = gpio_request(pdata->gpio_pin_s0, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_s0, err); -+ goto err_free_nxp; -+ } ++ mac = mylo->macs[0]; ++ snprintf(mac_buf, sizeof(mac_buf), "%02x:%02x:%02x:%02x:%02x:%02x", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + -+ err = gpio_request(pdata->gpio_pin_s1, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_s1, err); -+ goto err_free_s0; -+ } ++ ar71xx_prom_append_cmdline("ethaddr", mac_buf); + -+ err = gpio_request(pdata->gpio_pin_1y, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_1y, err); -+ goto err_free_s1; -+ } ++ return 1; ++} + -+ err = gpio_request(pdata->gpio_pin_2y, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_2y, err); -+ goto err_free_1y; -+ } ++#ifdef CONFIG_IMAGE_CMDLINE_HACK ++extern char __image_cmdline[]; + -+ err = gpio_direction_output(pdata->gpio_pin_s0, 0); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_s0, err); -+ goto err_free_2y; -+ } ++static int __init ar71xx_use__image_cmdline(void) ++{ ++ char *p = __image_cmdline; ++ int replace = 0; + -+ err = gpio_direction_output(pdata->gpio_pin_s1, 0); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_s1, err); -+ goto err_free_2y; ++ if (*p == '-') { ++ replace = 1; ++ p++; + } + -+ err = gpio_direction_input(pdata->gpio_pin_1y); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_1y, err); -+ goto err_free_2y; -+ } ++ if (*p == '\0') ++ return 0; + -+ err = gpio_direction_input(pdata->gpio_pin_2y); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_2y, err); -+ goto err_free_2y; ++ if (replace) { ++ strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline)); ++ } else { ++ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); ++ strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); + } + -+ nxp->parent = &pdev->dev; -+ mutex_init(&nxp->lock); -+ -+ gc = &nxp->gpio_chip; -+ -+ gc->direction_input = nxp_74hc153_direction_input; -+ gc->direction_output = nxp_74hc153_direction_output; -+ gc->get = nxp_74hc153_get_value; -+ gc->set = nxp_74hc153_set_value; -+ gc->can_sleep = 1; ++ return 1; ++} ++#else ++static inline int ar71xx_use__image_cmdline(void) { return 0; } ++#endif + -+ gc->base = pdata->gpio_base; -+ gc->ngpio = NXP_74HC153_NUM_GPIOS; -+ gc->label = dev_name(nxp->parent); -+ gc->dev = nxp->parent; -+ gc->owner = THIS_MODULE; ++static __init void ar71xx_prom_init_cmdline(int argc, char **argv) ++{ ++ int i; + -+ err = gpiochip_add(&nxp->gpio_chip); -+ if (err) { -+ dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); -+ goto err_free_2y; -+ } ++ if (ar71xx_use__image_cmdline()) ++ return; + -+ platform_set_drvdata(pdev, nxp); -+ return 0; ++ if (!is_valid_ram_addr(argv)) ++ return; + -+ err_free_2y: -+ gpio_free(pdata->gpio_pin_2y); -+ err_free_1y: -+ gpio_free(pdata->gpio_pin_1y); -+ err_free_s1: -+ gpio_free(pdata->gpio_pin_s1); -+ err_free_s0: -+ gpio_free(pdata->gpio_pin_s0); -+ err_free_nxp: -+ kfree(nxp); -+ return err; ++ for (i = 0; i < argc; i++) ++ if (is_valid_ram_addr(argv[i])) { ++ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); ++ strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline)); ++ } +} + -+static int nxp_74hc153_remove(struct platform_device *pdev) ++void __init prom_init(void) +{ -+ struct nxp_74hc153_chip *nxp = platform_get_drvdata(pdev); -+ struct nxp_74hc153_platform_data *pdata = pdev->dev.platform_data; ++ const char *env; ++ char **envp; + -+ if (nxp) { -+ int err; ++ printk(KERN_DEBUG "prom: fw_arg0=%08x, fw_arg1=%08x, " ++ "fw_arg2=%08x, fw_arg3=%08x\n", ++ (unsigned int)fw_arg0, (unsigned int)fw_arg1, ++ (unsigned int)fw_arg2, (unsigned int)fw_arg3); + -+ err = gpiochip_remove(&nxp->gpio_chip); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to remove gpio chip, err=%d\n", -+ err); -+ return err; -+ } + -+ gpio_free(pdata->gpio_pin_2y); -+ gpio_free(pdata->gpio_pin_1y); -+ gpio_free(pdata->gpio_pin_s1); -+ gpio_free(pdata->gpio_pin_s0); ++ if (ar71xx_prom_init_myloader()) ++ return; + -+ kfree(nxp); -+ platform_set_drvdata(pdev, NULL); ++ ar71xx_prom_init_cmdline(fw_arg0, (char **)fw_arg1); ++ ++ envp = (char **)fw_arg2; ++ if (!strstr(arcs_cmdline, "ethaddr=")) { ++ env = ar71xx_prom_find_env(envp, "ethaddr"); ++ if (env) ++ ar71xx_prom_append_cmdline("ethaddr", env); + } + -+ return 0; -+} ++ if (!strstr(arcs_cmdline, "board=")) { ++ env = ar71xx_prom_find_env(envp, "board"); ++ if (env) { ++ /* Workaround for buggy bootloaders */ ++ if (strcmp(env, "RouterStation") == 0 || ++ strcmp(env, "Ubiquiti AR71xx-based board") == 0) ++ env = "UBNT-RS"; + -+static struct platform_driver nxp_74hc153_driver = { -+ .probe = nxp_74hc153_probe, -+ .remove = __devexit_p(nxp_74hc153_remove), -+ .driver = { -+ .name = NXP_74HC153_DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; ++ if (strcmp(env, "RouterStation PRO") == 0) ++ env = "UBNT-RSPRO"; + -+static int __init nxp_74hc153_init(void) -+{ -+ return platform_driver_register(&nxp_74hc153_driver); ++ ar71xx_prom_append_cmdline("board", env); ++ } ++ } +} -+subsys_initcall(nxp_74hc153_init); + -+static void __exit nxp_74hc153_exit(void) ++void __init prom_free_prom_memory(void) +{ -+ platform_driver_unregister(&nxp_74hc153_driver); ++ /* We do not have to prom memory to free */ +} -+module_exit(nxp_74hc153_exit); -+ -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC153"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" NXP_74HC153_DRIVER_NAME); -diff -Nur linux-2.6.39.orig/drivers/input/misc/Kconfig linux-2.6.39/drivers/input/misc/Kconfig ---- linux-2.6.39.orig/drivers/input/misc/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/input/misc/Kconfig 2011-05-27 14:36:51.000000000 +0200 -@@ -467,4 +467,20 @@ - To compile this driver as a module, choose M here: the - module will be called xen-kbdfront. - -+config INPUT_GPIO_BUTTONS -+ tristate "Polled GPIO buttons interface" -+ depends on GENERIC_GPIO -+ select INPUT_POLLDEV -+ help -+ This driver implements support for buttons connected -+ to GPIO pins of various CPUs (and some other chips). -+ -+ Say Y here if your device has buttons connected -+ directly to such GPIO pins. Your board-specific -+ setup logic must also provide a platform device, -+ with configuration data saying which GPIOs are used. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called gpio-buttons. -+ - endif -diff -Nur linux-2.6.39.orig/drivers/input/misc/Makefile linux-2.6.39/drivers/input/misc/Makefile ---- linux-2.6.39.orig/drivers/input/misc/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/input/misc/Makefile 2011-05-27 14:36:51.000000000 +0200 -@@ -44,4 +44,5 @@ - obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o - obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o - obj-$(CONFIG_INPUT_YEALINK) += yealink.o -+obj-$(CONFIG_INPUT_GPIO_BUTTONS) += gpio_buttons.o - -diff -Nur linux-2.6.39.orig/drivers/input/misc/gpio_buttons.c linux-2.6.39/drivers/input/misc/gpio_buttons.c ---- linux-2.6.39.orig/drivers/input/misc/gpio_buttons.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/input/misc/gpio_buttons.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,216 @@ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/setup.c linux-2.6.39/arch/mips/ar71xx/setup.c +--- linux-2.6.39.orig/arch/mips/ar71xx/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/setup.c 2011-08-24 02:41:55.737990425 +0200 +@@ -0,0 +1,446 @@ +/* -+ * Driver for buttons on GPIO lines not capable of generating interrupts -+ * -+ * Copyright (C) 2007-2010 Gabor Juhos -+ * Copyright (C) 2010 Nuno Goncalves -+ * -+ * This file was based on: /drivers/input/misc/cobalt_btns.c -+ * Copyright (C) 2007 Yoichi Yuasa ++ * Atheros AR71xx SoC specific setup + * -+ * also was based on: /drivers/input/keyboard/gpio_keys.c -+ * Copyright 2005 Phil Blundell ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. ++ * Parts of this file are based on Atheros 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.31 BSP + * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + */ + +#include -+#include +#include -+#include ++#include + -+#include -+#include -+#include -+#include ++#include ++#include /* for mips_hpt_frequency */ ++#include /* for _machine_{restart,halt} */ ++#include + -+#include ++#include + -+#include ++#include "machtype.h" ++#include "devices.h" + -+#define DRV_NAME "gpio-buttons" -+#define DRV_VERSION "0.1.2" -+#define PFX DRV_NAME ": " ++#define AR71XX_SYS_TYPE_LEN 64 + -+struct gpio_button_data { -+ int last_state; -+ int count; -+}; ++u32 ar71xx_cpu_freq; ++EXPORT_SYMBOL_GPL(ar71xx_cpu_freq); + -+struct gpio_buttons_dev { -+ struct input_polled_dev *poll_dev; -+ struct gpio_buttons_platform_data *pdata; -+ struct gpio_button_data *data; -+}; ++u32 ar71xx_ahb_freq; ++EXPORT_SYMBOL_GPL(ar71xx_ahb_freq); + -+static void gpio_buttons_poll(struct input_polled_dev *dev) -+{ -+ struct gpio_buttons_dev *bdev = dev->private; -+ struct gpio_buttons_platform_data *pdata = bdev->pdata; -+ struct input_dev *input = dev->input; -+ int i; ++u32 ar71xx_ddr_freq; ++EXPORT_SYMBOL_GPL(ar71xx_ddr_freq); + -+ for (i = 0; i < bdev->pdata->nbuttons; i++) { -+ struct gpio_button *button = &pdata->buttons[i]; -+ unsigned int type = button->type ?: EV_KEY; -+ int state; ++u32 ar71xx_ref_freq; ++EXPORT_SYMBOL_GPL(ar71xx_ref_freq); + -+ if (bdev->data[i].count < button->threshold) { -+ bdev->data[i].count++; -+ continue; -+ } ++enum ar71xx_soc_type ar71xx_soc; ++EXPORT_SYMBOL_GPL(ar71xx_soc); + -+ state = gpio_get_value(button->gpio) ? 1 : 0; -+ if (state != bdev->data[i].last_state) { -+ input_event(input, type, button->code, -+ !!(state ^ button->active_low)); -+ input_sync(input); -+ bdev->data[i].count = 0; -+ bdev->data[i].last_state = state; -+ } -+ } ++u32 ar71xx_soc_rev; ++EXPORT_SYMBOL_GPL(ar71xx_soc_rev); ++ ++static char ar71xx_sys_type[AR71XX_SYS_TYPE_LEN]; ++ ++static void ar71xx_restart(char *command) ++{ ++ ar71xx_device_stop(RESET_MODULE_FULL_CHIP); ++ for (;;) ++ if (cpu_wait) ++ cpu_wait(); +} + -+static int __devinit gpio_buttons_probe(struct platform_device *pdev) ++static void ar71xx_halt(void) +{ -+ struct gpio_buttons_platform_data *pdata = pdev->dev.platform_data; -+ struct gpio_buttons_dev *bdev; -+ struct input_polled_dev *poll_dev; -+ struct input_dev *input; -+ int error, i; ++ while (1) ++ cpu_wait(); ++} + -+ if (!pdata) -+ return -ENXIO; ++static void __init ar71xx_detect_mem_size(void) ++{ ++ unsigned long size; + -+ bdev = kzalloc(sizeof(struct gpio_buttons_dev) + -+ sizeof(struct gpio_button_data) * pdata->nbuttons, -+ GFP_KERNEL); -+ if (!bdev) { -+ printk(KERN_ERR DRV_NAME "no memory for device\n"); -+ return -ENOMEM; ++ for (size = AR71XX_MEM_SIZE_MIN; size < AR71XX_MEM_SIZE_MAX; ++ size <<= 1) { ++ if (!memcmp(ar71xx_detect_mem_size, ++ ar71xx_detect_mem_size + size, 1024)) ++ break; + } + -+ bdev->data = (struct gpio_button_data *) &bdev[1]; ++ add_memory_region(0, size, BOOT_MEM_RAM); ++} + -+ poll_dev = input_allocate_polled_device(); -+ if (!poll_dev) { -+ printk(KERN_ERR DRV_NAME "no memory for polled device\n"); -+ error = -ENOMEM; -+ goto err_free_bdev; -+ } ++static void __init ar71xx_detect_sys_type(void) ++{ ++ char *chip = "????"; ++ u32 id; ++ u32 major; ++ u32 minor; ++ u32 rev = 0; ++ ++ id = ar71xx_reset_rr(AR71XX_RESET_REG_REV_ID); ++ major = id & REV_ID_MAJOR_MASK; ++ ++ switch (major) { ++ case REV_ID_MAJOR_AR71XX: ++ minor = id & AR71XX_REV_ID_MINOR_MASK; ++ rev = id >> AR71XX_REV_ID_REVISION_SHIFT; ++ rev &= AR71XX_REV_ID_REVISION_MASK; ++ switch (minor) { ++ case AR71XX_REV_ID_MINOR_AR7130: ++ ar71xx_soc = AR71XX_SOC_AR7130; ++ chip = "7130"; ++ break; ++ ++ case AR71XX_REV_ID_MINOR_AR7141: ++ ar71xx_soc = AR71XX_SOC_AR7141; ++ chip = "7141"; ++ break; + -+ poll_dev->private = bdev; -+ poll_dev->poll = gpio_buttons_poll; -+ poll_dev->poll_interval = pdata->poll_interval; ++ case AR71XX_REV_ID_MINOR_AR7161: ++ ar71xx_soc = AR71XX_SOC_AR7161; ++ chip = "7161"; ++ break; ++ } ++ break; + -+ input = poll_dev->input; ++ case REV_ID_MAJOR_AR7240: ++ ar71xx_soc = AR71XX_SOC_AR7240; ++ chip = "7240"; ++ rev = id & AR724X_REV_ID_REVISION_MASK; ++ break; + -+ input->evbit[0] = BIT(EV_KEY); -+ input->name = pdev->name; -+ input->phys = "gpio-buttons/input0"; -+ input->dev.parent = &pdev->dev; ++ case REV_ID_MAJOR_AR7241: ++ ar71xx_soc = AR71XX_SOC_AR7241; ++ chip = "7241"; ++ rev = id & AR724X_REV_ID_REVISION_MASK; ++ break; + -+ input->id.bustype = BUS_HOST; -+ input->id.vendor = 0x0001; -+ input->id.product = 0x0001; -+ input->id.version = 0x0100; ++ case REV_ID_MAJOR_AR7242: ++ ar71xx_soc = AR71XX_SOC_AR7242; ++ chip = "7242"; ++ rev = id & AR724X_REV_ID_REVISION_MASK; ++ break; + -+ for (i = 0; i < pdata->nbuttons; i++) { -+ struct gpio_button *button = &pdata->buttons[i]; -+ unsigned int gpio = button->gpio; -+ unsigned int type = button->type ?: EV_KEY; ++ case REV_ID_MAJOR_AR913X: ++ minor = id & AR91XX_REV_ID_MINOR_MASK; ++ rev = id >> AR91XX_REV_ID_REVISION_SHIFT; ++ rev &= AR91XX_REV_ID_REVISION_MASK; ++ switch (minor) { ++ case AR91XX_REV_ID_MINOR_AR9130: ++ ar71xx_soc = AR71XX_SOC_AR9130; ++ chip = "9130"; ++ break; + -+ error = gpio_request(gpio, button->desc ? -+ button->desc : DRV_NAME); -+ if (error) { -+ printk(KERN_ERR PFX "unable to claim gpio %u, " -+ "error %d\n", gpio, error); -+ goto err_free_gpio; ++ case AR91XX_REV_ID_MINOR_AR9132: ++ ar71xx_soc = AR71XX_SOC_AR9132; ++ chip = "9132"; ++ break; + } ++ break; + -+ error = gpio_direction_input(gpio); -+ if (error) { -+ printk(KERN_ERR PFX "unable to set direction on " -+ "gpio %u, error %d\n", gpio, error); -+ goto err_free_gpio; -+ } ++ case REV_ID_MAJOR_AR9330: ++ ar71xx_soc = AR71XX_SOC_AR9330; ++ chip = "9330"; ++ rev = id & AR933X_REV_ID_REVISION_MASK; ++ break; + -+ input_set_capability(input, type, button->code); -+ bdev->data[i].last_state = gpio_get_value(button->gpio) ? 1 : 0; -+ } ++ case REV_ID_MAJOR_AR9331: ++ ar71xx_soc = AR71XX_SOC_AR9331; ++ chip = "9331"; ++ rev = id & AR933X_REV_ID_REVISION_MASK; ++ break; ++ ++ case REV_ID_MAJOR_AR9342: ++ ar71xx_soc = AR71XX_SOC_AR9342; ++ chip = "9342"; ++ rev = id & AR934X_REV_ID_REVISION_MASK; ++ break; + -+ bdev->poll_dev = poll_dev; -+ bdev->pdata = pdata; -+ platform_set_drvdata(pdev, bdev); ++ case REV_ID_MAJOR_AR9344: ++ ar71xx_soc = AR71XX_SOC_AR9344; ++ chip = "9344"; ++ rev = id & AR934X_REV_ID_REVISION_MASK; ++ break; + -+ error = input_register_polled_device(poll_dev); -+ if (error) { -+ printk(KERN_ERR PFX "unable to register polled device, " -+ "error %d\n", error); -+ goto err_free_gpio; ++ default: ++ panic("ar71xx: unknown chip id:0x%08x\n", id); + } + -+ return 0; ++ ar71xx_soc_rev = rev; + -+err_free_gpio: -+ for (i = i - 1; i >= 0; i--) -+ gpio_free(pdata->buttons[i].gpio); ++ sprintf(ar71xx_sys_type, "Atheros AR%s rev %u", chip, rev); ++ pr_info("SoC: %s\n", ar71xx_sys_type); ++} + -+ input_free_polled_device(poll_dev); ++static void __init ar934x_detect_sys_frequency(void) ++{ ++ u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; + -+err_free_bdev: -+ kfree(bdev); ++ if (ar71xx_reset_rr(AR934X_RESET_REG_BOOTSTRAP) & AR934X_REF_CLK_40) ++ ar71xx_ref_freq = 40 * 1000 * 1000; ++ else ++ ar71xx_ref_freq = 25 * 1000 * 1000; ++ ++ clk_ctrl = ar71xx_pll_rr(AR934X_PLL_REG_DDR_CTRL_CLOCK); ++ ++ pll = ar71xx_pll_rr(AR934X_PLL_REG_CPU_CONFIG); ++ out_div = AR934X_CPU_PLL_CFG_OUTDIV_GET(pll); ++ ref_div = AR934X_CPU_PLL_CFG_REFDIV_GET(pll); ++ nint = AR934X_CPU_PLL_CFG_NINT_GET(pll); ++ frac = AR934X_CPU_PLL_CFG_NFRAC_GET(pll); ++ postdiv = AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_GET(clk_ctrl); ++ ar71xx_cpu_freq = ((nint * ar71xx_ref_freq / ref_div) >> out_div) / ++ (postdiv + 1); ++ ++ out_div = AR934X_DDR_PLL_CFG_OUTDIV_GET(pll); ++ ref_div = AR934X_DDR_PLL_CFG_REFDIV_GET(pll); ++ nint = AR934X_DDR_PLL_CFG_NINT_GET(pll); ++ frac = AR934X_DDR_PLL_CFG_NFRAC_GET(pll); ++ postdiv = AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_GET(clk_ctrl); ++ ar71xx_ddr_freq = ((nint * ar71xx_ref_freq / ref_div) >> out_div) / ++ (postdiv + 1); ++ ++ postdiv = AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_GET(clk_ctrl); ++ ++ if (AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_GET(clk_ctrl)) { ++ ar71xx_ahb_freq = ar71xx_ddr_freq / (postdiv + 1); ++ } else { ++ ar71xx_ahb_freq = ar71xx_cpu_freq / (postdiv + 1); ++ } + -+ platform_set_drvdata(pdev, NULL); -+ return error; +} + -+static int __devexit gpio_buttons_remove(struct platform_device *pdev) ++static void __init ar91xx_detect_sys_frequency(void) +{ -+ struct gpio_buttons_dev *bdev = platform_get_drvdata(pdev); -+ struct gpio_buttons_platform_data *pdata = bdev->pdata; -+ int i; -+ -+ input_unregister_polled_device(bdev->poll_dev); ++ u32 pll; ++ u32 freq; ++ u32 div; + -+ for (i = 0; i < pdata->nbuttons; i++) -+ gpio_free(pdata->buttons[i].gpio); ++ ar71xx_ref_freq = 5 * 1000 * 1000; + -+ input_free_polled_device(bdev->poll_dev); ++ pll = ar71xx_pll_rr(AR91XX_PLL_REG_CPU_CONFIG); + -+ kfree(bdev); -+ platform_set_drvdata(pdev, NULL); ++ div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK); ++ freq = div * ar71xx_ref_freq; + -+ return 0; -+} ++ ar71xx_cpu_freq = freq; + -+static struct platform_driver gpio_buttons_driver = { -+ .probe = gpio_buttons_probe, -+ .remove = __devexit_p(gpio_buttons_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; ++ div = ((pll >> AR91XX_DDR_DIV_SHIFT) & AR91XX_DDR_DIV_MASK) + 1; ++ ar71xx_ddr_freq = freq / div; + -+static int __init gpio_buttons_init(void) -+{ -+ printk(KERN_INFO DRV_NAME " driver version " DRV_VERSION "\n"); -+ return platform_driver_register(&gpio_buttons_driver); ++ div = (((pll >> AR91XX_AHB_DIV_SHIFT) & AR91XX_AHB_DIV_MASK) + 1) * 2; ++ ar71xx_ahb_freq = ar71xx_cpu_freq / div; +} + -+static void __exit gpio_buttons_exit(void) ++static void __init ar71xx_detect_sys_frequency(void) +{ -+ platform_driver_unregister(&gpio_buttons_driver); -+} -+ -+module_init(gpio_buttons_init); -+module_exit(gpio_buttons_exit); ++ u32 pll; ++ u32 freq; ++ u32 div; + -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_VERSION(DRV_VERSION); -+MODULE_DESCRIPTION("Polled buttons driver for CPU GPIOs"); ++ ar71xx_ref_freq = 40 * 1000 * 1000; + -diff -Nur linux-2.6.39.orig/drivers/leds/leds-rb750.c linux-2.6.39/drivers/leds/leds-rb750.c ---- linux-2.6.39.orig/drivers/leds/leds-rb750.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/leds/leds-rb750.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,140 @@ -+/* -+ * LED driver for the RouterBOARD 750 -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+#include -+#include -+#include -+#include ++ pll = ar71xx_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); + -+#include ++ div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; ++ freq = div * ar71xx_ref_freq; + -+#define DRV_NAME "leds-rb750" ++ div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; ++ ar71xx_cpu_freq = freq / div; + -+struct rb750_led_dev { -+ struct led_classdev cdev; -+ u32 mask; -+ int active_low; -+}; -+ -+struct rb750_led_drvdata { -+ struct rb750_led_dev *led_devs; -+ int num_leds; -+}; ++ div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; ++ ar71xx_ddr_freq = freq / div; + -+static inline struct rb750_led_dev *to_rbled(struct led_classdev *led_cdev) -+{ -+ return (struct rb750_led_dev *)container_of(led_cdev, -+ struct rb750_led_dev, cdev); ++ div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; ++ ar71xx_ahb_freq = ar71xx_cpu_freq / div; +} + -+static void rb750_led_brightness_set(struct led_classdev *led_cdev, -+ enum led_brightness value) ++static void __init ar724x_detect_sys_frequency(void) +{ -+ struct rb750_led_dev *rbled = to_rbled(led_cdev); -+ int level; ++ u32 pll; ++ u32 freq; ++ u32 div; + -+ level = (value == LED_OFF) ? 0 : 1; -+ level ^= rbled->active_low; ++ ar71xx_ref_freq = 5 * 1000 * 1000; + -+ if (level) -+ rb750_latch_change(0, rbled->mask); -+ else -+ rb750_latch_change(rbled->mask, 0); ++ pll = ar71xx_pll_rr(AR724X_PLL_REG_CPU_CONFIG); ++ ++ div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); ++ freq = div * ar71xx_ref_freq; ++ ++ div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); ++ freq *= div; ++ ++ ar71xx_cpu_freq = freq; ++ ++ div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; ++ ar71xx_ddr_freq = freq / div; ++ ++ div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; ++ ar71xx_ahb_freq = ar71xx_cpu_freq / div; +} + -+static int __devinit rb750_led_probe(struct platform_device *pdev) ++static void __init ar933x_detect_sys_frequency(void) +{ -+ struct rb750_led_platform_data *pdata; -+ struct rb750_led_drvdata *drvdata; -+ int ret = 0; -+ int i; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) -+ return -EINVAL; ++ u32 clock_ctrl; ++ u32 cpu_config; ++ u32 freq; ++ u32 t; + -+ drvdata = kzalloc(sizeof(struct rb750_led_drvdata) + -+ sizeof(struct rb750_led_dev) * pdata->num_leds, -+ GFP_KERNEL); -+ if (!drvdata) -+ return -ENOMEM; ++ t = ar71xx_reset_rr(AR933X_RESET_REG_BOOTSTRAP); ++ if (t & AR933X_BOOTSTRAP_REF_CLK_40) ++ ar71xx_ref_freq = (40 * 1000 * 1000); ++ else ++ ar71xx_ref_freq = (25 * 1000 * 1000); + -+ drvdata->num_leds = pdata->num_leds; -+ drvdata->led_devs = (struct rb750_led_dev *) &drvdata[1]; ++ clock_ctrl = ar71xx_pll_rr(AR933X_PLL_CLOCK_CTRL_REG); ++ if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { ++ ar71xx_cpu_freq = ar71xx_ref_freq; ++ ar71xx_ahb_freq = ar71xx_ref_freq; ++ ar71xx_ddr_freq = ar71xx_ref_freq; ++ } else { ++ cpu_config = ar71xx_pll_rr(AR933X_PLL_CPU_CONFIG_REG); + -+ for (i = 0; i < drvdata->num_leds; i++) { -+ struct rb750_led_dev *rbled = &drvdata->led_devs[i]; -+ struct rb750_led_data *led_data = &pdata->leds[i]; ++ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & ++ AR933X_PLL_CPU_CONFIG_REFDIV_MASK; ++ freq = ar71xx_ref_freq / t; + -+ rbled->cdev.name = led_data->name; -+ rbled->cdev.default_trigger = led_data->default_trigger; -+ rbled->cdev.brightness_set = rb750_led_brightness_set; -+ rbled->cdev.brightness = LED_OFF; ++ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & ++ AR933X_PLL_CPU_CONFIG_NINT_MASK; ++ freq *= t; + -+ rbled->mask = led_data->mask; -+ rbled->active_low = !!led_data->active_low; ++ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & ++ AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; ++ if (t == 0) ++ t = 1; + -+ ret = led_classdev_register(&pdev->dev, &rbled->cdev); -+ if (ret) -+ goto err; -+ } ++ freq >>= t; + -+ platform_set_drvdata(pdev, drvdata); -+ return 0; ++ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & ++ AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; ++ ar71xx_cpu_freq = freq / t; + -+ err: -+ for (i = i - 1; i >= 0; i--) -+ led_classdev_unregister(&drvdata->led_devs[i].cdev); ++ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & ++ AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; ++ ar71xx_ddr_freq = freq / t; + -+ kfree(drvdata); -+ return ret; ++ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & ++ AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; ++ ar71xx_ahb_freq = freq / t; ++ } +} + -+static int __devexit rb750_led_remove(struct platform_device *pdev) ++static void __init detect_sys_frequency(void) +{ -+ struct rb750_led_drvdata *drvdata; -+ int i; ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ ar71xx_detect_sys_frequency(); ++ break; + -+ drvdata = platform_get_drvdata(pdev); -+ for (i = 0; i < drvdata->num_leds; i++) -+ led_classdev_unregister(&drvdata->led_devs[i].cdev); ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ ar724x_detect_sys_frequency(); ++ break; + -+ kfree(drvdata); -+ return 0; -+} ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ ar91xx_detect_sys_frequency(); ++ break; + -+static struct platform_driver rb750_led_driver = { -+ .probe = rb750_led_probe, -+ .remove = __devexit_p(rb750_led_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ ar933x_detect_sys_frequency(); ++ break; + -+MODULE_ALIAS("platform:leds-rb750"); ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ar934x_detect_sys_frequency(); ++ break; ++ default: ++ BUG(); ++ } ++} + -+static int __init rb750_led_init(void) ++const char *get_system_type(void) +{ -+ return platform_driver_register(&rb750_led_driver); ++ return ar71xx_sys_type; +} + -+static void __exit rb750_led_exit(void) ++unsigned int __cpuinit get_c0_compare_irq(void) +{ -+ platform_driver_unregister(&rb750_led_driver); ++ return CP0_LEGACY_COMPARE_IRQ; +} + -+module_init(rb750_led_init); -+module_exit(rb750_led_exit); ++void __init plat_mem_setup(void) ++{ ++ set_io_port_base(KSEG1); + -+MODULE_DESCRIPTION(DRV_NAME); -+MODULE_DESCRIPTION("LED driver for the RouterBOARD 750"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c linux-2.6.39/drivers/leds/leds-wndr3700-usb.c ---- linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/leds/leds-wndr3700-usb.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,75 @@ -+/* -+ * USB LED driver for the NETGEAR WNDR3700 -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ ar71xx_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, ++ AR71XX_DDR_CTRL_SIZE); + -+#include -+#include -+#include ++ ar71xx_pll_base = ioremap_nocache(AR71XX_PLL_BASE, ++ AR71XX_PLL_SIZE); + -+#include ++ ar71xx_reset_base = ioremap_nocache(AR71XX_RESET_BASE, ++ AR71XX_RESET_SIZE); + -+#define DRIVER_NAME "wndr3700-led-usb" ++ ar71xx_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); + -+static void wndr3700_usb_led_set(struct led_classdev *cdev, -+ enum led_brightness brightness) -+{ -+ if (brightness) -+ ar71xx_device_start(RESET_MODULE_GE1_PHY); -+ else -+ ar71xx_device_stop(RESET_MODULE_GE1_PHY); ++ ar71xx_usb_ctrl_base = ioremap_nocache(AR71XX_USB_CTRL_BASE, ++ AR71XX_USB_CTRL_SIZE); ++ ++ ar71xx_detect_mem_size(); ++ ar71xx_detect_sys_type(); ++ detect_sys_frequency(); ++ ++ pr_info("Clocks: CPU:%u.%03uMHz, DDR:%u.%03uMHz, AHB:%u.%03uMHz, " ++ "Ref:%u.%03uMHz", ++ ar71xx_cpu_freq / 1000000, (ar71xx_cpu_freq / 1000) % 1000, ++ ar71xx_ddr_freq / 1000000, (ar71xx_ddr_freq / 1000) % 1000, ++ ar71xx_ahb_freq / 1000000, (ar71xx_ahb_freq / 1000) % 1000, ++ ar71xx_ref_freq / 1000000, (ar71xx_ref_freq / 1000) % 1000); ++ ++ _machine_restart = ar71xx_restart; ++ _machine_halt = ar71xx_halt; ++ pm_power_off = ar71xx_halt; +} + -+static enum led_brightness wndr3700_usb_led_get(struct led_classdev *cdev) ++void __init plat_time_init(void) +{ -+ return ar71xx_device_stopped(RESET_MODULE_GE1_PHY) ? LED_OFF : LED_FULL; ++ mips_hpt_frequency = ar71xx_cpu_freq / 2; +} + -+static struct led_classdev wndr3700_usb_led = { -+ .name = "wndr3700:green:usb", -+ .brightness_set = wndr3700_usb_led_set, -+ .brightness_get = wndr3700_usb_led_get, -+}; ++__setup("board=", mips_machtype_setup); + -+static int __devinit wndr3700_usb_led_probe(struct platform_device *pdev) ++static int __init ar71xx_machine_setup(void) +{ -+ return led_classdev_register(&pdev->dev, &wndr3700_usb_led); -+} ++ ar71xx_gpio_init(); + -+static int __devexit wndr3700_usb_led_remove(struct platform_device *pdev) -+{ -+ led_classdev_unregister(&wndr3700_usb_led); ++ ar71xx_add_device_uart(); ++ ar71xx_add_device_wdt(); ++ ++ mips_machine_setup(); + return 0; +} + -+static struct platform_driver wndr3700_usb_led_driver = { -+ .probe = wndr3700_usb_led_probe, -+ .remove = __devexit_p(wndr3700_usb_led_remove), -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; ++arch_initcall(ar71xx_machine_setup); + -+static int __init wndr3700_usb_led_init(void) ++static void __init ar71xx_generic_init(void) +{ -+ return platform_driver_register(&wndr3700_usb_led_driver); ++ /* Nothing to do */ +} + -+static void __exit wndr3700_usb_led_exit(void) ++MIPS_MACHINE(AR71XX_MACH_GENERIC, "Generic", "Generic AR71xx board", ++ ar71xx_generic_init); +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/checksum.h linux-2.6.39/arch/mips/include/asm/checksum.h +--- linux-2.6.39.orig/arch/mips/include/asm/checksum.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/include/asm/checksum.h 2011-08-24 05:53:21.109231561 +0200 +@@ -12,6 +12,7 @@ + #define _ASM_CHECKSUM_H + + #include ++#include + + #include + +@@ -104,26 +105,30 @@ + const unsigned int *stop = word + ihl; + unsigned int csum; + int carry; ++ unsigned int w; + +- csum = word[0]; +- csum += word[1]; +- carry = (csum < word[1]); ++ csum = __get_unaligned_cpu32(word++); ++ ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; + +- csum += word[2]; +- carry = (csum < word[2]); ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; + +- csum += word[3]; +- carry = (csum < word[3]); ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; + +- word += 4; + do { +- csum += *word; +- carry = (csum < *word); ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; +- word++; + } while (word != stop); + + return csum_fold(csum); +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/fw/myloader/myloader.h linux-2.6.39/arch/mips/include/asm/fw/myloader/myloader.h +--- linux-2.6.39.orig/arch/mips/include/asm/fw/myloader/myloader.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/fw/myloader/myloader.h 2011-04-27 12:19:21.887662064 +0200 +@@ -0,0 +1,34 @@ ++/* ++ * Compex's MyLoader specific definitions ++ * ++ * Copyright (C) 2006-2008 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++ ++#ifndef _ASM_MIPS_FW_MYLOADER_H ++#define _ASM_MIPS_FW_MYLOADER_H ++ ++#include ++ ++struct myloader_info { ++ uint32_t vid; ++ uint32_t did; ++ uint32_t svid; ++ uint32_t sdid; ++ uint8_t macs[MYLO_ETHADDR_COUNT][6]; ++}; ++ ++#ifdef CONFIG_MYLOADER ++extern struct myloader_info *myloader_get_info(void) __init; ++#else ++static inline struct myloader_info *myloader_get_info(void) +{ -+ platform_driver_unregister(&wndr3700_usb_led_driver); ++ return NULL; +} ++#endif /* CONFIG_MYLOADER */ + -+module_init(wndr3700_usb_led_init); -+module_exit(wndr3700_usb_led_exit); -+ -+MODULE_DESCRIPTION("USB LED driver for the NETGEAR WNDR3700"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" DRIVER_NAME); -diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Kconfig linux-2.6.39/drivers/mtd/maps/Kconfig ---- linux-2.6.39.orig/drivers/mtd/maps/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/mtd/maps/Kconfig 2011-05-27 14:36:51.000000000 +0200 -@@ -260,6 +260,13 @@ - Support for parsing CFE image tag and creating MTD partitions on - Broadcom BCM63xx boards. - -+config MTD_AR91XX_FLASH -+ tristate "Atheros AR91xx parallel flash support" -+ depends on ATHEROS_AR71XX -+ select MTD_COMPLEX_MAPPINGS -+ help -+ Parallel flash driver for the Atheros AR91xx based boards. -+ - config MTD_DILNETPC - tristate "CFI Flash device mapped on DIL/Net PC" - depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN -diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Makefile linux-2.6.39/drivers/mtd/maps/Makefile ---- linux-2.6.39.orig/drivers/mtd/maps/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/mtd/maps/Makefile 2011-05-27 14:36:51.000000000 +0200 -@@ -7,6 +7,7 @@ - endif - - # Chip mappings -+obj-$(CONFIG_MTD_AR91XX_FLASH) += ar91xx_flash.o - obj-$(CONFIG_MTD_CDB89712) += cdb89712.o - obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o - obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o -diff -Nur linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c ---- linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,310 @@ ++#endif /* _ASM_MIPS_FW_MYLOADER_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h 2011-08-06 09:32:36.758018150 +0200 +@@ -0,0 +1,769 @@ +/* -+ * Parallel flash driver for the Atheros AR91xx SoC ++ * Atheros AR71xx SoC specific definitions + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. ++ * Parts of this file are based on Atheros 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.31 BSP + * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + */ + -+#include ++#ifndef __ASM_MACH_AR71XX_H ++#define __ASM_MACH_AR71XX_H ++ +#include -+#include +#include -+#include -+#include -+#include -+#include -+#include -+#include +#include ++#include + -+#include -+#include -+ -+#define DRV_NAME "ar91xx-flash" -+ -+struct ar91xx_flash_info { -+ struct mtd_info *mtd; -+ struct map_info map; -+#ifdef CONFIG_MTD_PARTITIONS -+ int nr_parts; -+ struct mtd_partition *parts; -+#endif -+}; ++#ifndef __ASSEMBLER__ + -+static map_word ar91xx_flash_read(struct map_info *map, unsigned long ofs) -+{ -+ map_word val; ++#define AR71XX_PCI_MEM_BASE 0x10000000 ++#define AR71XX_PCI_MEM_SIZE 0x08000000 ++#define AR71XX_APB_BASE 0x18000000 ++#define AR71XX_GE0_BASE 0x19000000 ++#define AR71XX_GE0_SIZE 0x01000000 ++#define AR71XX_GE1_BASE 0x1a000000 ++#define AR71XX_GE1_SIZE 0x01000000 ++#define AR71XX_EHCI_BASE 0x1b000000 ++#define AR71XX_EHCI_SIZE 0x01000000 ++#define AR71XX_OHCI_BASE 0x1c000000 ++#define AR71XX_OHCI_SIZE 0x01000000 ++#define AR7240_OHCI_BASE 0x1b000000 ++#define AR7240_OHCI_SIZE 0x01000000 ++#define AR71XX_SPI_BASE 0x1f000000 ++#define AR71XX_SPI_SIZE 0x01000000 + -+ if (map_bankwidth_is_1(map)) -+ val.x[0] = __raw_readb(map->virt + (ofs ^ 3)); -+ else if (map_bankwidth_is_2(map)) -+ val.x[0] = __raw_readw(map->virt + (ofs ^ 2)); -+ else -+ val = map_word_ff(map); ++#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000) ++#define AR71XX_DDR_CTRL_SIZE 0x10000 ++#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000) ++#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000) ++#define AR71XX_UART_SIZE 0x10000 ++#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) ++#define AR71XX_USB_CTRL_SIZE 0x10000 ++#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000) ++#define AR71XX_GPIO_SIZE 0x10000 ++#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000) ++#define AR71XX_PLL_SIZE 0x10000 ++#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) ++#define AR71XX_RESET_SIZE 0x10000 ++#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000) ++#define AR71XX_MII_SIZE 0x10000 ++#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000) ++#define AR71XX_SLIC_SIZE 0x10000 ++#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000) ++#define AR71XX_DMA_SIZE 0x10000 ++#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000) ++#define AR71XX_STEREO_SIZE 0x10000 + -+ return val; -+} ++#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000) ++#define AR724X_PCI_CRP_SIZE 0x100 + -+static void ar91xx_flash_write(struct map_info *map, map_word d, -+ unsigned long ofs) -+{ -+ if (map_bankwidth_is_1(map)) -+ __raw_writeb(d.x[0], map->virt + (ofs ^ 3)); -+ else if (map_bankwidth_is_2(map)) -+ __raw_writew(d.x[0], map->virt + (ofs ^ 2)); ++#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000) ++#define AR724X_PCI_CTRL_SIZE 0x100 + -+ mb(); -+} ++#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000) ++#define AR91XX_WMAC_SIZE 0x30000 + -+static map_word ar91xx_flash_read_lock(struct map_info *map, unsigned long ofs) -+{ -+ map_word ret; ++#define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000) ++#define AR933X_UART_SIZE 0x14 ++#define AR933X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) ++#define AR933X_WMAC_SIZE 0x20000 + -+ ar71xx_flash_acquire(); -+ ret = ar91xx_flash_read(map, ofs); -+ ar71xx_flash_release(); ++#define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) ++#define AR934X_WMAC_SIZE 0x20000 + -+ return ret; -+} ++#define AR71XX_MEM_SIZE_MIN 0x0200000 ++#define AR71XX_MEM_SIZE_MAX 0x10000000 + -+static void ar91xx_flash_write_lock(struct map_info *map, map_word d, -+ unsigned long ofs) -+{ -+ ar71xx_flash_acquire(); -+ ar91xx_flash_write(map, d, ofs); -+ ar71xx_flash_release(); -+} ++#define AR71XX_CPU_IRQ_BASE 0 ++#define AR71XX_MISC_IRQ_BASE 8 ++#define AR71XX_MISC_IRQ_COUNT 32 ++#define AR71XX_GPIO_IRQ_BASE 40 ++#define AR71XX_GPIO_IRQ_COUNT 32 ++#define AR71XX_PCI_IRQ_BASE 72 ++#define AR71XX_PCI_IRQ_COUNT 8 + -+static void ar91xx_flash_copy_from_lock(struct map_info *map, void *to, -+ unsigned long from, ssize_t len) -+{ -+ ar71xx_flash_acquire(); -+ inline_map_copy_from(map, to, from, len); -+ ar71xx_flash_release(); -+} ++#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2) ++#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3) ++#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4) ++#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5) ++#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6) ++#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7) + -+static void ar91xx_flash_copy_to_lock(struct map_info *map, unsigned long to, -+ const void *from, ssize_t len) -+{ -+ ar71xx_flash_acquire(); -+ inline_map_copy_to(map, to, from, len); -+ ar71xx_flash_release(); -+} ++#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0) ++#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1) ++#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2) ++#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3) ++#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4) ++#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5) ++#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6) ++#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7) ++#define AR71XX_MISC_IRQ_TIMER2 (AR71XX_MISC_IRQ_BASE + 8) ++#define AR71XX_MISC_IRQ_TIMER3 (AR71XX_MISC_IRQ_BASE + 9) ++#define AR71XX_MISC_IRQ_TIMER4 (AR71XX_MISC_IRQ_BASE + 10) ++#define AR71XX_MISC_IRQ_DDR_PERF (AR71XX_MISC_IRQ_BASE + 11) ++#define AR71XX_MISC_IRQ_ENET_LINK (AR71XX_MISC_IRQ_BASE + 12) + -+static int ar91xx_flash_remove(struct platform_device *pdev) -+{ -+ struct ar91xx_flash_platform_data *pdata; -+ struct ar91xx_flash_info *info; ++#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x)) + -+ info = platform_get_drvdata(pdev); -+ if (info == NULL) -+ return 0; ++#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0) ++#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1) ++#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2) ++#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4) + -+ platform_set_drvdata(pdev, NULL); ++extern u32 ar71xx_ahb_freq; ++extern u32 ar71xx_cpu_freq; ++extern u32 ar71xx_ddr_freq; ++extern u32 ar71xx_ref_freq; + -+ if (info->mtd == NULL) -+ return 0; ++enum ar71xx_soc_type { ++ AR71XX_SOC_UNKNOWN, ++ AR71XX_SOC_AR7130, ++ AR71XX_SOC_AR7141, ++ AR71XX_SOC_AR7161, ++ AR71XX_SOC_AR7240, ++ AR71XX_SOC_AR7241, ++ AR71XX_SOC_AR7242, ++ AR71XX_SOC_AR9130, ++ AR71XX_SOC_AR9132, ++ AR71XX_SOC_AR9330, ++ AR71XX_SOC_AR9331, ++ AR71XX_SOC_AR9341, ++ AR71XX_SOC_AR9342, ++ AR71XX_SOC_AR9344, ++}; ++extern u32 ar71xx_soc_rev; + -+ pdata = pdev->dev.platform_data; -+#ifdef CONFIG_MTD_PARTITIONS -+ if (info->nr_parts) { -+ del_mtd_partitions(info->mtd); -+ kfree(info->parts); -+ } else if (pdata->nr_parts) { -+ del_mtd_partitions(info->mtd); -+ } else { -+ del_mtd_device(info->mtd); -+ } -+#else -+ del_mtd_device(info->mtd); -+#endif -+ map_destroy(info->mtd); ++extern enum ar71xx_soc_type ar71xx_soc; + -+ return 0; -+} ++/* ++ * PLL block ++ */ ++#define AR71XX_PLL_REG_CPU_CONFIG 0x00 ++#define AR71XX_PLL_REG_SEC_CONFIG 0x04 ++#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 ++#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 + -+static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; -+#ifdef CONFIG_MTD_PARTITIONS -+static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; -+#endif ++#define AR71XX_PLL_DIV_SHIFT 3 ++#define AR71XX_PLL_DIV_MASK 0x1f ++#define AR71XX_CPU_DIV_SHIFT 16 ++#define AR71XX_CPU_DIV_MASK 0x3 ++#define AR71XX_DDR_DIV_SHIFT 18 ++#define AR71XX_DDR_DIV_MASK 0x3 ++#define AR71XX_AHB_DIV_SHIFT 20 ++#define AR71XX_AHB_DIV_MASK 0x7 + -+static int ar91xx_flash_probe(struct platform_device *pdev) -+{ -+ struct ar91xx_flash_platform_data *pdata; -+ struct ar91xx_flash_info *info; -+ struct resource *res; -+ struct resource *region; -+ const char **probe_type; -+ int err = 0; ++#define AR71XX_ETH0_PLL_SHIFT 17 ++#define AR71XX_ETH1_PLL_SHIFT 19 + -+ pdata = pdev->dev.platform_data; -+ if (pdata == NULL) -+ return -EINVAL; ++#define AR724X_PLL_REG_CPU_CONFIG 0x00 ++#define AR724X_PLL_REG_PCIE_CONFIG 0x18 + -+ info = devm_kzalloc(&pdev->dev, sizeof(struct ar91xx_flash_info), -+ GFP_KERNEL); -+ if (info == NULL) { -+ err = -ENOMEM; -+ goto err_out; -+ } ++#define AR724X_PLL_DIV_SHIFT 0 ++#define AR724X_PLL_DIV_MASK 0x3ff ++#define AR724X_PLL_REF_DIV_SHIFT 10 ++#define AR724X_PLL_REF_DIV_MASK 0xf ++#define AR724X_AHB_DIV_SHIFT 19 ++#define AR724X_AHB_DIV_MASK 0x1 ++#define AR724X_DDR_DIV_SHIFT 22 ++#define AR724X_DDR_DIV_MASK 0x3 + -+ platform_set_drvdata(pdev, info); ++#define AR7242_PLL_REG_ETH0_INT_CLOCK 0x2c + -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (res == NULL) { -+ err = -ENOENT; -+ goto err_out; -+ } ++#define AR91XX_PLL_REG_CPU_CONFIG 0x00 ++#define AR91XX_PLL_REG_ETH_CONFIG 0x04 ++#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14 ++#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18 + -+ dev_info(&pdev->dev, "%.8llx at %.8llx\n", -+ (unsigned long long)(res->end - res->start + 1), -+ (unsigned long long)res->start); ++#define AR91XX_PLL_DIV_SHIFT 0 ++#define AR91XX_PLL_DIV_MASK 0x3ff ++#define AR91XX_DDR_DIV_SHIFT 22 ++#define AR91XX_DDR_DIV_MASK 0x3 ++#define AR91XX_AHB_DIV_SHIFT 19 ++#define AR91XX_AHB_DIV_MASK 0x1 + -+ region = devm_request_mem_region(&pdev->dev, -+ res->start, res->end - res->start + 1, -+ dev_name(&pdev->dev)); -+ if (region == NULL) { -+ dev_err(&pdev->dev, "could not reserve memory region\n"); -+ err = -ENOMEM; -+ goto err_out; -+ } ++#define AR91XX_ETH0_PLL_SHIFT 20 ++#define AR91XX_ETH1_PLL_SHIFT 22 + -+ info->map.name = dev_name(&pdev->dev); -+ info->map.phys = res->start; -+ info->map.size = res->end - res->start + 1; -+ info->map.bankwidth = pdata->width; ++#define AR933X_PLL_CPU_CONFIG_REG 0x00 ++#define AR933X_PLL_CLOCK_CTRL_REG 0x08 + -+ info->map.virt = devm_ioremap(&pdev->dev, info->map.phys, -+ info->map.size); -+ if (info->map.virt == NULL) { -+ dev_err(&pdev->dev, "failed to ioremap flash region\n"); -+ err = -EIO; -+ goto err_out; -+ } ++#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT 10 ++#define AR933X_PLL_CPU_CONFIG_NINT_MASK 0x3f ++#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT 16 ++#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f ++#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT 23 ++#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7 + -+ simple_map_init(&info->map); -+ if (pdata->is_shared) { -+ info->map.read = ar91xx_flash_read_lock; -+ info->map.write = ar91xx_flash_write_lock; -+ info->map.copy_from = ar91xx_flash_copy_from_lock; -+ info->map.copy_to = ar91xx_flash_copy_to_lock; -+ } else { -+ info->map.read = ar91xx_flash_read; -+ info->map.write = ar91xx_flash_write; -+ } ++#define AR933X_PLL_CLOCK_CTRL_BYPASS BIT(2) ++#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT 5 ++#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK 0x3 ++#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT 10 ++#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK 0x3 ++#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15 ++#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7 + -+ probe_type = rom_probe_types; -+ for (; info->mtd == NULL && *probe_type != NULL; probe_type++) -+ info->mtd = do_map_probe(*probe_type, &info->map); ++#define AR934X_PLL_REG_CPU_CONFIG 0x00 ++#define AR934X_PLL_REG_DDR_CTRL_CLOCK 0x8 + -+ if (info->mtd == NULL) { -+ dev_err(&pdev->dev, "map_probe failed\n"); -+ err = -ENXIO; -+ goto err_out; -+ } ++#define AR934X_CPU_PLL_CFG_OUTDIV_MSB 21 ++#define AR934X_CPU_PLL_CFG_OUTDIV_LSB 19 ++#define AR934X_CPU_PLL_CFG_OUTDIV_MASK 0x00380000 + -+ info->mtd->owner = THIS_MODULE; ++#define AR934X_CPU_PLL_CFG_OUTDIV_GET(x) \ ++ (((x) & AR934X_CPU_PLL_CFG_OUTDIV_MASK) >> \ ++ AR934X_CPU_PLL_CFG_OUTDIV_LSB) + -+#ifdef CONFIG_MTD_PARTITIONS -+ if (pdata->nr_parts) { -+ dev_info(&pdev->dev, "using static partition mapping\n"); -+ add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); -+ return 0; -+ } ++#define AR934X_DDR_PLL_CFG_OUTDIV_MSB 25 ++#define AR934X_DDR_PLL_CFG_OUTDIV_LSB 23 ++#define AR934X_DDR_PLL_CFG_OUTDIV_MASK 0x03800000 + -+ err = parse_mtd_partitions(info->mtd, part_probe_types, -+ &info->parts, 0); -+ if (err > 0) { -+ add_mtd_partitions(info->mtd, info->parts, err); -+ return 0; -+ } -+#endif ++#define AR934X_DDR_PLL_CFG_OUTDIV_GET(x) \ ++ (((x) & AR934X_DDR_PLL_CFG_OUTDIV_MASK) >> \ ++ AR934X_DDR_PLL_CFG_OUTDIV_LSB) + -+ add_mtd_device(info->mtd); -+ return 0; ++#define AR934X_DDR_PLL_CFG_OUTDIV_SET(x) \ ++ (((x) << AR934X_DDR_PLL_CFG_OUTDIV_LSB) & \ ++ AR934X_DDR_PLL_CFG_OUTDIV_MASK) + -+ err_out: -+ ar91xx_flash_remove(pdev); -+ return err; -+} ++#define AR934X_CPU_PLL_CFG_REFDIV_MSB 16 ++#define AR934X_CPU_PLL_CFG_REFDIV_LSB 12 ++#define AR934X_CPU_PLL_CFG_REFDIV_MASK 0x0001f000 + -+#ifdef CONFIG_PM -+static int ar91xx_flash_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ struct ar91xx_flash_info *info = platform_get_drvdata(dev); -+ int ret = 0; ++#define AR934X_CPU_PLL_CFG_REFDIV_GET(x) \ ++ (((x) & AR934X_CPU_PLL_CFG_REFDIV_MASK) >> \ ++ AR934X_CPU_PLL_CFG_REFDIV_LSB) + -+ if (info->mtd->suspend) -+ ret = info->mtd->suspend(info->mtd); ++#define AR934X_CPU_PLL_CFG_REFDIV_SET(x) \ ++ (((x) << AR934X_CPU_PLL_CFG_REFDIV_LSB) & \ ++ AR934X_CPU_PLL_CFG_REFDIV_MASK) + -+ if (ret) -+ goto fail; ++#define AR934X_CPU_PLL_CFG_REFDIV_RESET 2 + -+ return 0; ++#define AR934X_CPU_PLL_CFG_NINT_MSB 11 ++#define AR934X_CPU_PLL_CFG_NINT_LSB 6 ++#define AR934X_CPU_PLL_CFG_NINT_MASK 0x00000fc0 + -+ fail: -+ if (info->mtd->suspend) { -+ BUG_ON(!info->mtd->resume); -+ info->mtd->resume(info->mtd); -+ } ++#define AR934X_CPU_PLL_CFG_NINT_GET(x) \ ++ (((x) & AR934X_CPU_PLL_CFG_NINT_MASK) >> \ ++ AR934X_CPU_PLL_CFG_NINT_LSB) + -+ return ret; -+} ++#define AR934X_CPU_PLL_CFG_NINT_SET(x) \ ++ (((x) << AR934X_CPU_PLL_CFG_NINT_LSB) & \ ++ AR934X_CPU_PLL_CFG_NINT_MASK) + -+static int ar91xx_flash_resume(struct platform_device *pdev) -+{ -+ struct ar91xx_flash_info *info = platform_get_drvdata(pdev); ++#define AR934X_CPU_PLL_CFG_NINT_RESET 20 + -+ if (info->mtd->resume) -+ info->mtd->resume(info->mtd); ++#define AR934X_CPU_PLL_CFG_NFRAC_MSB 5 ++#define AR934X_CPU_PLL_CFG_NFRAC_LSB 0 ++#define AR934X_CPU_PLL_CFG_NFRAC_MASK 0x0000003f + -+ return 0; -+} ++#define AR934X_CPU_PLL_CFG_NFRAC_GET(x) \ ++ (((x) & AR934X_CPU_PLL_CFG_NFRAC_MASK) >> \ ++ AR934X_CPU_PLL_CFG_NFRAC_LSB) + -+static void ar91xx_flash_shutdown(struct platform_device *pdev) -+{ -+ struct ar91xx_flash_info *info = platform_get_drvdata(pdev); ++#define AR934X_CPU_PLL_CFG_NFRAC_SET(x) \ ++ (((x) << AR934X_CPU_PLL_CFG_NFRAC_LSB) & \ ++ AR934X_CPU_PLL_CFG_NFRAC_MASK) + -+ if (info->mtd->suspend && info->mtd->resume) -+ if (info->mtd->suspend(info->mtd) == 0) -+ info->mtd->resume(info->mtd); -+} -+#else -+#define ar91xx_flash_suspend NULL -+#define ar91xx_flash_resume NULL -+#define ar91xx_flash_shutdown NULL -+#endif ++#define AR934X_DDR_PLL_CFG_REFDIV_MSB 20 ++#define AR934X_DDR_PLL_CFG_REFDIV_LSB 16 ++#define AR934X_DDR_PLL_CFG_REFDIV_MASK 0x001f0000 + -+static struct platform_driver ar91xx_flash_driver = { -+ .probe = ar91xx_flash_probe, -+ .remove = ar91xx_flash_remove, -+ .suspend = ar91xx_flash_suspend, -+ .resume = ar91xx_flash_resume, -+ .shutdown = ar91xx_flash_shutdown, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; ++#define AR934X_DDR_PLL_CFG_REFDIV_GET(x) \ ++ (((x) & AR934X_DDR_PLL_CFG_REFDIV_MASK) >> \ ++ AR934X_DDR_PLL_CFG_REFDIV_LSB) + -+static int __init ar91xx_flash_init(void) -+{ -+ return platform_driver_register(&ar91xx_flash_driver); -+} ++#define AR934X_DDR_PLL_CFG_REFDIV_SET(x) \ ++ (((x) << AR934X_DDR_PLL_CFG_REFDIV_LSB) & \ ++ AR934X_DDR_PLL_CFG_REFDIV_MASK) + -+static void __exit ar91xx_flash_exit(void) -+{ -+ platform_driver_unregister(&ar91xx_flash_driver); -+} ++#define AR934X_DDR_PLL_CFG_REFDIV_RESET 2 + -+module_init(ar91xx_flash_init); -+module_exit(ar91xx_flash_exit); ++#define AR934X_DDR_PLL_CFG_NINT_MSB 15 ++#define AR934X_DDR_PLL_CFG_NINT_LSB 10 ++#define AR934X_DDR_PLL_CFG_NINT_MASK 0x0000fc00 + -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_DESCRIPTION("Parallel flash driver for the Atheros AR91xx SoC"); -+MODULE_ALIAS("platform:" DRV_NAME); -diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Kconfig linux-2.6.39/drivers/mtd/nand/Kconfig ---- linux-2.6.39.orig/drivers/mtd/nand/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/mtd/nand/Kconfig 2011-05-27 14:36:51.000000000 +0200 -@@ -531,4 +531,8 @@ - Enables support for NAND Flash chips on the ST Microelectronics - Flexible Static Memory Controller (FSMC) - -+config MTD_NAND_RB4XX -+ tristate "NAND flash driver for RouterBoard 4xx series" -+ depends on MTD_NAND && AR71XX_MACH_RB4XX ++#define AR934X_DDR_PLL_CFG_NINT_GET(x) \ ++ (((x) & AR934X_DDR_PLL_CFG_NINT_MASK) >> \ ++ AR934X_DDR_PLL_CFG_NINT_LSB) + - endif # MTD_NAND -diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Makefile linux-2.6.39/drivers/mtd/nand/Makefile ---- linux-2.6.39.orig/drivers/mtd/nand/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/mtd/nand/Makefile 2011-05-27 14:36:51.000000000 +0200 -@@ -34,6 +34,7 @@ - obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o - obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o - obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o -+obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o - obj-$(CONFIG_MTD_ALAUDA) += alauda.o - obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o - obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o -diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c ---- linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,513 @@ -+/* -+ * NAND flash driver for the MikroTik RouterBoard 4xx series -+ * -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This file was based on the driver for Linux 2.6.22 published by -+ * MikroTik for their RouterBoard 4xx series devices. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++#define AR934X_DDR_PLL_CFG_NINT_SET(x) \ ++ (((x) << AR934X_DDR_PLL_CFG_NINT_LSB) & \ ++ AR934X_DDR_PLL_CFG_NINT_MASK) + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#define AR934X_DDR_PLL_CFG_NINT_RESET 20 + -+#include ++#define AR934X_DDR_PLL_CFG_NFRAC_MSB 9 ++#define AR934X_DDR_PLL_CFG_NFRAC_LSB 0 ++#define AR934X_DDR_PLL_CFG_NFRAC_MASK 0x000003ff + -+#define DRV_NAME "rb4xx-nand" -+#define DRV_VERSION "0.1.10" -+#define DRV_DESC "NAND flash driver for RouterBoard 4xx series" ++#define AR934X_DDR_PLL_CFG_NFRAC_GET(x) \ ++ (((x) & AR934X_DDR_PLL_CFG_NFRAC_MASK) >> \ ++ AR934X_DDR_PLL_CFG_NFRAC_LSB) + -+#define USE_FAST_READ 1 -+#define USE_FAST_WRITE 1 -+#undef RB4XX_NAND_DEBUG ++#define AR934X_DDR_PLL_CFG_NFRAC_SET(x) \ ++ (((x) << AR934X_DDR_PLL_CFG_NFRAC_LSB) & \ ++ AR934X_DDR_PLL_CFG_NFRAC_MASK) + -+#ifdef RB4XX_NAND_DEBUG -+#define DBG(fmt, arg...) printk(KERN_DEBUG DRV_NAME ": " fmt, ## arg) -+#else -+#define DBG(fmt, arg...) do {} while (0) -+#endif ++#define AR934X_DDR_PLL_CFG_NFRAC_RESET 512 + -+#define RB4XX_NAND_GPIO_RDY 5 -+#define RB4XX_FLASH_HZ 33333334 -+#define RB4XX_NAND_HZ 33333334 ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MSB 19 ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB 15 ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x000f8000 + -+#define SPI_CTRL_FASTEST 0x40 -+#define SPI_CTRL_SAFE 0x43 /* 25 MHz for AHB 200 MHz */ -+#define SBIT_IOC_BASE SPI_IOC_CS1 -+#define SBIT_IOC_DO_SHIFT 0 -+#define SBIT_IOC_DO (1u << SBIT_IOC_DO_SHIFT) -+#define SBIT_IOC_DO2_SHIFT 18 -+#define SBIT_IOC_DO2 (1u << SBIT_IOC_DO2_SHIFT) -+ -+#define CPLD_CMD_WRITE_MULT 0x08 /* send cmd, n x send data, read data */ -+#define CPLD_CMD_WRITE_CFG 0x09 /* send cmd, n x send cfg */ -+#define CPLD_CMD_READ_MULT 0x0a /* send cmd, send idle, n x read data */ -+#define CPLD_CMD_READ_FAST 0x0b /* send cmd, 4 x idle, n x read data */ -+ -+#define CFG_BIT_nCE 0x80 -+#define CFG_BIT_CLE 0x40 -+#define CFG_BIT_ALE 0x20 -+#define CFG_BIT_FAN 0x10 -+#define CFG_BIT_nLED4 0x08 -+#define CFG_BIT_nLED3 0x04 -+#define CFG_BIT_nLED2 0x02 -+#define CFG_BIT_nLED1 0x01 -+ -+#define CFG_BIT_nLEDS \ -+ (CFG_BIT_nLED1 | CFG_BIT_nLED2 | CFG_BIT_nLED3 | CFG_BIT_nLED4) ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_GET(x) \ ++ (((x) & AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK) >> \ ++ AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB) + -+struct rb4xx_nand_info { -+ struct nand_chip chip; -+ struct mtd_info mtd; -+}; ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SET(x) \ ++ (((x) << AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB) & \ ++ AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK) + -+/* -+ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader -+ * will not be able to find the kernel that we load. -+ */ -+static struct nand_ecclayout rb4xx_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_RESET 0 + -+static struct mtd_partition rb4xx_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, -+ { -+ .name = "rootfs", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = (1024*1024*64) - (1024*256) - (4 * 1024 * 1024) -+ }, -+ { -+ .name = "cfgfs", -+ .offset = (1024*1024*64) - (1024*256), -+ .size = (1024*256), -+ }, -+}; ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MSB 14 ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB 10 ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x00007c00 + -+#if USE_FAST_READ -+#define SPI_NDATA_BASE 0x00800000 -+static unsigned spi_ctrl_fread = SPI_CTRL_SAFE; -+static unsigned spi_ctrl_flash = SPI_CTRL_SAFE; -+extern unsigned mips_hpt_frequency; -+#endif ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_GET(x) \ ++ (((x) & AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK) >> \ ++ AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB) + -+static inline unsigned rb4xx_spi_rreg(unsigned r) -+{ -+ return __raw_readl((void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r)); -+} ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SET(x) \ ++ (((x) << AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB) & \ ++ AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK) + -+static inline void rb4xx_spi_wreg(unsigned r, unsigned v) -+{ -+ __raw_writel(v, (void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r)); -+} ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_RESET 0 + -+static inline void do_spi_clk(int bit) -+{ -+ unsigned bval = SBIT_IOC_BASE | (bit & 1); ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MSB 9 ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB 5 ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x000003e0 + -+ rb4xx_spi_wreg(SPI_REG_IOC, bval); -+ rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK); -+} ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_GET(x) \ ++ (((x) & AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK) >> \ ++ AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB) + -+static void do_spi_byte(uint8_t byte) -+{ -+ do_spi_clk(byte >> 7); -+ do_spi_clk(byte >> 6); -+ do_spi_clk(byte >> 5); -+ do_spi_clk(byte >> 4); -+ do_spi_clk(byte >> 3); -+ do_spi_clk(byte >> 2); -+ do_spi_clk(byte >> 1); -+ do_spi_clk(byte); ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SET(x) \ ++ (((x) << AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB) & \ ++ AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK) + -+ DBG("spi_byte sent 0x%02x got 0x%x\n", -+ byte, rb4xx_spi_rreg(SPI_REG_RDS)); -+} ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_RESET 0 + -+#if USE_FAST_WRITE -+static inline void do_spi_clk_fast(int bit1, int bit2) -+{ -+ unsigned bval = (SBIT_IOC_BASE | -+ ((bit1 << SBIT_IOC_DO_SHIFT) & SBIT_IOC_DO) | -+ ((bit2 << SBIT_IOC_DO2_SHIFT) & SBIT_IOC_DO2)); ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MSB 24 ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB 24 ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK 0x01000000 + -+ rb4xx_spi_wreg(SPI_REG_IOC, bval); -+ rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK); -+} ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_GET(x) \ ++ (((x) & AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK) >> \ ++ AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB) + -+static inline void do_spi_byte_fast(uint8_t byte) -+{ -+ do_spi_clk_fast(byte >> 7, byte >> 6); -+ do_spi_clk_fast(byte >> 5, byte >> 4); -+ do_spi_clk_fast(byte >> 3, byte >> 2); -+ do_spi_clk_fast(byte >> 1, byte >> 0); ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_SET(x) \ ++ (((x) << AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB) & \ ++ AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK) + -+ DBG("spi_byte_fast sent 0x%02x got 0x%x\n", -+ byte, rb4xx_spi_rreg(SPI_REG_RDS)); -+} -+#else -+static inline void do_spi_byte_fast(uint8_t byte) ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_RESET 1 ++ ++extern void __iomem *ar71xx_pll_base; ++ ++static inline void ar71xx_pll_wr(unsigned reg, u32 val) +{ -+ do_spi_byte(byte); ++ __raw_writel(val, ar71xx_pll_base + reg); +} -+#endif /* USE_FAST_WRITE */ + -+static int do_spi_cmd(unsigned cmd, unsigned sendCnt, const uint8_t *sendData, -+ unsigned recvCnt, uint8_t *recvData, -+ const uint8_t *verifyData, int fastWrite) ++static inline u32 ar71xx_pll_rr(unsigned reg) +{ -+ unsigned i; -+ -+ DBG("SPI cmd 0x%x send %u recv %u\n", cmd, sendCnt, recvCnt); -+ -+ rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO); -+ rb4xx_spi_wreg(SPI_REG_CTRL, SPI_CTRL_FASTEST); ++ return __raw_readl(ar71xx_pll_base + reg); ++} + -+ do_spi_byte(cmd); -+#if 0 -+ if (cmd == CPLD_CMD_READ_FAST) { -+ do_spi_byte(0x80); -+ do_spi_byte(0); -+ do_spi_byte(0); -+ } -+#endif -+ for (i = 0; i < sendCnt; ++i) { -+ if (fastWrite) -+ do_spi_byte_fast(sendData[i]); -+ else -+ do_spi_byte(sendData[i]); -+ } -+ -+ for (i = 0; i < recvCnt; ++i) { -+ if (fastWrite) -+ do_spi_byte_fast(0); -+ else -+ do_spi_byte(0); -+ -+ if (recvData) { -+ recvData[i] = rb4xx_spi_rreg(SPI_REG_RDS) & 0xff; -+ } else if (verifyData) { -+ if (verifyData[i] != (rb4xx_spi_rreg(SPI_REG_RDS) -+ & 0xff)) -+ break; -+ } -+ } -+ -+ rb4xx_spi_wreg(SPI_REG_IOC, SBIT_IOC_BASE | SPI_IOC_CS0); -+ rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_flash); -+ rb4xx_spi_wreg(SPI_REG_FS, 0); -+ -+ return i == recvCnt; -+} ++/* ++ * USB_CONFIG block ++ */ ++#define USB_CTRL_REG_FLADJ 0x00 ++#define USB_CTRL_REG_CONFIG 0x04 + -+static int got_write = 1; ++extern void __iomem *ar71xx_usb_ctrl_base; + -+static void rb4xx_nand_write_data(const uint8_t *byte, unsigned cnt) ++static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val) +{ -+ do_spi_cmd(CPLD_CMD_WRITE_MULT, cnt, byte, 1, NULL, NULL, 1); -+ got_write = 1; ++ __raw_writel(val, ar71xx_usb_ctrl_base + reg); +} + -+static void rb4xx_nand_write_byte(uint8_t byte) ++static inline u32 ar71xx_usb_ctrl_rr(unsigned reg) +{ -+ rb4xx_nand_write_data(&byte, 1); ++ return __raw_readl(ar71xx_usb_ctrl_base + reg); +} + -+#if USE_FAST_READ -+static uint8_t *rb4xx_nand_read_getaddr(unsigned cnt) -+{ -+ static unsigned nboffset = 0x100000; -+ unsigned addr; ++/* ++ * GPIO block ++ */ ++#define GPIO_REG_OE 0x00 ++#define GPIO_REG_IN 0x04 ++#define GPIO_REG_OUT 0x08 ++#define GPIO_REG_SET 0x0c ++#define GPIO_REG_CLEAR 0x10 ++#define GPIO_REG_INT_MODE 0x14 ++#define GPIO_REG_INT_TYPE 0x18 ++#define GPIO_REG_INT_POLARITY 0x1c ++#define GPIO_REG_INT_PENDING 0x20 ++#define GPIO_REG_INT_ENABLE 0x24 ++#define GPIO_REG_FUNC 0x28 + -+ if (got_write) { -+ nboffset = (nboffset + 31) & ~31; -+ if (nboffset >= 0x100000) /* 1MB */ -+ nboffset = 0; ++#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17) ++#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16) ++#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13) ++#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12) ++#define AR71XX_GPIO_FUNC_UART_EN BIT(8) ++#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4) ++#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0) + -+ got_write = 0; -+ rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO); -+ rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_fread); -+ rb4xx_spi_wreg(SPI_REG_FS, 0); -+ } ++#define AR71XX_GPIO_COUNT 16 + -+ addr = KSEG1ADDR(AR71XX_SPI_BASE + SPI_NDATA_BASE) + nboffset; -+ DBG("rb4xx_nand_read_getaddr 0x%x cnt 0x%x\n", addr, cnt); ++#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19) ++#define AR724X_GPIO_FUNC_SPI_EN BIT(18) ++#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14) ++#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13) ++#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12) ++#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11) ++#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10) ++#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9) ++#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) ++#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) ++#define AR724X_GPIO_FUNC_UART_EN BIT(1) ++#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0) + -+ nboffset += cnt; -+ return (uint8_t *)addr; -+} ++#define AR724X_GPIO_COUNT 18 + -+static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt) -+{ -+ unsigned size32 = cnt & ~31; -+ unsigned remain = cnt & 31; ++#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22) ++#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21) ++#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20) ++#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19) ++#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18) ++#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17) ++#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16) ++#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9) ++#define AR91XX_GPIO_FUNC_UART_EN BIT(8) ++#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4) + -+ if (size32) { -+ uint8_t *addr = rb4xx_nand_read_getaddr(size32); -+ memcpy(buf, (void *)addr, size32); -+ } ++#define AR91XX_GPIO_COUNT 22 + -+ if (remain) { -+ do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain, -+ buf + size32, NULL, 0); -+ } -+} ++#define AR933X_GPIO_COUNT 30 + -+static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt) -+{ -+ unsigned size32 = cnt & ~31; -+ unsigned remain = cnt & 31; ++#define AR934X_GPIO_FUNC_SPI_CS_1_EN BIT(14) ++#define AR934X_GPIO_FUNC_SPI_CS_0_EN BIT(13) + -+ if (size32) { -+ uint8_t *addr = rb4xx_nand_read_getaddr(size32); -+ if (memcmp(buf, (void *)addr, size32) != 0) -+ return 0; -+ } ++#define AR934X_GPIO_COUNT 32 ++#define AR934X_GPIO_FUNC_DDR_DQOE_EN BIT(17) + -+ if (remain) { -+ return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain, -+ NULL, buf + size32, 0); -+ } -+ return 1; -+} -+#else /* USE_FAST_READ */ -+static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt) -+{ -+ do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, buf, NULL, 0); -+} ++extern void __iomem *ar71xx_gpio_base; + -+static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt) ++static inline void ar71xx_gpio_wr(unsigned reg, u32 value) +{ -+ return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, NULL, buf, 0); ++ __raw_writel(value, ar71xx_gpio_base + reg); +} -+#endif /* USE_FAST_READ */ + -+static void rb4xx_nand_write_cfg(uint8_t byte) ++static inline u32 ar71xx_gpio_rr(unsigned reg) +{ -+ do_spi_cmd(CPLD_CMD_WRITE_CFG, 1, &byte, 0, NULL, NULL, 0); -+ got_write = 1; ++ return __raw_readl(ar71xx_gpio_base + reg); +} + -+static int rb4xx_nand_dev_ready(struct mtd_info *mtd) -+{ -+ return gpio_get_value(RB4XX_NAND_GPIO_RDY); -+} ++void ar71xx_gpio_init(void) __init; ++void ar71xx_gpio_function_enable(u32 mask); ++void ar71xx_gpio_function_disable(u32 mask); ++void ar71xx_gpio_function_setup(u32 set, u32 clear); + -+static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ uint8_t cfg = CFG_BIT_nLEDS; ++/* ++ * DDR_CTRL block ++ */ ++#define AR71XX_DDR_REG_PCI_WIN0 0x7c ++#define AR71XX_DDR_REG_PCI_WIN1 0x80 ++#define AR71XX_DDR_REG_PCI_WIN2 0x84 ++#define AR71XX_DDR_REG_PCI_WIN3 0x88 ++#define AR71XX_DDR_REG_PCI_WIN4 0x8c ++#define AR71XX_DDR_REG_PCI_WIN5 0x90 ++#define AR71XX_DDR_REG_PCI_WIN6 0x94 ++#define AR71XX_DDR_REG_PCI_WIN7 0x98 ++#define AR71XX_DDR_REG_FLUSH_GE0 0x9c ++#define AR71XX_DDR_REG_FLUSH_GE1 0xa0 ++#define AR71XX_DDR_REG_FLUSH_USB 0xa4 ++#define AR71XX_DDR_REG_FLUSH_PCI 0xa8 + -+ cfg |= (ctrl & NAND_CLE) ? CFG_BIT_CLE : 0; -+ cfg |= (ctrl & NAND_ALE) ? CFG_BIT_ALE : 0; -+ cfg |= (ctrl & NAND_NCE) ? 0 : CFG_BIT_nCE; ++#define AR724X_DDR_REG_FLUSH_GE0 0x7c ++#define AR724X_DDR_REG_FLUSH_GE1 0x80 ++#define AR724X_DDR_REG_FLUSH_USB 0x84 ++#define AR724X_DDR_REG_FLUSH_PCIE 0x88 + -+ rb4xx_nand_write_cfg(cfg); -+ } ++#define AR91XX_DDR_REG_FLUSH_GE0 0x7c ++#define AR91XX_DDR_REG_FLUSH_GE1 0x80 ++#define AR91XX_DDR_REG_FLUSH_USB 0x84 ++#define AR91XX_DDR_REG_FLUSH_WMAC 0x88 + -+ if (cmd != NAND_CMD_NONE) -+ rb4xx_nand_write_byte(cmd); -+} ++#define AR933X_DDR_REG_FLUSH_GE0 0x7c ++#define AR933X_DDR_REG_FLUSH_GE1 0x80 ++#define AR933X_DDR_REG_FLUSH_USB 0x84 ++#define AR933X_DDR_REG_FLUSH_WMAC 0x88 + -+static uint8_t rb4xx_nand_read_byte(struct mtd_info *mtd) -+{ -+ uint8_t byte = 0; ++#define AR934X_DDR_REG_FLUSH_GE0 0x9c ++#define AR934X_DDR_REG_FLUSH_GE1 0xa0 ++#define AR934X_DDR_REG_FLUSH_USB 0xa4 ++#define AR934X_DDR_REG_FLUSH_PCIE 0xa8 + -+ rb4xx_nand_read_data(&byte, 1); -+ return byte; -+} + -+static void rb4xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, -+ int len) -+{ -+ rb4xx_nand_write_data(buf, len); -+} ++#define PCI_WIN0_OFFS 0x10000000 ++#define PCI_WIN1_OFFS 0x11000000 ++#define PCI_WIN2_OFFS 0x12000000 ++#define PCI_WIN3_OFFS 0x13000000 ++#define PCI_WIN4_OFFS 0x14000000 ++#define PCI_WIN5_OFFS 0x15000000 ++#define PCI_WIN6_OFFS 0x16000000 ++#define PCI_WIN7_OFFS 0x07000000 + -+static void rb4xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, -+ int len) ++extern void __iomem *ar71xx_ddr_base; ++ ++static inline void ar71xx_ddr_wr(unsigned reg, u32 val) +{ -+ rb4xx_nand_read_data(buf, len); ++ __raw_writel(val, ar71xx_ddr_base + reg); +} + -+static int rb4xx_nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, -+ int len) ++static inline u32 ar71xx_ddr_rr(unsigned reg) +{ -+ if (!rb4xx_nand_verify_data(buf, len)) -+ return -EFAULT; -+ -+ return 0; ++ return __raw_readl(ar71xx_ddr_base + reg); +} + -+static unsigned get_spi_ctrl(unsigned hz_max, const char *name) -+{ -+ unsigned div; ++void ar71xx_ddr_flush(u32 reg); + -+ div = (ar71xx_ahb_freq - 1) / (2 * hz_max); -+ /* -+ * CPU has a bug at (div == 0) - first bit read is random -+ */ -+ if (div == 0) -+ ++div; ++/* ++ * PCI block ++ */ ++#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000) ++#define AR71XX_PCI_CFG_SIZE 0x100 + -+ if (name) { -+ unsigned ahb_khz = (ar71xx_ahb_freq + 500) / 1000; -+ unsigned div_real = 2 * (div + 1); -+ printk(KERN_INFO "%s SPI clock %u kHz (AHB %u kHz / %u)\n", -+ name, -+ ahb_khz / div_real, -+ ahb_khz, div_real); -+ } ++#define PCI_REG_CRP_AD_CBE 0x00 ++#define PCI_REG_CRP_WRDATA 0x04 ++#define PCI_REG_CRP_RDDATA 0x08 ++#define PCI_REG_CFG_AD 0x0c ++#define PCI_REG_CFG_CBE 0x10 ++#define PCI_REG_CFG_WRDATA 0x14 ++#define PCI_REG_CFG_RDDATA 0x18 ++#define PCI_REG_PCI_ERR 0x1c ++#define PCI_REG_PCI_ERR_ADDR 0x20 ++#define PCI_REG_AHB_ERR 0x24 ++#define PCI_REG_AHB_ERR_ADDR 0x28 + -+ return SPI_CTRL_FASTEST + div; -+} ++#define PCI_CRP_CMD_WRITE 0x00010000 ++#define PCI_CRP_CMD_READ 0x00000000 ++#define PCI_CFG_CMD_READ 0x0000000a ++#define PCI_CFG_CMD_WRITE 0x0000000b + -+static int __init rb4xx_nand_probe(struct platform_device *pdev) -+{ -+ struct rb4xx_nand_info *info; -+ int ret; ++#define PCI_IDSEL_ADL_START 17 + -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); ++#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000) ++#define AR724X_PCI_CFG_SIZE 0x1000 + -+ ret = gpio_request(RB4XX_NAND_GPIO_RDY, "NAND RDY"); -+ if (ret) { -+ printk(KERN_ERR "rb4xx-nand: gpio request failed\n"); -+ return ret; -+ } ++#define AR724X_PCI_REG_APP 0x00 ++#define AR724X_PCI_REG_RESET 0x18 ++#define AR724X_PCI_REG_INT_STATUS 0x4c ++#define AR724X_PCI_REG_INT_MASK 0x50 + -+ ret = gpio_direction_input(RB4XX_NAND_GPIO_RDY); -+ if (ret) { -+ printk(KERN_ERR "rb4xx-nand: unable to set input mode " -+ "on gpio%d\n", RB4XX_NAND_GPIO_RDY); -+ goto err_free_gpio; -+ } ++#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0) ++#define AR724X_PCI_RESET_LINK_UP BIT(0) + -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) { -+ printk(KERN_ERR "rb4xx-nand: no memory for private data\n"); -+ ret = -ENOMEM; -+ goto err_free_gpio; -+ } ++#define AR724X_PCI_INT_DEV0 BIT(14) + -+#if USE_FAST_READ -+ spi_ctrl_fread = get_spi_ctrl(RB4XX_NAND_HZ, "NAND"); -+#endif -+ spi_ctrl_flash = get_spi_ctrl(RB4XX_FLASH_HZ, "FLASH"); ++/* ++ * RESET block ++ */ ++#define AR71XX_RESET_REG_TIMER 0x00 ++#define AR71XX_RESET_REG_TIMER_RELOAD 0x04 ++#define AR71XX_RESET_REG_WDOG_CTRL 0x08 ++#define AR71XX_RESET_REG_WDOG 0x0c ++#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10 ++#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14 ++#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18 ++#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c ++#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20 ++#define AR71XX_RESET_REG_RESET_MODULE 0x24 ++#define AR71XX_RESET_REG_PERFC_CTRL 0x2c ++#define AR71XX_RESET_REG_PERFC0 0x30 ++#define AR71XX_RESET_REG_PERFC1 0x34 ++#define AR71XX_RESET_REG_REV_ID 0x90 + -+ rb4xx_nand_write_cfg(CFG_BIT_nLEDS | CFG_BIT_nCE); ++#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18 ++#define AR91XX_RESET_REG_RESET_MODULE 0x1c ++#define AR91XX_RESET_REG_PERF_CTRL 0x20 ++#define AR91XX_RESET_REG_PERFC0 0x24 ++#define AR91XX_RESET_REG_PERFC1 0x28 + -+ info->chip.priv = &info; -+ info->mtd.priv = &info->chip; -+ info->mtd.owner = THIS_MODULE; ++#define AR724X_RESET_REG_RESET_MODULE 0x1c + -+ info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl; -+ info->chip.dev_ready = rb4xx_nand_dev_ready; -+ info->chip.read_byte = rb4xx_nand_read_byte; -+ info->chip.write_buf = rb4xx_nand_write_buf; -+ info->chip.read_buf = rb4xx_nand_read_buf; -+ info->chip.verify_buf = rb4xx_nand_verify_buf; ++#define AR933X_RESET_REG_RESET_MODULE 0x1c ++#define AR933X_RESET_REG_BOOTSTRAP 0xac ++#define AR933X_BOOTSTRAP_EEPBUSY BIT(4) ++#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) + -+ info->chip.chip_delay = 25; -+ info->chip.ecc.mode = NAND_ECC_SOFT; -+ info->chip.options |= NAND_NO_AUTOINCR; ++#define AR934X_RESET_REG_RESET_MODULE 0x1c ++#define AR934X_RESET_REG_BOOTSTRAP 0xb0 ++/* 0 - 25MHz 1 - 40 MHz */ ++#define AR934X_REF_CLK_40 (1 << 4) + -+ platform_set_drvdata(pdev, info); ++#define WDOG_CTRL_LAST_RESET BIT(31) ++#define WDOG_CTRL_ACTION_MASK 3 ++#define WDOG_CTRL_ACTION_NONE 0 /* no action */ ++#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */ ++#define WDOG_CTRL_ACTION_NMI 2 /* NMI */ ++#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */ + -+ ret = nand_scan_ident(&info->mtd, 1, NULL); -+ if (ret) { -+ ret = -ENXIO; -+ goto err_free_info; -+ } ++#define MISC_INT_ENET_LINK BIT(12) ++#define MISC_INT_DDR_PERF BIT(11) ++#define MISC_INT_TIMER4 BIT(10) ++#define MISC_INT_TIMER3 BIT(9) ++#define MISC_INT_TIMER2 BIT(8) ++#define MISC_INT_DMA BIT(7) ++#define MISC_INT_OHCI BIT(6) ++#define MISC_INT_PERFC BIT(5) ++#define MISC_INT_WDOG BIT(4) ++#define MISC_INT_UART BIT(3) ++#define MISC_INT_GPIO BIT(2) ++#define MISC_INT_ERROR BIT(1) ++#define MISC_INT_TIMER BIT(0) + -+ if (info->mtd.writesize == 512) -+ info->chip.ecc.layout = &rb4xx_nand_ecclayout; ++#define PCI_INT_CORE BIT(4) ++#define PCI_INT_DEV2 BIT(2) ++#define PCI_INT_DEV1 BIT(1) ++#define PCI_INT_DEV0 BIT(0) + -+ ret = nand_scan_tail(&info->mtd); -+ if (ret) { -+ return -ENXIO; -+ goto err_set_drvdata; -+ } ++#define RESET_MODULE_EXTERNAL BIT(28) ++#define RESET_MODULE_FULL_CHIP BIT(24) ++#define RESET_MODULE_AMBA2WMAC BIT(22) ++#define RESET_MODULE_CPU_NMI BIT(21) ++#define RESET_MODULE_CPU_COLD BIT(20) ++#define RESET_MODULE_DMA BIT(19) ++#define RESET_MODULE_SLIC BIT(18) ++#define RESET_MODULE_STEREO BIT(17) ++#define RESET_MODULE_DDR BIT(16) ++#define RESET_MODULE_GE1_MAC BIT(13) ++#define RESET_MODULE_GE1_PHY BIT(12) ++#define RESET_MODULE_USBSUS_OVERRIDE BIT(10) ++#define RESET_MODULE_GE0_MAC BIT(9) ++#define RESET_MODULE_GE0_PHY BIT(8) ++#define RESET_MODULE_USB_OHCI_DLL BIT(6) ++#define RESET_MODULE_USB_HOST BIT(5) ++#define RESET_MODULE_USB_PHY BIT(4) ++#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3) ++#define RESET_MODULE_PCI_BUS BIT(1) ++#define RESET_MODULE_PCI_CORE BIT(0) + -+#ifdef CONFIG_MTD_PARTITIONS -+ ret = add_mtd_partitions(&info->mtd, rb4xx_nand_partitions, -+ ARRAY_SIZE(rb4xx_nand_partitions)); -+#else -+ ret = add_mtd_device(&info->mtd); -+#endif -+ if (ret) -+ goto err_release_nand; ++#define AR724X_RESET_GE1_MDIO BIT(23) ++#define AR724X_RESET_GE0_MDIO BIT(22) ++#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10) ++#define AR724X_RESET_PCIE_PHY BIT(7) ++#define AR724X_RESET_PCIE BIT(6) ++#define AR724X_RESET_USB_HOST BIT(5) ++#define AR724X_RESET_USB_PHY BIT(4) ++#define AR724X_RESET_USBSUS_OVERRIDE BIT(3) + -+ return 0; ++#define AR933X_RESET_WMAC BIT(11) ++#define AR933X_RESET_GE1_MDIO BIT(23) ++#define AR933X_RESET_GE0_MDIO BIT(22) ++#define AR933X_RESET_GE1_MAC BIT(13) ++#define AR933X_RESET_GE0_MAC BIT(9) + -+err_release_nand: -+ nand_release(&info->mtd); -+err_set_drvdata: -+ platform_set_drvdata(pdev, NULL); -+err_free_info: -+ kfree(info); -+err_free_gpio: -+ gpio_free(RB4XX_NAND_GPIO_RDY); -+ return ret; -+} ++#define REV_ID_MAJOR_MASK 0xfff0 ++#define REV_ID_MAJOR_AR71XX 0x00a0 ++#define REV_ID_MAJOR_AR913X 0x00b0 ++#define REV_ID_MAJOR_AR7240 0x00c0 ++#define REV_ID_MAJOR_AR7241 0x0100 ++#define REV_ID_MAJOR_AR7242 0x1100 ++#define REV_ID_MAJOR_AR9330 0x0110 ++#define REV_ID_MAJOR_AR9331 0x1110 ++#define REV_ID_MAJOR_AR9341 0x0120 ++#define REV_ID_MAJOR_AR9342 0x1120 ++#define REV_ID_MAJOR_AR9344 0x2120 + -+static int __devexit rb4xx_nand_remove(struct platform_device *pdev) -+{ -+ struct rb4xx_nand_info *info = platform_get_drvdata(pdev); ++#define AR71XX_REV_ID_MINOR_MASK 0x3 ++#define AR71XX_REV_ID_MINOR_AR7130 0x0 ++#define AR71XX_REV_ID_MINOR_AR7141 0x1 ++#define AR71XX_REV_ID_MINOR_AR7161 0x2 ++#define AR71XX_REV_ID_REVISION_MASK 0x3 ++#define AR71XX_REV_ID_REVISION_SHIFT 2 + -+ nand_release(&info->mtd); -+ platform_set_drvdata(pdev, NULL); -+ kfree(info); ++#define AR91XX_REV_ID_MINOR_MASK 0x3 ++#define AR91XX_REV_ID_MINOR_AR9130 0x0 ++#define AR91XX_REV_ID_MINOR_AR9132 0x1 ++#define AR91XX_REV_ID_REVISION_MASK 0x3 ++#define AR91XX_REV_ID_REVISION_SHIFT 2 + -+ return 0; -+} ++#define AR724X_REV_ID_REVISION_MASK 0x3 + -+static struct platform_driver rb4xx_nand_driver = { -+ .probe = rb4xx_nand_probe, -+ .remove = __devexit_p(rb4xx_nand_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; ++#define AR933X_REV_ID_REVISION_MASK 0xf + -+static int __init rb4xx_nand_init(void) ++#define AR934X_REV_ID_REVISION_MASK 0xf ++ ++extern void __iomem *ar71xx_reset_base; ++ ++static inline void ar71xx_reset_wr(unsigned reg, u32 val) +{ -+ return platform_driver_register(&rb4xx_nand_driver); ++ __raw_writel(val, ar71xx_reset_base + reg); +} + -+static void __exit rb4xx_nand_exit(void) ++static inline u32 ar71xx_reset_rr(unsigned reg) +{ -+ platform_driver_unregister(&rb4xx_nand_driver); ++ return __raw_readl(ar71xx_reset_base + reg); +} + -+module_init(rb4xx_nand_init); -+module_exit(rb4xx_nand_exit); ++void ar71xx_device_stop(u32 mask); ++void ar71xx_device_start(u32 mask); ++int ar71xx_device_stopped(u32 mask); + -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_AUTHOR("Imre Kaloz "); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c linux-2.6.39/drivers/mtd/nand/rb750_nand.c ---- linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/mtd/nand/rb750_nand.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,360 @@ +/* -+ * NAND flash driver for the MikroTik RouterBOARD 750 ++ * SPI block ++ */ ++#define SPI_REG_FS 0x00 /* Function Select */ ++#define SPI_REG_CTRL 0x04 /* SPI Control */ ++#define SPI_REG_IOC 0x08 /* SPI I/O Control */ ++#define SPI_REG_RDS 0x0c /* Read Data Shift */ ++ ++#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */ ++ ++#define SPI_CTRL_RD BIT(6) /* Remap Disable */ ++#define SPI_CTRL_DIV_MASK 0x3f ++ ++#define SPI_IOC_DO BIT(0) /* Data Out pin */ ++#define SPI_IOC_CLK BIT(8) /* CLK pin */ ++#define SPI_IOC_CS(n) BIT(16 + (n)) ++#define SPI_IOC_CS0 SPI_IOC_CS(0) ++#define SPI_IOC_CS1 SPI_IOC_CS(1) ++#define SPI_IOC_CS2 SPI_IOC_CS(2) ++#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2) ++ ++void ar71xx_flash_acquire(void); ++void ar71xx_flash_release(void); ++ ++/* ++ * MII_CTRL block ++ */ ++#define MII_REG_MII0_CTRL 0x00 ++#define MII_REG_MII1_CTRL 0x04 ++ ++#define MII0_CTRL_IF_GMII 0 ++#define MII0_CTRL_IF_MII 1 ++#define MII0_CTRL_IF_RGMII 2 ++#define MII0_CTRL_IF_RMII 3 ++ ++#define MII1_CTRL_IF_RGMII 0 ++#define MII1_CTRL_IF_RMII 1 ++ ++#endif /* __ASSEMBLER__ */ ++ ++#endif /* __ASM_MACH_AR71XX_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 2011-04-27 12:19:21.867661560 +0200 +@@ -0,0 +1,26 @@ ++/* ++ * AR91xx parallel flash driver platform data definitions + * -+ * Copyright (C) 2010 Gabor Juhos ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+#include -+#include -+#include ++#ifndef __AR91XX_FLASH_H ++#define __AR91XX_FLASH_H + -+#include -+#include ++struct mtd_partition; + -+#define DRV_NAME "rb750-nand" -+#define DRV_VERSION "0.1.0" -+#define DRV_DESC "NAND flash driver for the RouterBOARD 750" ++struct ar91xx_flash_platform_data { ++ unsigned int width; ++ u8 is_shared:1; ++#ifdef CONFIG_MTD_PARTITIONS ++ unsigned int nr_parts; ++ struct mtd_partition *parts; ++#endif ++}; + -+#define RB750_NAND_IO0 BIT(RB750_GPIO_NAND_IO0) -+#define RB750_NAND_ALE BIT(RB750_GPIO_NAND_ALE) -+#define RB750_NAND_CLE BIT(RB750_GPIO_NAND_CLE) -+#define RB750_NAND_NRE BIT(RB750_GPIO_NAND_NRE) -+#define RB750_NAND_NWE BIT(RB750_GPIO_NAND_NWE) -+#define RB750_NAND_RDY BIT(RB750_GPIO_NAND_RDY) -+#define RB750_NAND_NCE BIT(RB750_GPIO_NAND_NCE) ++#endif /* __AR91XX_FLASH_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h 2011-08-06 09:32:36.758018150 +0200 +@@ -0,0 +1,67 @@ ++/* ++ * Atheros AR933X UART defines ++ * ++ * Copyright (C) 2011 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+#define RB750_NAND_DATA_SHIFT 1 -+#define RB750_NAND_DATA_BITS (0xff << RB750_NAND_DATA_SHIFT) -+#define RB750_NAND_INPUT_BITS (RB750_NAND_DATA_BITS | RB750_NAND_RDY) -+#define RB750_NAND_OUTPUT_BITS (RB750_NAND_ALE | RB750_NAND_CLE | \ -+ RB750_NAND_NRE | RB750_NAND_NWE | \ -+ RB750_NAND_NCE) ++#ifndef __AR933X_UART_H ++#define __AR933X_UART_H ++ ++#define AR933X_UART_REGS_SIZE 20 ++#define AR933X_UART_FIFO_SIZE 16 ++ ++#define AR933X_UART_DATA_REG 0x00 ++#define AR933X_UART_CS_REG 0x04 ++#define AR933X_UART_CLOCK_REG 0x08 ++#define AR933X_UART_INT_REG 0x0c ++#define AR933X_UART_INT_EN_REG 0x10 ++ ++#define AR933X_UART_DATA_TX_RX_MASK 0xff ++#define AR933X_UART_DATA_RX_CSR BIT(8) ++#define AR933X_UART_DATA_TX_CSR BIT(9) ++ ++#define AR933X_UART_CS_PARITY_S 0 ++#define AR933X_UART_CS_PARITY_M 0x3 ++#define AR933X_UART_CS_PARITY_NONE 0 ++#define AR933X_UART_CS_PARITY_ODD 1 ++#define AR933X_UART_CS_PARITY_EVEN 2 ++#define AR933X_UART_CS_IF_MODE_S 2 ++#define AR933X_UART_CS_IF_MODE_M 0x3 ++#define AR933X_UART_CS_IF_MODE_NONE 0 ++#define AR933X_UART_CS_IF_MODE_DTE 1 ++#define AR933X_UART_CS_IF_MODE_DCE 2 ++#define AR933X_UART_CS_FLOW_CTRL_S 4 ++#define AR933X_UART_CS_FLOW_CTRL_M 0x3 ++#define AR933X_UART_CS_DMA_EN BIT(6) ++#define AR933X_UART_CS_TX_READY_ORIDE BIT(7) ++#define AR933X_UART_CS_RX_READY_ORIDE BIT(8) ++#define AR933X_UART_CS_TX_READY BIT(9) ++#define AR933X_UART_CS_RX_BREAK BIT(10) ++#define AR933X_UART_CS_TX_BREAK BIT(11) ++#define AR933X_UART_CS_HOST_INT BIT(12) ++#define AR933X_UART_CS_HOST_INT_EN BIT(13) ++#define AR933X_UART_CS_TX_BUSY BIT(14) ++#define AR933X_UART_CS_RX_BUSY BIT(15) ++ ++#define AR933X_UART_CLOCK_STEP_M 0xffff ++#define AR933X_UART_CLOCK_SCALE_M 0xfff ++#define AR933X_UART_CLOCK_SCALE_S 16 ++#define AR933X_UART_CLOCK_STEP_M 0xffff ++ ++#define AR933X_UART_INT_RX_VALID BIT(0) ++#define AR933X_UART_INT_TX_READY BIT(1) ++#define AR933X_UART_INT_RX_FRAMING_ERR BIT(2) ++#define AR933X_UART_INT_RX_OFLOW_ERR BIT(3) ++#define AR933X_UART_INT_TX_OFLOW_ERR BIT(4) ++#define AR933X_UART_INT_RX_PARITY_ERR BIT(5) ++#define AR933X_UART_INT_RX_BREAK_ON BIT(6) ++#define AR933X_UART_INT_RX_BREAK_OFF BIT(7) ++#define AR933X_UART_INT_RX_FULL BIT(8) ++#define AR933X_UART_INT_TX_EMPTY BIT(9) ++#define AR933X_UART_INT_ALLINTS 0x3ff ++ ++#endif /* __AR933X_UART_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h 2011-08-06 09:32:36.758018150 +0200 +@@ -0,0 +1,18 @@ ++/* ++ * Platform data definition for Atheros AR933X UART ++ * ++ * Copyright (C) 2011 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+struct rb750_nand_info { -+ struct nand_chip chip; -+ struct mtd_info mtd; ++#ifndef _AR933X_UART_PLATFORM_H ++#define _AR933X_UART_PLATFORM_H ++ ++struct ar933x_uart_platform_data { ++ unsigned uartclk; +}; + ++#endif /* _AR933X_UART_PLATFORM_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 2011-04-27 12:19:21.877661867 +0200 +@@ -0,0 +1,56 @@ +/* -+ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader -+ * will not be able to find the kernel that we load. ++ * Atheros AR71xx specific CPU feature overrides ++ * ++ * Copyright (C) 2008 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This file was derived from: include/asm-mips/cpu-features.h ++ * Copyright (C) 2003, 2004 Ralf Baechle ++ * Copyright (C) 2004 Maciej W. Rozycki ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * + */ -+static struct nand_ecclayout rb750_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; -+ -+static struct mtd_partition rb750_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, { -+ .name = "rootfs", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+static void rb750_nand_write(const u8 *buf, unsigned len) -+{ -+ void __iomem *base = ar71xx_gpio_base; -+ u32 out; -+ unsigned i; ++#ifndef __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H ++#define __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H + -+ /* set data lines to output mode */ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_DATA_BITS, -+ base + GPIO_REG_OE); ++#define cpu_has_tlb 1 ++#define cpu_has_4kex 1 ++#define cpu_has_3k_cache 0 ++#define cpu_has_4k_cache 1 ++#define cpu_has_tx39_cache 0 ++#define cpu_has_sb1_cache 0 ++#define cpu_has_fpu 0 ++#define cpu_has_32fpr 0 ++#define cpu_has_counter 1 ++#define cpu_has_watch 1 ++#define cpu_has_divec 1 + -+ out = __raw_readl(base + GPIO_REG_OUT); -+ out &= ~(RB750_NAND_DATA_BITS | RB750_NAND_NWE); -+ for (i = 0; i != len; i++) { -+ u32 data; ++#define cpu_has_prefetch 1 ++#define cpu_has_ejtag 1 ++#define cpu_has_llsc 1 + -+ data = buf[i]; -+ data <<= RB750_NAND_DATA_SHIFT; -+ data |= out; -+ __raw_writel(data, base + GPIO_REG_OUT); ++#define cpu_has_mips16 1 ++#define cpu_has_mdmx 0 ++#define cpu_has_mips3d 0 ++#define cpu_has_smartmips 0 + -+ __raw_writel(data | RB750_NAND_NWE, base + GPIO_REG_OUT); -+ /* flush write */ -+ __raw_readl(base + GPIO_REG_OUT); -+ } ++#define cpu_has_mips32r1 1 ++#define cpu_has_mips32r2 1 ++#define cpu_has_mips64r1 0 ++#define cpu_has_mips64r2 0 + -+ /* set data lines to input mode */ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~RB750_NAND_DATA_BITS, -+ base + GPIO_REG_OE); -+ /* flush write */ -+ __raw_readl(base + GPIO_REG_OE); -+} ++#define cpu_has_dsp 0 ++#define cpu_has_mipsmt 0 + -+static int rb750_nand_read_verify(u8 *read_buf, unsigned len, -+ const u8 *verify_buf) -+{ -+ void __iomem *base = ar71xx_gpio_base; -+ unsigned i; ++#define cpu_has_64bits 0 ++#define cpu_has_64bit_zero_reg 0 ++#define cpu_has_64bit_gp_regs 0 ++#define cpu_has_64bit_addresses 0 + -+ for (i = 0; i < len; i++) { -+ u8 data; ++#define cpu_dcache_line_size() 32 ++#define cpu_icache_line_size() 32 + -+ /* activate RE line */ -+ __raw_writel(RB750_NAND_NRE, base + GPIO_REG_CLEAR); -+ /* flush write */ -+ __raw_readl(base + GPIO_REG_CLEAR); ++#endif /* __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h 2011-04-27 12:19:21.877661867 +0200 +@@ -0,0 +1,53 @@ ++/* ++ * Atheros AR71xx GPIO API definitions ++ * ++ * Copyright (C) 2008 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ + -+ /* read input lines */ -+ data = __raw_readl(base + GPIO_REG_IN) >> RB750_NAND_DATA_SHIFT; ++#ifndef __ASM_MACH_AR71XX_GPIO_H ++#define __ASM_MACH_AR71XX_GPIO_H + -+ /* deactivate RE line */ -+ __raw_writel(RB750_NAND_NRE, base + GPIO_REG_SET); ++#define ARCH_NR_GPIOS 64 ++#include + -+ if (read_buf) -+ read_buf[i] = data; -+ else if (verify_buf && verify_buf[i] != data) -+ return -EFAULT; -+ } ++#include + -+ return 0; -+} ++extern unsigned long ar71xx_gpio_count; ++extern void __ar71xx_gpio_set_value(unsigned gpio, int value); ++extern int __ar71xx_gpio_get_value(unsigned gpio); + -+static void rb750_nand_select_chip(struct mtd_info *mtd, int chip) ++static inline int gpio_to_irq(unsigned gpio) +{ -+ void __iomem *base = ar71xx_gpio_base; -+ u32 func; -+ -+ func = __raw_readl(base + GPIO_REG_FUNC); -+ if (chip >= 0) { -+ /* disable latch */ -+ rb750_latch_change(RB750_LVC573_LE, 0); -+ -+ /* disable alternate functions */ -+ ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, -+ AR724X_GPIO_FUNC_SPI_EN); -+ -+ /* set input mode for data lines */ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) & -+ ~RB750_NAND_INPUT_BITS, -+ base + GPIO_REG_OE); -+ -+ /* deactivate RE and WE lines */ -+ __raw_writel(RB750_NAND_NRE | RB750_NAND_NWE, -+ base + GPIO_REG_SET); -+ /* flush write */ -+ (void) __raw_readl(base + GPIO_REG_SET); -+ -+ /* activate CE line */ -+ __raw_writel(RB750_NAND_NCE, base + GPIO_REG_CLEAR); -+ } else { -+ /* deactivate CE line */ -+ __raw_writel(RB750_NAND_NCE, base + GPIO_REG_SET); -+ /* flush write */ -+ (void) __raw_readl(base + GPIO_REG_SET); -+ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) | -+ RB750_NAND_IO0 | RB750_NAND_RDY, -+ base + GPIO_REG_OE); -+ -+ /* restore alternate functions */ -+ ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN, -+ AR724X_GPIO_FUNC_JTAG_DISABLE); -+ -+ /* enable latch */ -+ rb750_latch_change(0, RB750_LVC573_LE); -+ } ++ return AR71XX_GPIO_IRQ(gpio); +} + -+static int rb750_nand_dev_ready(struct mtd_info *mtd) ++static inline int irq_to_gpio(unsigned irq) +{ -+ void __iomem *base = ar71xx_gpio_base; -+ -+ return !!(__raw_readl(base + GPIO_REG_IN) & RB750_NAND_RDY); ++ return irq - AR71XX_GPIO_IRQ_BASE; +} + -+static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) ++static inline int gpio_get_value(unsigned gpio) +{ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ void __iomem *base = ar71xx_gpio_base; -+ u32 t; -+ -+ t = __raw_readl(base + GPIO_REG_OUT); -+ -+ t &= ~(RB750_NAND_CLE | RB750_NAND_ALE); -+ t |= (ctrl & NAND_CLE) ? RB750_NAND_CLE : 0; -+ t |= (ctrl & NAND_ALE) ? RB750_NAND_ALE : 0; -+ -+ __raw_writel(t, base + GPIO_REG_OUT); -+ /* flush write */ -+ __raw_readl(base + GPIO_REG_OUT); -+ } ++ if (gpio < ar71xx_gpio_count) ++ return __ar71xx_gpio_get_value(gpio); + -+ if (cmd != NAND_CMD_NONE) { -+ u8 t = cmd; -+ rb750_nand_write(&t, 1); -+ } ++ return __gpio_get_value(gpio); +} + -+static u8 rb750_nand_read_byte(struct mtd_info *mtd) ++static inline void gpio_set_value(unsigned gpio, int value) +{ -+ u8 data = 0; -+ rb750_nand_read_verify(&data, 1, NULL); -+ return data; ++ if (gpio < ar71xx_gpio_count) ++ __ar71xx_gpio_set_value(gpio, value); ++ else ++ __gpio_set_value(gpio, value); +} + -+static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) -+{ -+ rb750_nand_read_verify(buf, len, NULL); -+} ++#define gpio_cansleep __gpio_cansleep + -+static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) -+{ -+ rb750_nand_write(buf, len); -+} ++#endif /* __ASM_MACH_AR71XX_GPIO_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h 2011-04-27 12:19:21.877661867 +0200 +@@ -0,0 +1,17 @@ ++/* ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++#ifndef __ASM_MACH_AR71XX_IRQ_H ++#define __ASM_MACH_AR71XX_IRQ_H + -+static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len) -+{ -+ return rb750_nand_read_verify(NULL, len, buf); -+} ++#define MIPS_CPU_IRQ_BASE 0 ++#define NR_IRQS 80 + -+static void __init rb750_nand_gpio_init(void) -+{ -+ void __iomem *base = ar71xx_gpio_base; -+ u32 out; ++#include_next + -+ out = __raw_readl(base + GPIO_REG_OUT); ++#endif /* __ASM_MACH_AR71XX_IRQ_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 2011-04-27 12:19:21.877661867 +0200 +@@ -0,0 +1,32 @@ ++/* ++ * Atheros AR71xx specific kernel entry setup ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++#ifndef __ASM_MACH_AR71XX_KERNEL_ENTRY_H ++#define __ASM_MACH_AR71XX_KERNEL_ENTRY_H + -+ /* setup output levels */ -+ __raw_writel(RB750_NAND_NCE | RB750_NAND_NRE | RB750_NAND_NWE, -+ base + GPIO_REG_SET); ++ /* ++ * Some bootloaders set the 'Kseg0 coherency algorithm' to ++ * 'Cacheable, noncoherent, write-through, no write allocate' ++ * and this cause performance issues. Let's go and change it to ++ * 'Cacheable, noncoherent, write-back, write allocate' ++ */ ++ .macro kernel_entry_setup ++ mfc0 t0, CP0_CONFIG ++ li t1, ~CONF_CM_CMASK ++ and t0, t1 ++ ori t0, CONF_CM_CACHABLE_NONCOHERENT ++ mtc0 t0, CP0_CONFIG ++ nop ++ .endm + -+ __raw_writel(RB750_NAND_ALE | RB750_NAND_CLE, -+ base + GPIO_REG_CLEAR); ++ .macro smp_slave_setup ++ .endm + -+ /* setup input lines */ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(RB750_NAND_INPUT_BITS), -+ base + GPIO_REG_OE); ++#endif /* __ASM_MACH_AR71XX_KERNEL_ENTRY_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 2011-04-27 12:19:21.877661867 +0200 +@@ -0,0 +1,66 @@ ++/* ++ * MikroTik RouterBOARD 750 definitions ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++#ifndef _MACH_RB750_H ++#define _MACH_RB750_H + -+ /* setup output lines */ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_OUTPUT_BITS, -+ base + GPIO_REG_OE); ++#include + -+ rb750_latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0); -+} ++#define RB750_GPIO_LVC573_LE 0 /* Latch enable on LVC573 */ ++#define RB750_GPIO_NAND_IO0 1 /* NAND I/O 0 */ ++#define RB750_GPIO_NAND_IO1 2 /* NAND I/O 1 */ ++#define RB750_GPIO_NAND_IO2 3 /* NAND I/O 2 */ ++#define RB750_GPIO_NAND_IO3 4 /* NAND I/O 3 */ ++#define RB750_GPIO_NAND_IO4 5 /* NAND I/O 4 */ ++#define RB750_GPIO_NAND_IO5 6 /* NAND I/O 5 */ ++#define RB750_GPIO_NAND_IO6 7 /* NAND I/O 6 */ ++#define RB750_GPIO_NAND_IO7 8 /* NAND I/O 7 */ ++#define RB750_GPIO_NAND_NCE 11 /* NAND Chip Enable (active low) */ ++#define RB750_GPIO_NAND_RDY 12 /* NAND Ready */ ++#define RB750_GPIO_NAND_CLE 14 /* NAND Command Latch Enable */ ++#define RB750_GPIO_NAND_ALE 15 /* NAND Address Latch Enable */ ++#define RB750_GPIO_NAND_NRE 16 /* NAND Read Enable (active low) */ ++#define RB750_GPIO_NAND_NWE 17 /* NAND Write Enable (active low) */ + -+static int __init rb750_nand_probe(struct platform_device *pdev) -+{ -+ struct rb750_nand_info *info; -+ int ret; ++#define RB750_GPIO_BTN_RESET 1 ++#define RB750_GPIO_SPI_CS0 2 ++#define RB750_GPIO_LED_ACT 12 ++#define RB750_GPIO_LED_PORT1 13 ++#define RB750_GPIO_LED_PORT2 14 ++#define RB750_GPIO_LED_PORT3 15 ++#define RB750_GPIO_LED_PORT4 16 ++#define RB750_GPIO_LED_PORT5 17 + -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); ++#define RB750_LED_ACT BIT(RB750_GPIO_LED_ACT) ++#define RB750_LED_PORT1 BIT(RB750_GPIO_LED_PORT1) ++#define RB750_LED_PORT2 BIT(RB750_GPIO_LED_PORT2) ++#define RB750_LED_PORT3 BIT(RB750_GPIO_LED_PORT3) ++#define RB750_LED_PORT4 BIT(RB750_GPIO_LED_PORT4) ++#define RB750_LED_PORT5 BIT(RB750_GPIO_LED_PORT5) + -+ rb750_nand_gpio_init(); ++#define RB750_LVC573_LE BIT(RB750_GPIO_LVC573_LE) + -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) -+ return -ENOMEM; ++#define RB750_LED_BITS (RB750_LED_PORT1 | RB750_LED_PORT2 | RB750_LED_PORT3 | \ ++ RB750_LED_PORT4 | RB750_LED_PORT5 | RB750_LED_ACT) + -+ info->chip.priv = &info; -+ info->mtd.priv = &info->chip; -+ info->mtd.owner = THIS_MODULE; ++struct rb750_led_data { ++ char *name; ++ char *default_trigger; ++ u32 mask; ++ int active_low; ++}; + -+ info->chip.select_chip = rb750_nand_select_chip; -+ info->chip.cmd_ctrl = rb750_nand_cmd_ctrl; -+ info->chip.dev_ready = rb750_nand_dev_ready; -+ info->chip.read_byte = rb750_nand_read_byte; -+ info->chip.write_buf = rb750_nand_write_buf; -+ info->chip.read_buf = rb750_nand_read_buf; -+ info->chip.verify_buf = rb750_nand_verify_buf; ++struct rb750_led_platform_data { ++ int num_leds; ++ struct rb750_led_data *leds; ++}; + -+ info->chip.chip_delay = 25; -+ info->chip.ecc.mode = NAND_ECC_SOFT; -+ info->chip.options |= NAND_NO_AUTOINCR; ++int rb750_latch_change(u32 mask_clr, u32 mask_set); + -+ platform_set_drvdata(pdev, info); ++#endif /* _MACH_RB750_H */ +\ No newline at end of file +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h 2011-04-27 12:19:21.877661867 +0200 +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (C) 2008 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h ++ * Copyright (C) 2003, 2004 Ralf Baechle ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ ret = nand_scan_ident(&info->mtd, 1); -+ if (ret) { -+ ret = -ENXIO; -+ goto err_free_info; -+ } ++#ifndef __ASM_MACH_AR71XX_MANGLE_PORT_H ++#define __ASM_MACH_AR71XX_MANGLE_PORT_H + -+ if (info->mtd.writesize == 512) -+ info->chip.ecc.layout = &rb750_nand_ecclayout; ++#define __swizzle_addr_b(port) ((port) ^ 3) ++#define __swizzle_addr_w(port) ((port) ^ 2) ++#define __swizzle_addr_l(port) (port) ++#define __swizzle_addr_q(port) (port) + -+ ret = nand_scan_tail(&info->mtd); -+ if (ret) { -+ return -ENXIO; -+ goto err_set_drvdata; -+ } ++#if defined(CONFIG_SWAP_IO_SPACE) ++ ++# define ioswabb(a, x) (x) ++# define __mem_ioswabb(a, x) (x) ++# define ioswabw(a, x) le16_to_cpu(x) ++# define __mem_ioswabw(a, x) (x) ++# define ioswabl(a, x) le32_to_cpu(x) ++# define __mem_ioswabl(a, x) (x) ++# define ioswabq(a, x) le64_to_cpu(x) ++# define __mem_ioswabq(a, x) (x) + -+#ifdef CONFIG_MTD_PARTITIONS -+ ret = add_mtd_partitions(&info->mtd, rb750_nand_partitions, -+ ARRAY_SIZE(rb750_nand_partitions)); +#else -+ ret = add_mtd_device(&info->mtd); -+#endif -+ if (ret) -+ goto err_release_nand; + -+ return 0; ++# define ioswabb(a, x) (x) ++# define __mem_ioswabb(a, x) (x) ++# define ioswabw(a, x) (x) ++# define __mem_ioswabw(a, x) cpu_to_le16(x) ++# define ioswabl(a, x) (x) ++# define __mem_ioswabl(a, x) cpu_to_le32(x) ++# define ioswabq(a, x) (x) ++# define __mem_ioswabq(a, x) cpu_to_le64(x) + -+ err_release_nand: -+ nand_release(&info->mtd); -+ err_set_drvdata: -+ platform_set_drvdata(pdev, NULL); -+ err_free_info: -+ kfree(info); -+ return ret; -+} ++#endif + -+static int __devexit rb750_nand_remove(struct platform_device *pdev) -+{ -+ struct rb750_nand_info *info = platform_get_drvdata(pdev); ++#endif /* __ASM_MACH_AR71XX_MANGLE_PORT_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h 2011-04-27 12:19:21.877661867 +0200 +@@ -0,0 +1,46 @@ ++/* ++ * Atheros AR71xx SoC specific PCI definitions ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ nand_release(&info->mtd); -+ platform_set_drvdata(pdev, NULL); -+ kfree(info); ++#ifndef __ASM_MACH_AR71XX_PCI_H ++#define __ASM_MACH_AR71XX_PCI_H + -+ return 0; -+} ++struct pci_dev; + -+static struct platform_driver rb750_nand_driver = { -+ .probe = rb750_nand_probe, -+ .remove = __devexit_p(rb750_nand_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, ++struct ar71xx_pci_irq { ++ int irq; ++ u8 slot; ++ u8 pin; +}; + -+static int __init rb750_nand_init(void) -+{ -+ return platform_driver_register(&rb750_nand_driver); -+} ++#ifdef CONFIG_PCI ++extern int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev); ++extern unsigned ar71xx_pci_nr_irqs __initdata; ++extern struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata; + -+static void __exit rb750_nand_exit(void) ++int ar71xx_pcibios_map_irq(const struct pci_dev *dev, ++ uint8_t slot, uint8_t pin) __init; ++int ar71xx_pcibios_init(void) __init; ++ ++int ar71xx_pci_be_handler(int is_fixup); ++ ++int ar724x_pcibios_map_irq(const struct pci_dev *dev, ++ uint8_t slot, uint8_t pin) __init; ++int ar724x_pcibios_init(void) __init; ++ ++int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) __init; ++#else ++static inline int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) +{ -+ platform_driver_unregister(&rb750_nand_driver); ++ return 0; +} ++#endif + -+module_init(rb750_nand_init); -+module_exit(rb750_nand_exit); -+ -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c linux-2.6.39/drivers/mtd/wrt160nl_part.c ---- linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/mtd/wrt160nl_part.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,181 @@ ++#endif /* __ASM_MACH_AR71XX_PCI_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h 2011-08-22 07:40:11.890481646 +0200 +@@ -0,0 +1,63 @@ +/* -+ * Copyright (C) 2009 Christian Daniel -+ * Copyright (C) 2009 Gabor Juhos ++ * Atheros AR71xx SoC specific platform data definitions + * -+ * 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. -+ * -+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ * TRX flash partition table. -+ * Based on ar7 map by Felix Fietkau ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+ -+#include -+#include ++#ifndef __ASM_MACH_AR71XX_PLATFORM_H ++#define __ASM_MACH_AR71XX_PLATFORM_H + -+struct cybertan_header { -+ char magic[4]; -+ u8 res1[4]; -+ char fw_date[3]; -+ char fw_ver[3]; -+ char id[4]; -+ char hw_ver; -+ char unused; -+ u8 flags[2]; -+ u8 res2[10]; -+}; ++#include ++#include ++#include ++#include + -+#define TRX_PARTS 6 -+#define TRX_MAGIC 0x30524448 -+#define TRX_MAX_OFFSET 3 ++struct ag71xx_platform_data { ++ phy_interface_t phy_if_mode; ++ u32 phy_mask; ++ int speed; ++ int duplex; ++ u32 reset_bit; ++ u32 mii_if; ++ u8 mac_addr[ETH_ALEN]; ++ struct device *mii_bus_dev; + -+struct trx_header { -+ uint32_t magic; /* "HDR0" */ -+ uint32_t len; /* Length of file including header */ -+ uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ -+ uint32_t flag_version; /* 0:15 flags, 16:31 version */ -+ uint32_t offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ -+}; ++ u8 has_gbit:1; ++ u8 is_ar91xx:1; ++ u8 is_ar7240:1; ++ u8 is_ar724x:1; ++ u8 has_ar8216:1; ++ u8 has_ar7240_switch:1; + -+#define IH_MAGIC 0x27051956 /* Image Magic Number */ -+#define IH_NMLEN 32 /* Image Name Length */ ++ void (*ddr_flush)(void); ++ void (*set_pll)(int speed); + -+struct uimage_header { -+ uint32_t ih_magic; /* Image Header Magic Number */ -+ uint32_t ih_hcrc; /* Image Header CRC Checksum */ -+ uint32_t ih_time; /* Image Creation Timestamp */ -+ uint32_t ih_size; /* Image Data Size */ -+ uint32_t ih_load; /* Data» Load Address */ -+ uint32_t ih_ep; /* Entry Point Address */ -+ uint32_t ih_dcrc; /* Image Data CRC Checksum */ -+ uint8_t ih_os; /* Operating System */ -+ uint8_t ih_arch; /* CPU architecture */ -+ uint8_t ih_type; /* Image Type */ -+ uint8_t ih_comp; /* Compression Type */ -+ uint8_t ih_name[IH_NMLEN]; /* Image Name */ ++ u32 fifo_cfg1; ++ u32 fifo_cfg2; ++ u32 fifo_cfg3; +}; + -+struct wrt160nl_header { -+ struct cybertan_header cybertan; -+ struct trx_header trx; -+ struct uimage_header uimage; -+} __attribute__ ((packed)); -+ -+static struct mtd_partition trx_parts[TRX_PARTS]; -+ -+static int wrt160nl_parse_partitions(struct mtd_info *master, -+ struct mtd_partition **pparts, -+ unsigned long origin) -+{ -+ struct wrt160nl_header *header; -+ struct trx_header *theader; -+ struct uimage_header *uheader; -+ size_t retlen; -+ unsigned int kernel_len; -+ int ret; -+ -+ header = vmalloc(sizeof(*header)); -+ if (!header) { -+ return -ENOMEM; -+ goto out; -+ } -+ -+ ret = master->read(master, 4 * master->erasesize, sizeof(*header), -+ &retlen, (void *) header); -+ if (ret) -+ goto free_hdr; -+ -+ if (retlen != sizeof(*header)) { -+ ret = -EIO; -+ goto free_hdr; -+ } -+ -+ if (strncmp(header->cybertan.magic, "NL16", 4) != 0) { -+ printk(KERN_NOTICE "%s: no WRT160NL signature found\n", -+ master->name); -+ goto free_hdr; -+ } -+ -+ theader = &header->trx; -+ if (le32_to_cpu(theader->magic) != TRX_MAGIC) { -+ printk(KERN_NOTICE "%s: no TRX header found\n", master->name); -+ goto free_hdr; -+ } -+ -+ uheader = &header->uimage; -+ if (uheader->ih_magic != IH_MAGIC) { -+ printk(KERN_NOTICE "%s: no uImage found\n", master->name); -+ goto free_hdr; -+ } -+ -+ kernel_len = le32_to_cpu(theader->offsets[1]) + sizeof(struct cybertan_header); -+ -+ trx_parts[0].name = "u-boot"; -+ trx_parts[0].offset = 0; -+ trx_parts[0].size = 4 * master->erasesize; -+ trx_parts[0].mask_flags = MTD_WRITEABLE; -+ -+ trx_parts[1].name = "kernel"; -+ trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size; -+ trx_parts[1].size = kernel_len; -+ trx_parts[1].mask_flags = 0; -+ -+ trx_parts[2].name = "rootfs"; -+ trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size; -+ trx_parts[2].size = master->size - 6 * master->erasesize - trx_parts[1].size; -+ trx_parts[2].mask_flags = 0; -+ -+ trx_parts[3].name = "nvram"; -+ trx_parts[3].offset = master->size - 2 * master->erasesize; -+ trx_parts[3].size = master->erasesize; -+ trx_parts[3].mask_flags = MTD_WRITEABLE; ++struct ag71xx_mdio_platform_data { ++ u32 phy_mask; ++ int is_ar7240; ++}; + -+ trx_parts[4].name = "art"; -+ trx_parts[4].offset = master->size - master->erasesize; -+ trx_parts[4].size = master->erasesize; -+ trx_parts[4].mask_flags = MTD_WRITEABLE; ++struct ar71xx_ehci_platform_data { ++ u8 is_ar91xx; ++}; + -+ trx_parts[5].name = "firmware"; -+ trx_parts[5].offset = 4 * master->erasesize; -+ trx_parts[5].size = master->size - 6 * master->erasesize; -+ trx_parts[5].mask_flags = 0; ++struct ar71xx_spi_platform_data { ++ unsigned bus_num; ++ unsigned num_chipselect; ++ u32 (*get_ioc_base)(u8 chip_select, int cs_high, int is_on); ++}; + -+ *pparts = trx_parts; -+ ret = TRX_PARTS; ++#define AR71XX_SPI_CS_INACTIVE 0 ++#define AR71XX_SPI_CS_ACTIVE 1 + -+ free_hdr: -+ vfree(header); -+ out: -+ return ret; -+} ++#endif /* __ASM_MACH_AR71XX_PLATFORM_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h 2011-04-27 12:19:21.867661560 +0200 +@@ -0,0 +1,48 @@ ++/* ++ * SPI driver definitions for the CPLD chip on the Mikrotik RB4xx boards ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This file was based on the patches for Linux 2.6.27.39 published by ++ * MikroTik for their RouterBoard 4xx series devices. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+static struct mtd_part_parser wrt160nl_parser = { -+ .owner = THIS_MODULE, -+ .parse_fn = wrt160nl_parse_partitions, -+ .name = "wrt160nl", ++#define CPLD_GPIO_nLED1 0 ++#define CPLD_GPIO_nLED2 1 ++#define CPLD_GPIO_nLED3 2 ++#define CPLD_GPIO_nLED4 3 ++#define CPLD_GPIO_FAN 4 ++#define CPLD_GPIO_ALE 5 ++#define CPLD_GPIO_CLE 6 ++#define CPLD_GPIO_nCE 7 ++#define CPLD_GPIO_nLED5 8 ++ ++#define CPLD_NUM_GPIOS 9 ++ ++#define CPLD_CFG_nLED1 BIT(CPLD_GPIO_nLED1) ++#define CPLD_CFG_nLED2 BIT(CPLD_GPIO_nLED2) ++#define CPLD_CFG_nLED3 BIT(CPLD_GPIO_nLED3) ++#define CPLD_CFG_nLED4 BIT(CPLD_GPIO_nLED4) ++#define CPLD_CFG_FAN BIT(CPLD_GPIO_FAN) ++#define CPLD_CFG_ALE BIT(CPLD_GPIO_ALE) ++#define CPLD_CFG_CLE BIT(CPLD_GPIO_CLE) ++#define CPLD_CFG_nCE BIT(CPLD_GPIO_nCE) ++#define CPLD_CFG_nLED5 BIT(CPLD_GPIO_nLED5) ++ ++struct rb4xx_cpld_platform_data { ++ unsigned gpio_base; +}; + -+static int __init wrt160nl_parser_init(void) -+{ -+ return register_mtd_parser(&wrt160nl_parser); -+} ++extern int rb4xx_cpld_change_cfg(unsigned mask, unsigned value); ++extern int rb4xx_cpld_read(unsigned char *rx_buf, ++ const unsigned char *verify_buf, ++ unsigned cnt); ++extern int rb4xx_cpld_read_from(unsigned addr, ++ unsigned char *rx_buf, ++ const unsigned char *verify_buf, ++ unsigned cnt); ++extern int rb4xx_cpld_write(const unsigned char *buf, unsigned count); +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h 2011-04-27 12:19:21.867661560 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle ++ */ ++#ifndef __ASM_MACH_AR71XX_WAR_H ++#define __ASM_MACH_AR71XX_WAR_H + -+module_init(wrt160nl_parser_init); ++#define R4600_V1_INDEX_ICACHEOP_WAR 0 ++#define R4600_V1_HIT_CACHEOP_WAR 0 ++#define R4600_V2_HIT_CACHEOP_WAR 0 ++#define R5432_CP0_INTERRUPT_WAR 0 ++#define BCM1250_M3_WAR 0 ++#define SIBYTE_1956_WAR 0 ++#define MIPS4K_ICACHE_REFILL_WAR 0 ++#define MIPS_CACHE_SYNC_WAR 0 ++#define TX49XX_ICACHE_INDEX_INV_WAR 0 ++#define RM9000_CDEX_SMP_WAR 0 ++#define ICACHE_REFILLS_WORKAROUND_WAR 0 ++#define R10000_LLSC_WAR 0 ++#define MIPS34K_MISSED_ITLB_WAR 0 + -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Christian Daniel "); -diff -Nur linux-2.6.39.orig/drivers/net/Kconfig linux-2.6.39/drivers/net/Kconfig ---- linux-2.6.39.orig/drivers/net/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/Kconfig 2011-05-27 14:36:51.000000000 +0200 -@@ -2071,6 +2071,8 @@ ++#endif /* __ASM_MACH_AR71XX_WAR_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/time.h linux-2.6.39/arch/mips/include/asm/time.h +--- linux-2.6.39.orig/arch/mips/include/asm/time.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/include/asm/time.h 2011-08-24 05:53:05.239228886 +0200 +@@ -52,6 +52,7 @@ + */ + #ifdef CONFIG_CEVT_R4K_LIB + extern unsigned int __weak get_c0_compare_int(void); ++extern unsigned int __weak get_c0_compare_irq(void); + extern int r4k_clockevent_init(void); + #endif - The safe and default value for this is N. +diff -Nur linux-2.6.39.orig/arch/mips/Kconfig linux-2.6.39/arch/mips/Kconfig +--- linux-2.6.39.orig/arch/mips/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/Kconfig 2011-08-24 02:42:39.969240338 +0200 +@@ -84,6 +84,23 @@ + help + Support for the Atheros AR71XX/AR724X/AR913X SoCs. -+source drivers/net/ag71xx/Kconfig ++config ATHEROS_AR71XX ++ bool "Atheros AR71xx based boards" ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select ARCH_REQUIRE_GPIOLIB ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_CPU_MIPS32_R2 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_HAS_EARLY_PRINTK ++ select MIPS_MACHINE ++ help ++ Support for Atheros AR71xx based boards. + - config DL2K - tristate "DL2000/TC902x-based Gigabit Ethernet support" - depends on PCI -diff -Nur linux-2.6.39.orig/drivers/net/Makefile linux-2.6.39/drivers/net/Makefile ---- linux-2.6.39.orig/drivers/net/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/Makefile 2011-05-27 14:36:51.000000000 +0200 -@@ -112,6 +112,7 @@ - # end link order section - # + config BCM47XX + bool "Broadcom BCM47XX based boards" + select CEVT_R4K +@@ -739,6 +756,7 @@ + endchoice -+obj-$(CONFIG_AG71XX) += ag71xx/ - obj-$(CONFIG_SUNDANCE) += sundance.o - obj-$(CONFIG_HAMACHI) += hamachi.o - obj-$(CONFIG_NET) += Space.o loopback.o -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Kconfig linux-2.6.39/drivers/net/ag71xx/Kconfig ---- linux-2.6.39.orig/drivers/net/ag71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/Kconfig 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,33 @@ -+config AG71XX -+ tristate "Atheros AR71xx built-in ethernet mac support" -+ depends on ATHEROS_AR71XX -+ select PHYLIB -+ help -+ If you wish to compile a kernel for AR71xx/91xx and enable -+ ethernet support, then you should always answer Y to this. + source "arch/mips/alchemy/Kconfig" ++source "arch/mips/ar71xx/Kconfig" + source "arch/mips/ath79/Kconfig" + source "arch/mips/bcm63xx/Kconfig" + source "arch/mips/jazz/Kconfig" +@@ -907,6 +925,9 @@ + config MIPS_DISABLE_OBSOLETE_IDE + bool + ++config MYLOADER ++ bool + -+if AG71XX + config SYNC_R4K + bool + +diff -Nur linux-2.6.39.orig/arch/mips/Kconfig.orig linux-2.6.39/arch/mips/Kconfig.orig +--- linux-2.6.39.orig/arch/mips/Kconfig.orig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/Kconfig.orig 2011-08-22 16:21:32.077979816 +0200 +@@ -0,0 +1,2472 @@ ++config MIPS ++ bool ++ default y ++ select HAVE_GENERIC_DMA_COHERENT ++ select HAVE_IDE ++ select HAVE_OPROFILE ++ select HAVE_IRQ_WORK ++ select HAVE_PERF_EVENTS ++ select PERF_USE_VMALLOC ++ select HAVE_ARCH_KGDB ++ select HAVE_FUNCTION_TRACER ++ select HAVE_FUNCTION_TRACE_MCOUNT_TEST ++ select HAVE_DYNAMIC_FTRACE ++ select HAVE_FTRACE_MCOUNT_RECORD ++ select HAVE_C_RECORDMCOUNT ++ select HAVE_FUNCTION_GRAPH_TRACER ++ select HAVE_KPROBES ++ select HAVE_KRETPROBES ++ select RTC_LIB if !MACH_LOONGSON ++ select GENERIC_ATOMIC64 if !64BIT ++ select HAVE_DMA_ATTRS ++ select HAVE_DMA_API_DEBUG ++ select HAVE_GENERIC_HARDIRQS ++ select GENERIC_IRQ_PROBE ++ select GENERIC_IRQ_SHOW ++ select HAVE_ARCH_JUMP_LABEL ++ ++menu "Machine selection" ++ ++config ZONE_DMA ++ bool ++ ++choice ++ prompt "System type" ++ default SGI_IP22 ++ ++config MIPS_ALCHEMY ++ bool "Alchemy processor based machines" ++ select 64BIT_PHYS_ADDR ++ select CEVT_R4K_LIB ++ select CSRC_R4K_LIB ++ select IRQ_CPU ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_APM_EMULATION ++ select GENERIC_GPIO ++ select ARCH_WANT_OPTIONAL_GPIOLIB ++ select SYS_SUPPORTS_ZBOOT ++ ++config AR7 ++ bool "Texas Instruments AR7" ++ select BOOT_ELF32 ++ select DMA_NONCOHERENT ++ select CEVT_R4K ++ select CSRC_R4K ++ select IRQ_CPU ++ select NO_EXCEPT_FILL ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_EARLY_PRINTK ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SYS_SUPPORTS_ZBOOT_UART16550 ++ select ARCH_REQUIRE_GPIOLIB ++ select GCD ++ select VLYNQ ++ help ++ Support for the Texas Instruments AR7 System-on-a-Chip ++ family: TNETD7100, 7200 and 7300. + -+config AG71XX_DEBUG -+ bool "Atheros AR71xx built-in ethernet driver debugging" -+ default n ++config ATH79 ++ bool "Atheros AR71XX/AR724X/AR913X based boards" ++ select ARCH_REQUIRE_GPIOLIB ++ select BOOT_RAW ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select IRQ_CPU ++ select MIPS_MACHINE ++ select SYS_HAS_CPU_MIPS32_R2 ++ select SYS_HAS_EARLY_PRINTK ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN + help -+ Atheros AR71xx built-in ethernet driver debugging messages. ++ Support for the Atheros AR71XX/AR724X/AR913X SoCs. + -+config AG71XX_DEBUG_FS -+ bool "Atheros AR71xx built-in ethernet driver debugfs support" -+ depends on DEBUG_FS -+ default n ++config ATHEROS_AR71XX ++ bool "Atheros AR71xx based boards" ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select ARCH_REQUIRE_GPIOLIB ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_CPU_MIPS32_R2 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_HAS_EARLY_PRINTK ++ select MIPS_MACHINE + help -+ Say Y, if you need access to various statistics provided by -+ the ag71xx driver. ++ Support for Atheros AR71xx based boards. + -+config AG71XX_AR8216_SUPPORT -+ bool "special support for the Atheros AR8216 switch" -+ default n -+ default y if AR71XX_MACH_WNR2000 || AR71XX_MACH_MZK_W04NU ++config BCM47XX ++ bool "Broadcom BCM47XX based boards" ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SSB ++ select SSB_DRIVER_MIPS ++ select SSB_DRIVER_EXTIF ++ select SSB_EMBEDDED ++ select SSB_B43_PCI_BRIDGE if PCI ++ select SSB_PCICORE_HOSTMODE if PCI ++ select GENERIC_GPIO ++ select SYS_HAS_EARLY_PRINTK ++ select CFE + help -+ Say 'y' here if you want to enable special support for the -+ Atheros AR8216 switch found on some boards. ++ Support for BCM47XX based boards + -+endif -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Makefile linux-2.6.39/drivers/net/ag71xx/Makefile ---- linux-2.6.39.orig/drivers/net/ag71xx/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/Makefile 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,14 @@ -+# -+# Makefile for the Atheros AR71xx built-in ethernet macs -+# ++config BCM63XX ++ bool "Broadcom BCM63XX based boards" ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select IRQ_CPU ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_HAS_EARLY_PRINTK ++ select SWAP_IO_SPACE ++ select ARCH_REQUIRE_GPIOLIB ++ help ++ Support for BCM63XX based boards + -+ag71xx-y += ag71xx_main.o -+ag71xx-y += ag71xx_ethtool.o -+ag71xx-y += ag71xx_phy.o -+ag71xx-y += ag71xx_mdio.o ++config MIPS_COBALT ++ bool "Cobalt Server" ++ select CEVT_R4K ++ select CSRC_R4K ++ select CEVT_GT641XX ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select I8253 ++ select I8259 ++ select IRQ_CPU ++ select IRQ_GT641XX ++ select PCI_GT64XXX_PCI0 ++ select PCI ++ select SYS_HAS_CPU_NEVADA ++ select SYS_HAS_EARLY_PRINTK ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_LITTLE_ENDIAN + -+ag71xx-$(CONFIG_AG71XX_DEBUG_FS) += ag71xx_debugfs.o -+ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o ++config MACH_DECSTATION ++ bool "DECstations" ++ select BOOT_ELF32 ++ select CEVT_DS1287 ++ select CEVT_R4K ++ select CSRC_IOASIC ++ select CSRC_R4K ++ select CPU_DADDI_WORKAROUNDS if 64BIT ++ select CPU_R4000_WORKAROUNDS if 64BIT ++ select CPU_R4400_WORKAROUNDS if 64BIT ++ select DMA_NONCOHERENT ++ select NO_IOPORT ++ select IRQ_CPU ++ select SYS_HAS_CPU_R3000 ++ select SYS_HAS_CPU_R4X00 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SYS_SUPPORTS_128HZ ++ select SYS_SUPPORTS_256HZ ++ select SYS_SUPPORTS_1024HZ ++ help ++ This enables support for DEC's MIPS based workstations. For details ++ see the Linux/MIPS FAQ on and the ++ DECstation porting pages on . + -+obj-$(CONFIG_AG71XX) += ag71xx.o ++ If you have one of the following DECstation Models you definitely ++ want to choose R4xx0 for the CPU Type: + -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h linux-2.6.39/drivers/net/ag71xx/ag71xx.h ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,500 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ DECstation 5000/50 ++ DECstation 5000/150 ++ DECstation 5000/260 ++ DECsystem 5900/260 + -+#ifndef __AG71XX_H -+#define __AG71XX_H ++ otherwise choose R3000. + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++config MACH_JAZZ ++ bool "Jazz family of machines" ++ select ARC ++ select ARC32 ++ select ARCH_MAY_HAVE_PC_FDC ++ select CEVT_R4K ++ select CSRC_R4K ++ select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN ++ select GENERIC_ISA_DMA ++ select IRQ_CPU ++ select I8253 ++ select I8259 ++ select ISA ++ select SYS_HAS_CPU_R4X00 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL ++ select SYS_SUPPORTS_100HZ ++ help ++ This a family of machines based on the MIPS R4030 chipset which was ++ used by several vendors to build RISC/os and Windows NT workstations. ++ Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and ++ Olivetti M700-10 workstations. + -+#include ++config MACH_JZ4740 ++ bool "Ingenic JZ4740 based machines" ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select DMA_NONCOHERENT ++ select IRQ_CPU ++ select GENERIC_GPIO ++ select ARCH_REQUIRE_GPIOLIB ++ select SYS_HAS_EARLY_PRINTK ++ select HAVE_PWM ++ select HAVE_CLK + -+#include -+#include ++config LASAT ++ bool "LASAT Networks platforms" ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select SYS_HAS_EARLY_PRINTK ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select PCI_GT64XXX_PCI0 ++ select MIPS_NILE4 ++ select R5000_CPU_SCACHE ++ select SYS_HAS_CPU_R5000 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_64BIT_KERNEL if BROKEN ++ select SYS_SUPPORTS_LITTLE_ENDIAN + -+#define ETH_FCS_LEN 4 ++config MACH_LOONGSON ++ bool "Loongson family of machines" ++ select SYS_SUPPORTS_ZBOOT ++ help ++ This enables the support of Loongson family of machines. ++ ++ Loongson is a family of general-purpose MIPS-compatible CPUs. ++ developed at Institute of Computing Technology (ICT), ++ Chinese Academy of Sciences (CAS) in the People's Republic ++ of China. The chief architect is Professor Weiwu Hu. ++ ++config MIPS_MALTA ++ bool "MIPS Malta board" ++ select ARCH_MAY_HAVE_PC_FDC ++ select BOOT_ELF32 ++ select BOOT_RAW ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select GENERIC_ISA_DMA ++ select IRQ_CPU ++ select IRQ_GIC ++ select HW_HAS_PCI ++ select I8253 ++ select I8259 ++ select MIPS_BOARDS_GEN ++ select MIPS_BONITO64 ++ select MIPS_CPU_SCACHE ++ select PCI_GT64XXX_PCI0 ++ select MIPS_MSC ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_CPU_MIPS32_R2 ++ select SYS_HAS_CPU_MIPS64_R1 ++ select SYS_HAS_CPU_NEVADA ++ select SYS_HAS_CPU_RM7000 ++ select SYS_HAS_EARLY_PRINTK ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SYS_SUPPORTS_MIPS_CMP ++ select SYS_SUPPORTS_MULTITHREADING ++ select SYS_SUPPORTS_SMARTMIPS ++ select SYS_SUPPORTS_ZBOOT ++ help ++ This enables support for the MIPS Technologies Malta evaluation ++ board. + -+#define AG71XX_DRV_NAME "ag71xx" -+#define AG71XX_DRV_VERSION "0.5.35" ++config MIPS_SIM ++ bool 'MIPS simulator (MIPSsim)' ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select SYS_HAS_EARLY_PRINTK ++ select IRQ_CPU ++ select BOOT_RAW ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_CPU_MIPS32_R2 ++ select SYS_HAS_EARLY_PRINTK ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_MULTITHREADING ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ help ++ This option enables support for MIPS Technologies MIPSsim software ++ emulator. + -+#define AG71XX_NAPI_WEIGHT 64 -+#define AG71XX_OOM_REFILL (1 + HZ/10) ++config NEC_MARKEINS ++ bool "NEC EMMA2RH Mark-eins board" ++ select SOC_EMMA2RH ++ select HW_HAS_PCI ++ help ++ This enables support for the NEC Electronics Mark-eins boards. + -+#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE) -+#define AG71XX_INT_TX (AG71XX_INT_TX_PS) -+#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF) ++config MACH_VR41XX ++ bool "NEC VR4100 series based machines" ++ select CEVT_R4K ++ select CSRC_R4K ++ select SYS_HAS_CPU_VR41XX ++ select ARCH_REQUIRE_GPIOLIB + -+#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX) -+#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL) ++config NXP_STB220 ++ bool "NXP STB220 board" ++ select SOC_PNX833X ++ help ++ Support for NXP Semiconductors STB220 Development Board. + -+#define AG71XX_TX_FIFO_LEN 2048 -+#define AG71XX_TX_MTU_LEN 1536 -+#define AG71XX_RX_PKT_RESERVE 64 -+#define AG71XX_RX_PKT_SIZE \ -+ (AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN) ++config NXP_STB225 ++ bool "NXP 225 board" ++ select SOC_PNX833X ++ select SOC_PNX8335 ++ help ++ Support for NXP Semiconductors STB225 Development Board. + -+#define AG71XX_TX_RING_SIZE 64 -+#define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4) -+#define AG71XX_TX_THRES_WAKEUP \ -+ (AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4)) ++config PNX8550_JBS ++ bool "NXP PNX8550 based JBS board" ++ select PNX8550 ++ select SYS_SUPPORTS_LITTLE_ENDIAN + -+#define AG71XX_RX_RING_SIZE 128 ++config PNX8550_STB810 ++ bool "NXP PNX8550 based STB810 board" ++ select PNX8550 ++ select SYS_SUPPORTS_LITTLE_ENDIAN + -+#ifdef CONFIG_AG71XX_DEBUG -+#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args) -+#else -+#define DBG(fmt, args...) do {} while (0) -+#endif ++config PMC_MSP ++ bool "PMC-Sierra MSP chipsets" ++ depends on EXPERIMENTAL ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select SWAP_IO_SPACE ++ select NO_EXCEPT_FILL ++ select BOOT_RAW ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_CPU_MIPS32_R2 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select IRQ_CPU ++ select SERIAL_8250 ++ select SERIAL_8250_CONSOLE ++ help ++ This adds support for the PMC-Sierra family of Multi-Service ++ Processor System-On-A-Chips. These parts include a number ++ of integrated peripherals, interfaces and DSPs in addition to ++ a variety of MIPS cores. + -+#define ag71xx_assert(_cond) \ -+do { \ -+ if (_cond) \ -+ break; \ -+ printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \ -+ BUG(); \ -+} while (0) ++config PMC_YOSEMITE ++ bool "PMC-Sierra Yosemite eval board" ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_COHERENT ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select IRQ_CPU_RM7K ++ select IRQ_CPU_RM9K ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_RM9000 ++ select SYS_HAS_EARLY_PRINTK ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_HIGHMEM ++ select SYS_SUPPORTS_SMP ++ help ++ Yosemite is an evaluation board for the RM9000x2 processor ++ manufactured by PMC-Sierra. + -+struct ag71xx_desc { -+ u32 data; -+ u32 ctrl; -+#define DESC_EMPTY BIT(31) -+#define DESC_MORE BIT(24) -+#define DESC_PKTLEN_M 0xfff -+ u32 next; -+ u32 pad; -+} __attribute__((aligned(4))); ++config POWERTV ++ bool "Cisco PowerTV" ++ select BOOT_ELF32 ++ select CEVT_R4K ++ select CPU_MIPSR2_IRQ_VI ++ select CPU_MIPSR2_IRQ_EI ++ select CSRC_POWERTV ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select SYS_HAS_EARLY_PRINTK ++ select SYS_HAS_CPU_MIPS32_R2 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_HIGHMEM ++ select USB_OHCI_LITTLE_ENDIAN ++ help ++ This enables support for the Cisco PowerTV Platform. + -+struct ag71xx_buf { -+ struct sk_buff *skb; -+ struct ag71xx_desc *desc; -+ dma_addr_t dma_addr; -+ u32 pad; -+}; ++config SGI_IP22 ++ bool "SGI IP22 (Indy/Indigo2)" ++ select ARC ++ select ARC32 ++ select BOOT_ELF32 ++ select CEVT_R4K ++ select CSRC_R4K ++ select DEFAULT_SGI_PARTITION ++ select DMA_NONCOHERENT ++ select HW_HAS_EISA ++ select I8253 ++ select I8259 ++ select IP22_CPU_SCACHE ++ select IRQ_CPU ++ select GENERIC_ISA_DMA_SUPPORT_BROKEN ++ select SGI_HAS_I8042 ++ select SGI_HAS_INDYDOG ++ select SGI_HAS_HAL2 ++ select SGI_HAS_SEEQ ++ select SGI_HAS_WD93 ++ select SGI_HAS_ZILOG ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_R4X00 ++ select SYS_HAS_CPU_R5000 ++ # ++ # Disable EARLY_PRINTK for now since it leads to overwritten prom ++ # memory during early boot on some machines. ++ # ++ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com ++ # for a more details discussion ++ # ++ # select SYS_HAS_EARLY_PRINTK ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ help ++ This are the SGI Indy, Challenge S and Indigo2, as well as certain ++ OEM variants like the Tandem CMN B006S. To compile a Linux kernel ++ that runs on these, say Y here. ++ ++config SGI_IP27 ++ bool "SGI IP27 (Origin200/2000)" ++ select ARC ++ select ARC64 ++ select BOOT_ELF64 ++ select DEFAULT_SGI_PARTITION ++ select DMA_COHERENT ++ select SYS_HAS_EARLY_PRINTK ++ select HW_HAS_PCI ++ select NR_CPUS_DEFAULT_64 ++ select SYS_HAS_CPU_R10000 ++ select SYS_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_NUMA ++ select SYS_SUPPORTS_SMP ++ help ++ This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics ++ workstations. To compile a Linux kernel that runs on these, say Y ++ here. ++ ++config SGI_IP28 ++ bool "SGI IP28 (Indigo2 R10k) (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ select ARC ++ select ARC64 ++ select BOOT_ELF64 ++ select CEVT_R4K ++ select CSRC_R4K ++ select DEFAULT_SGI_PARTITION ++ select DMA_NONCOHERENT ++ select GENERIC_ISA_DMA_SUPPORT_BROKEN ++ select IRQ_CPU ++ select HW_HAS_EISA ++ select I8253 ++ select I8259 ++ select SGI_HAS_I8042 ++ select SGI_HAS_INDYDOG ++ select SGI_HAS_HAL2 ++ select SGI_HAS_SEEQ ++ select SGI_HAS_WD93 ++ select SGI_HAS_ZILOG ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_R10000 ++ # ++ # Disable EARLY_PRINTK for now since it leads to overwritten prom ++ # memory during early boot on some machines. ++ # ++ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com ++ # for a more details discussion ++ # ++ # select SYS_HAS_EARLY_PRINTK ++ select SYS_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ help ++ This is the SGI Indigo2 with R10000 processor. To compile a Linux ++ kernel that runs on these, say Y here. ++ ++config SGI_IP32 ++ bool "SGI IP32 (O2)" ++ select ARC ++ select ARC32 ++ select BOOT_ELF32 ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select R5000_CPU_SCACHE ++ select RM7000_CPU_SCACHE ++ select SYS_HAS_CPU_R5000 ++ select SYS_HAS_CPU_R10000 if BROKEN ++ select SYS_HAS_CPU_RM7000 ++ select SYS_HAS_CPU_NEVADA ++ select SYS_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ help ++ If you want this kernel to run on SGI O2 workstation, say Y here. ++ ++config SIBYTE_CRHINE ++ bool "Sibyte BCM91120C-CRhine" ++ depends on EXPERIMENTAL ++ select BOOT_ELF32 ++ select DMA_COHERENT ++ select SIBYTE_BCM1120 ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_SB1 ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ ++config SIBYTE_CARMEL ++ bool "Sibyte BCM91120x-Carmel" ++ depends on EXPERIMENTAL ++ select BOOT_ELF32 ++ select DMA_COHERENT ++ select SIBYTE_BCM1120 ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_SB1 ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ ++config SIBYTE_CRHONE ++ bool "Sibyte BCM91125C-CRhone" ++ depends on EXPERIMENTAL ++ select BOOT_ELF32 ++ select DMA_COHERENT ++ select SIBYTE_BCM1125 ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_SB1 ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_HIGHMEM ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ ++config SIBYTE_RHONE ++ bool "Sibyte BCM91125E-Rhone" ++ depends on EXPERIMENTAL ++ select BOOT_ELF32 ++ select DMA_COHERENT ++ select SIBYTE_BCM1125H ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_SB1 ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ ++config SIBYTE_SWARM ++ bool "Sibyte BCM91250A-SWARM" ++ select BOOT_ELF32 ++ select DMA_COHERENT ++ select HAVE_PATA_PLATFORM ++ select NR_CPUS_DEFAULT_2 ++ select SIBYTE_SB1250 ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_SB1 ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_HIGHMEM ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select ZONE_DMA32 if 64BIT ++ ++config SIBYTE_LITTLESUR ++ bool "Sibyte BCM91250C2-LittleSur" ++ depends on EXPERIMENTAL ++ select BOOT_ELF32 ++ select DMA_COHERENT ++ select HAVE_PATA_PLATFORM ++ select NR_CPUS_DEFAULT_2 ++ select SIBYTE_SB1250 ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_SB1 ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_HIGHMEM ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ ++config SIBYTE_SENTOSA ++ bool "Sibyte BCM91250E-Sentosa" ++ depends on EXPERIMENTAL ++ select BOOT_ELF32 ++ select DMA_COHERENT ++ select NR_CPUS_DEFAULT_2 ++ select SIBYTE_SB1250 ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_SB1 ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ ++config SIBYTE_BIGSUR ++ bool "Sibyte BCM91480B-BigSur" ++ select BOOT_ELF32 ++ select DMA_COHERENT ++ select NR_CPUS_DEFAULT_4 ++ select SIBYTE_BCM1x80 ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_SB1 ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_HIGHMEM ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select ZONE_DMA32 if 64BIT ++ ++config SNI_RM ++ bool "SNI RM200/300/400" ++ select ARC if CPU_LITTLE_ENDIAN ++ select ARC32 if CPU_LITTLE_ENDIAN ++ select SNIPROM if CPU_BIG_ENDIAN ++ select ARCH_MAY_HAVE_PC_FDC ++ select BOOT_ELF32 ++ select CEVT_R4K ++ select CSRC_R4K ++ select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN ++ select DMA_NONCOHERENT ++ select GENERIC_ISA_DMA ++ select HW_HAS_EISA ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select I8253 ++ select I8259 ++ select ISA ++ select SWAP_IO_SPACE if CPU_BIG_ENDIAN ++ select SYS_HAS_CPU_R4X00 ++ select SYS_HAS_CPU_R5000 ++ select SYS_HAS_CPU_R10000 ++ select R5000_CPU_SCACHE ++ select SYS_HAS_EARLY_PRINTK ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_HIGHMEM ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ help ++ The SNI RM200/300/400 are MIPS-based machines manufactured by ++ Siemens Nixdorf Informationssysteme (SNI), parent company of Pyramid ++ Technology and now in turn merged with Fujitsu. Say Y here to ++ support this machine type. + -+struct ag71xx_ring { -+ struct ag71xx_buf *buf; -+ u8 *descs_cpu; -+ dma_addr_t descs_dma; -+ unsigned int desc_size; -+ unsigned int curr; -+ unsigned int dirty; -+ unsigned int size; -+}; ++config MACH_TX39XX ++ bool "Toshiba TX39 series based machines" + -+struct ag71xx_mdio { -+ struct mii_bus *mii_bus; -+ int mii_irq[PHY_MAX_ADDR]; -+ void __iomem *mdio_base; -+ struct ag71xx_mdio_platform_data *pdata; -+}; ++config MACH_TX49XX ++ bool "Toshiba TX49 series based machines" + -+struct ag71xx_int_stats { -+ unsigned long rx_pr; -+ unsigned long rx_be; -+ unsigned long rx_of; -+ unsigned long tx_ps; -+ unsigned long tx_be; -+ unsigned long tx_ur; -+ unsigned long total; -+}; ++config MIKROTIK_RB532 ++ bool "Mikrotik RB532 boards" ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SWAP_IO_SPACE ++ select BOOT_RAW ++ select ARCH_REQUIRE_GPIOLIB ++ help ++ Support the Mikrotik(tm) RouterBoard 532 series, ++ based on the IDT RC32434 SoC. + -+struct ag71xx_napi_stats { -+ unsigned long napi_calls; -+ unsigned long rx_count; -+ unsigned long rx_packets; -+ unsigned long rx_packets_max; -+ unsigned long tx_count; -+ unsigned long tx_packets; -+ unsigned long tx_packets_max; ++config WR_PPMC ++ bool "Wind River PPMC board" ++ select CEVT_R4K ++ select CSRC_R4K ++ select IRQ_CPU ++ select BOOT_ELF32 ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select PCI_GT64XXX_PCI0 ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_CPU_MIPS32_R2 ++ select SYS_HAS_CPU_MIPS64_R1 ++ select SYS_HAS_CPU_NEVADA ++ select SYS_HAS_CPU_RM7000 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ help ++ This enables support for the Wind River MIPS32 4KC PPMC evaluation ++ board, which is based on GT64120 bridge chip. + -+ unsigned long rx[AG71XX_NAPI_WEIGHT + 1]; -+ unsigned long tx[AG71XX_NAPI_WEIGHT + 1]; -+}; ++config CAVIUM_OCTEON_SIMULATOR ++ bool "Cavium Networks Octeon Simulator" ++ select CEVT_R4K ++ select 64BIT_PHYS_ADDR ++ select DMA_COHERENT ++ select SYS_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_HIGHMEM ++ select SYS_SUPPORTS_HOTPLUG_CPU ++ select SYS_HAS_CPU_CAVIUM_OCTEON ++ help ++ The Octeon simulator is software performance model of the Cavium ++ Octeon Processor. It supports simulating Octeon processors on x86 ++ hardware. + -+struct ag71xx_debug { -+ struct dentry *debugfs_dir; -+ struct dentry *debugfs_int_stats; -+ struct dentry *debugfs_napi_stats; ++config CAVIUM_OCTEON_REFERENCE_BOARD ++ bool "Cavium Networks Octeon reference board" ++ select CEVT_R4K ++ select 64BIT_PHYS_ADDR ++ select DMA_COHERENT ++ select SYS_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_HIGHMEM ++ select SYS_SUPPORTS_HOTPLUG_CPU ++ select SYS_HAS_EARLY_PRINTK ++ select SYS_HAS_CPU_CAVIUM_OCTEON ++ select SWAP_IO_SPACE ++ select HW_HAS_PCI ++ select ARCH_SUPPORTS_MSI ++ select ZONE_DMA32 ++ select USB_ARCH_HAS_OHCI ++ select USB_ARCH_HAS_EHCI ++ help ++ This option supports all of the Octeon reference boards from Cavium ++ Networks. It builds a kernel that dynamically determines the Octeon ++ CPU type and supports all known board reference implementations. ++ Some of the supported boards are: ++ EBT3000 ++ EBH3000 ++ EBH3100 ++ Thunder ++ Kodama ++ Hikari ++ Say Y here for most Octeon reference boards. ++ ++endchoice ++ ++source "arch/mips/alchemy/Kconfig" ++source "arch/mips/ar71xx/Kconfig" ++source "arch/mips/ath79/Kconfig" ++source "arch/mips/bcm63xx/Kconfig" ++source "arch/mips/jazz/Kconfig" ++source "arch/mips/jz4740/Kconfig" ++source "arch/mips/lasat/Kconfig" ++source "arch/mips/pmc-sierra/Kconfig" ++source "arch/mips/powertv/Kconfig" ++source "arch/mips/sgi-ip27/Kconfig" ++source "arch/mips/sibyte/Kconfig" ++source "arch/mips/txx9/Kconfig" ++source "arch/mips/vr41xx/Kconfig" ++source "arch/mips/cavium-octeon/Kconfig" ++source "arch/mips/loongson/Kconfig" + -+ struct ag71xx_int_stats int_stats; -+ struct ag71xx_napi_stats napi_stats; -+}; ++endmenu + -+struct ag71xx { -+ void __iomem *mac_base; -+ void __iomem *mii_ctrl; ++config RWSEM_GENERIC_SPINLOCK ++ bool ++ default y + -+ spinlock_t lock; -+ struct platform_device *pdev; -+ struct net_device *dev; -+ struct napi_struct napi; -+ u32 msg_enable; ++config RWSEM_XCHGADD_ALGORITHM ++ bool + -+ struct ag71xx_ring rx_ring; -+ struct ag71xx_ring tx_ring; ++config ARCH_HAS_ILOG2_U32 ++ bool ++ default n + -+ struct mii_bus *mii_bus; -+ struct phy_device *phy_dev; ++config ARCH_HAS_ILOG2_U64 ++ bool ++ default n + -+ unsigned int link; -+ unsigned int speed; -+ int duplex; ++config ARCH_SUPPORTS_OPROFILE ++ bool ++ default y if !MIPS_MT_SMTC + -+ struct work_struct restart_work; -+ struct timer_list oom_timer; ++config GENERIC_FIND_NEXT_BIT ++ bool ++ default y + -+#ifdef CONFIG_AG71XX_DEBUG_FS -+ struct ag71xx_debug debug; -+#endif -+}; ++config GENERIC_FIND_BIT_LE ++ bool ++ default y + -+extern struct ethtool_ops ag71xx_ethtool_ops; -+void ag71xx_link_adjust(struct ag71xx *ag); ++config GENERIC_HWEIGHT ++ bool ++ default y + -+int ag71xx_mdio_driver_init(void) __init; -+void ag71xx_mdio_driver_exit(void); ++config GENERIC_CALIBRATE_DELAY ++ bool ++ default y + -+int ag71xx_phy_connect(struct ag71xx *ag); -+void ag71xx_phy_disconnect(struct ag71xx *ag); -+void ag71xx_phy_start(struct ag71xx *ag); -+void ag71xx_phy_stop(struct ag71xx *ag); ++config GENERIC_CLOCKEVENTS ++ bool ++ default y + -+static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag) -+{ -+ return ag->pdev->dev.platform_data; -+} ++config GENERIC_CMOS_UPDATE ++ bool ++ default y + -+static inline int ag71xx_desc_empty(struct ag71xx_desc *desc) -+{ -+ return ((desc->ctrl & DESC_EMPTY) != 0); -+} ++config SCHED_OMIT_FRAME_POINTER ++ bool ++ default y + -+static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc) -+{ -+ return (desc->ctrl & DESC_PKTLEN_M); -+} ++# ++# Select some configuration options automatically based on user selections. ++# ++config ARC ++ bool + -+/* Register offsets */ -+#define AG71XX_REG_MAC_CFG1 0x0000 -+#define AG71XX_REG_MAC_CFG2 0x0004 -+#define AG71XX_REG_MAC_IPG 0x0008 -+#define AG71XX_REG_MAC_HDX 0x000c -+#define AG71XX_REG_MAC_MFL 0x0010 -+#define AG71XX_REG_MII_CFG 0x0020 -+#define AG71XX_REG_MII_CMD 0x0024 -+#define AG71XX_REG_MII_ADDR 0x0028 -+#define AG71XX_REG_MII_CTRL 0x002c -+#define AG71XX_REG_MII_STATUS 0x0030 -+#define AG71XX_REG_MII_IND 0x0034 -+#define AG71XX_REG_MAC_IFCTL 0x0038 -+#define AG71XX_REG_MAC_ADDR1 0x0040 -+#define AG71XX_REG_MAC_ADDR2 0x0044 -+#define AG71XX_REG_FIFO_CFG0 0x0048 -+#define AG71XX_REG_FIFO_CFG1 0x004c -+#define AG71XX_REG_FIFO_CFG2 0x0050 -+#define AG71XX_REG_FIFO_CFG3 0x0054 -+#define AG71XX_REG_FIFO_CFG4 0x0058 -+#define AG71XX_REG_FIFO_CFG5 0x005c -+#define AG71XX_REG_FIFO_RAM0 0x0060 -+#define AG71XX_REG_FIFO_RAM1 0x0064 -+#define AG71XX_REG_FIFO_RAM2 0x0068 -+#define AG71XX_REG_FIFO_RAM3 0x006c -+#define AG71XX_REG_FIFO_RAM4 0x0070 -+#define AG71XX_REG_FIFO_RAM5 0x0074 -+#define AG71XX_REG_FIFO_RAM6 0x0078 -+#define AG71XX_REG_FIFO_RAM7 0x007c ++config ARCH_MAY_HAVE_PC_FDC ++ bool + -+#define AG71XX_REG_TX_CTRL 0x0180 -+#define AG71XX_REG_TX_DESC 0x0184 -+#define AG71XX_REG_TX_STATUS 0x0188 -+#define AG71XX_REG_RX_CTRL 0x018c -+#define AG71XX_REG_RX_DESC 0x0190 -+#define AG71XX_REG_RX_STATUS 0x0194 -+#define AG71XX_REG_INT_ENABLE 0x0198 -+#define AG71XX_REG_INT_STATUS 0x019c ++config BOOT_RAW ++ bool + -+#define MAC_CFG1_TXE BIT(0) /* Tx Enable */ -+#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */ -+#define MAC_CFG1_RXE BIT(2) /* Rx Enable */ -+#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */ -+#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */ -+#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */ -+#define MAC_CFG1_LB BIT(8) /* Loopback mode */ -+#define MAC_CFG1_SR BIT(31) /* Soft Reset */ ++config CEVT_BCM1480 ++ bool + -+#define MAC_CFG2_FDX BIT(0) -+#define MAC_CFG2_CRC_EN BIT(1) -+#define MAC_CFG2_PAD_CRC_EN BIT(2) -+#define MAC_CFG2_LEN_CHECK BIT(4) -+#define MAC_CFG2_HUGE_FRAME_EN BIT(5) -+#define MAC_CFG2_IF_1000 BIT(9) -+#define MAC_CFG2_IF_10_100 BIT(8) ++config CEVT_DS1287 ++ bool + -+#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */ -+#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */ -+#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */ -+#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */ -+#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */ -+#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \ -+ | FIFO_CFG0_TXS | FIFO_CFG0_TXF) ++config CEVT_GT641XX ++ bool + -+#define FIFO_CFG0_ENABLE_SHIFT 8 ++config CEVT_R4K_LIB ++ bool + -+#define FIFO_CFG4_DE BIT(0) /* Drop Event */ -+#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */ -+#define FIFO_CFG4_FC BIT(2) /* False Carrier */ -+#define FIFO_CFG4_CE BIT(3) /* Code Error */ -+#define FIFO_CFG4_CR BIT(4) /* CRC error */ -+#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */ -+#define FIFO_CFG4_LO BIT(6) /* Length out of range */ -+#define FIFO_CFG4_OK BIT(7) /* Packet is OK */ -+#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */ -+#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */ -+#define FIFO_CFG4_DR BIT(10) /* Dribble */ -+#define FIFO_CFG4_LE BIT(11) /* Long Event */ -+#define FIFO_CFG4_CF BIT(12) /* Control Frame */ -+#define FIFO_CFG4_PF BIT(13) /* Pause Frame */ -+#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */ -+#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */ -+#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */ -+#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */ ++config CEVT_R4K ++ select CEVT_R4K_LIB ++ bool + -+#define FIFO_CFG5_DE BIT(0) /* Drop Event */ -+#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */ -+#define FIFO_CFG5_FC BIT(2) /* False Carrier */ -+#define FIFO_CFG5_CE BIT(3) /* Code Error */ -+#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */ -+#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */ -+#define FIFO_CFG5_OK BIT(6) /* Packet is OK */ -+#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */ -+#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */ -+#define FIFO_CFG5_DR BIT(9) /* Dribble */ -+#define FIFO_CFG5_CF BIT(10) /* Control Frame */ -+#define FIFO_CFG5_PF BIT(11) /* Pause Frame */ -+#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */ -+#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */ -+#define FIFO_CFG5_LE BIT(14) /* Long Event */ -+#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */ -+#define FIFO_CFG5_16 BIT(16) /* unknown */ -+#define FIFO_CFG5_17 BIT(17) /* unknown */ -+#define FIFO_CFG5_SF BIT(18) /* Short Frame */ -+#define FIFO_CFG5_BM BIT(19) /* Byte Mode */ ++config CEVT_SB1250 ++ bool + -+#define AG71XX_INT_TX_PS BIT(0) -+#define AG71XX_INT_TX_UR BIT(1) -+#define AG71XX_INT_TX_BE BIT(3) -+#define AG71XX_INT_RX_PR BIT(4) -+#define AG71XX_INT_RX_OF BIT(6) -+#define AG71XX_INT_RX_BE BIT(7) ++config CEVT_TXX9 ++ bool + -+#define MAC_IFCTL_SPEED BIT(16) ++config CSRC_BCM1480 ++ bool + -+#define MII_CFG_CLK_DIV_4 0 -+#define MII_CFG_CLK_DIV_6 2 -+#define MII_CFG_CLK_DIV_8 3 -+#define MII_CFG_CLK_DIV_10 4 -+#define MII_CFG_CLK_DIV_14 5 -+#define MII_CFG_CLK_DIV_20 6 -+#define MII_CFG_CLK_DIV_28 7 -+#define MII_CFG_RESET BIT(31) ++config CSRC_IOASIC ++ bool + -+#define MII_CMD_WRITE 0x0 -+#define MII_CMD_READ 0x1 -+#define MII_ADDR_SHIFT 8 -+#define MII_IND_BUSY BIT(0) -+#define MII_IND_INVALID BIT(2) ++config CSRC_POWERTV ++ bool + -+#define TX_CTRL_TXE BIT(0) /* Tx Enable */ ++config CSRC_R4K_LIB ++ bool + -+#define TX_STATUS_PS BIT(0) /* Packet Sent */ -+#define TX_STATUS_UR BIT(1) /* Tx Underrun */ -+#define TX_STATUS_BE BIT(3) /* Bus Error */ ++config CSRC_R4K ++ select CSRC_R4K_LIB ++ bool + -+#define RX_CTRL_RXE BIT(0) /* Rx Enable */ ++config CSRC_SB1250 ++ bool + -+#define RX_STATUS_PR BIT(0) /* Packet Received */ -+#define RX_STATUS_OF BIT(2) /* Rx Overflow */ -+#define RX_STATUS_BE BIT(3) /* Bus Error */ ++config GPIO_TXX9 ++ select GENERIC_GPIO ++ select ARCH_REQUIRE_GPIOLIB ++ bool + -+#define MII_CTRL_IF_MASK 3 -+#define MII_CTRL_SPEED_SHIFT 4 -+#define MII_CTRL_SPEED_MASK 3 -+#define MII_CTRL_SPEED_10 0 -+#define MII_CTRL_SPEED_100 1 -+#define MII_CTRL_SPEED_1000 2 ++config CFE ++ bool + -+static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg) -+{ -+ switch (reg) { -+ case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: -+ case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: -+ break; ++config ARCH_DMA_ADDR_T_64BIT ++ def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT + -+ default: -+ BUG(); -+ } -+} ++config DMA_COHERENT ++ bool + -+static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) -+{ -+ ag71xx_check_reg_offset(ag, reg); ++config DMA_NONCOHERENT ++ bool ++ select NEED_DMA_MAP_STATE + -+ __raw_writel(value, ag->mac_base + reg); -+ /* flush write */ -+ (void) __raw_readl(ag->mac_base + reg); -+} ++config NEED_DMA_MAP_STATE ++ bool + -+static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) -+{ -+ ag71xx_check_reg_offset(ag, reg); ++config SYS_HAS_EARLY_PRINTK ++ bool + -+ return __raw_readl(ag->mac_base + reg); -+} ++config HOTPLUG_CPU ++ bool "Support for hot-pluggable CPUs" ++ depends on SMP && HOTPLUG && SYS_SUPPORTS_HOTPLUG_CPU ++ help ++ Say Y here to allow turning CPUs off and on. CPUs can be ++ controlled through /sys/devices/system/cpu. ++ (Note: power management support will enable this option ++ automatically on SMP systems. ) ++ Say N if you want to disable CPU hotplug. + -+static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) -+{ -+ void __iomem *r; ++config SYS_SUPPORTS_HOTPLUG_CPU ++ bool + -+ ag71xx_check_reg_offset(ag, reg); ++config I8259 ++ bool + -+ r = ag->mac_base + reg; -+ __raw_writel(__raw_readl(r) | mask, r); -+ /* flush write */ -+ (void)__raw_readl(r); -+} ++config MIPS_BONITO64 ++ bool + -+static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) -+{ -+ void __iomem *r; ++config MIPS_MSC ++ bool + -+ ag71xx_check_reg_offset(ag, reg); ++config MIPS_NILE4 ++ bool + -+ r = ag->mac_base + reg; -+ __raw_writel(__raw_readl(r) & ~mask, r); -+ /* flush write */ -+ (void) __raw_readl(r); -+} ++config MIPS_DISABLE_OBSOLETE_IDE ++ bool + -+static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) -+{ -+ ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints); -+} ++config SYNC_R4K ++ bool + -+static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints) -+{ -+ ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints); -+} ++config MIPS_MACHINE ++ def_bool n + -+static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++config NO_IOPORT ++ def_bool n + -+ if (pdata->is_ar724x) -+ return; ++config GENERIC_ISA_DMA ++ bool ++ select ZONE_DMA if GENERIC_ISA_DMA_SUPPORT_BROKEN=n ++ select ISA_DMA_API + -+ __raw_writel(value, ag->mii_ctrl); ++config GENERIC_ISA_DMA_SUPPORT_BROKEN ++ bool ++ select GENERIC_ISA_DMA + -+ /* flush write */ -+ __raw_readl(ag->mii_ctrl); -+} ++config ISA_DMA_API ++ bool + -+static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++config GENERIC_GPIO ++ bool + -+ if (pdata->is_ar724x) -+ return 0xffffffff; ++# ++# Endianess selection. Sufficiently obscure so many users don't know what to ++# answer,so we try hard to limit the available choices. Also the use of a ++# choice statement should be more obvious to the user. ++# ++choice ++ prompt "Endianess selection" ++ help ++ Some MIPS machines can be configured for either little or big endian ++ byte order. These modes require different kernels and a different ++ Linux distribution. In general there is one preferred byteorder for a ++ particular system but some systems are just as commonly used in the ++ one or the other endianness. ++ ++config CPU_BIG_ENDIAN ++ bool "Big endian" ++ depends on SYS_SUPPORTS_BIG_ENDIAN ++ ++config CPU_LITTLE_ENDIAN ++ bool "Little endian" ++ depends on SYS_SUPPORTS_LITTLE_ENDIAN ++ help + -+ return __raw_readl(ag->mii_ctrl); -+} ++endchoice + -+static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag, -+ unsigned int mii_if) -+{ -+ u32 t; ++config EXPORT_UASM ++ bool + -+ t = ag71xx_mii_ctrl_rr(ag); -+ t &= ~(MII_CTRL_IF_MASK); -+ t |= (mii_if & MII_CTRL_IF_MASK); -+ ag71xx_mii_ctrl_wr(ag, t); -+} ++config SYS_SUPPORTS_APM_EMULATION ++ bool + -+static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag, -+ unsigned int speed) -+{ -+ u32 t; ++config SYS_SUPPORTS_BIG_ENDIAN ++ bool + -+ t = ag71xx_mii_ctrl_rr(ag); -+ t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT); -+ t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT; -+ ag71xx_mii_ctrl_wr(ag, t); -+} ++config SYS_SUPPORTS_LITTLE_ENDIAN ++ bool + -+#ifdef CONFIG_AG71XX_AR8216_SUPPORT -+void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); -+int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, -+ int pktlen); -+static inline int ag71xx_has_ar8216(struct ag71xx *ag) -+{ -+ return ag71xx_get_pdata(ag)->has_ar8216; -+} -+#else -+static inline void ag71xx_add_ar8216_header(struct ag71xx *ag, -+ struct sk_buff *skb) -+{ -+} ++config SYS_SUPPORTS_HUGETLBFS ++ bool ++ depends on CPU_SUPPORTS_HUGEPAGES && 64BIT ++ default y + -+static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag, -+ struct sk_buff *skb, -+ int pktlen) -+{ -+ return 0; -+} -+static inline int ag71xx_has_ar8216(struct ag71xx *ag) -+{ -+ return 0; -+} -+#endif ++config IRQ_CPU ++ bool + -+#ifdef CONFIG_AG71XX_DEBUG_FS -+int ag71xx_debugfs_root_init(void); -+void ag71xx_debugfs_root_exit(void); -+int ag71xx_debugfs_init(struct ag71xx *ag); -+void ag71xx_debugfs_exit(struct ag71xx *ag); -+void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status); -+void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx); -+#else -+static inline int ag71xx_debugfs_root_init(void) { return 0; } -+static inline void ag71xx_debugfs_root_exit(void) {} -+static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; } -+static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {} -+static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, -+ u32 status) {} -+static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, -+ int rx, int tx) {} -+#endif /* CONFIG_AG71XX_DEBUG_FS */ ++config IRQ_CPU_RM7K ++ bool + -+#endif /* _AG71XX_H */ -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar8216.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ar8216.c ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar8216.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ar8216.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,44 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * Special support for the Atheros ar8216 switch chip -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++config IRQ_CPU_RM9K ++ bool + -+#include "ag71xx.h" ++config IRQ_MSP_SLP ++ bool + -+#define AR8216_PACKET_TYPE_MASK 0xf -+#define AR8216_PACKET_TYPE_NORMAL 0 ++config IRQ_MSP_CIC ++ bool + -+#define AR8216_HEADER_LEN 2 ++config IRQ_TXX9 ++ bool + -+void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb) -+{ -+ skb_push(skb, AR8216_HEADER_LEN); -+ skb->data[0] = 0x10; -+ skb->data[1] = 0x80; -+} ++config IRQ_GT641XX ++ bool + -+int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, -+ int pktlen) -+{ -+ u8 type; ++config IRQ_GIC ++ bool + -+ type = skb->data[1] & AR8216_PACKET_TYPE_MASK; -+ switch (type) { -+ case AR8216_PACKET_TYPE_NORMAL: -+ break; ++config MIPS_BOARDS_GEN ++ bool + -+ default: -+ return -EINVAL; -+ } ++config PCI_GT64XXX_PCI0 ++ bool + -+ skb_pull(skb, AR8216_HEADER_LEN); -+ return 0; -+} -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_debugfs.c linux-2.6.39/drivers/net/ag71xx/ag71xx_debugfs.c ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_debugfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_debugfs.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,197 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++config NO_EXCEPT_FILL ++ bool + -+#include ++config MIPS_RM9122 ++ bool ++ select SERIAL_RM9000 + -+#include "ag71xx.h" ++config SOC_EMMA2RH ++ bool ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select IRQ_CPU ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_R5500 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN + -+static struct dentry *ag71xx_debugfs_root; ++config SOC_PNX833X ++ bool ++ select CEVT_R4K ++ select CSRC_R4K ++ select IRQ_CPU ++ select DMA_NONCOHERENT ++ select SYS_HAS_CPU_MIPS32_R2 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select GENERIC_GPIO ++ select CPU_MIPSR2_IRQ_VI + -+static int ag71xx_debugfs_generic_open(struct inode *inode, struct file *file) -+{ -+ file->private_data = inode->i_private; -+ return 0; -+} ++config SOC_PNX8335 ++ bool ++ select SOC_PNX833X + -+void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status) -+{ -+ if (status) -+ ag->debug.int_stats.total++; -+ if (status & AG71XX_INT_TX_PS) -+ ag->debug.int_stats.tx_ps++; -+ if (status & AG71XX_INT_TX_UR) -+ ag->debug.int_stats.tx_ur++; -+ if (status & AG71XX_INT_TX_BE) -+ ag->debug.int_stats.tx_be++; -+ if (status & AG71XX_INT_RX_PR) -+ ag->debug.int_stats.rx_pr++; -+ if (status & AG71XX_INT_RX_OF) -+ ag->debug.int_stats.rx_of++; -+ if (status & AG71XX_INT_RX_BE) -+ ag->debug.int_stats.rx_be++; -+} ++config PNX8550 ++ bool ++ select SOC_PNX8550 + -+static ssize_t read_file_int_stats(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+#define PR_INT_STAT(_label, _field) \ -+ len += snprintf(buf + len, sizeof(buf) - len, \ -+ "%20s: %10lu\n", _label, ag->debug.int_stats._field); ++config SOC_PNX8550 ++ bool ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_EARLY_PRINTK ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select GENERIC_GPIO + -+ struct ag71xx *ag = file->private_data; -+ char buf[256]; -+ unsigned int len = 0; ++config SWAP_IO_SPACE ++ bool + -+ PR_INT_STAT("TX Packet Sent", tx_ps); -+ PR_INT_STAT("TX Underrun", tx_ur); -+ PR_INT_STAT("TX Bus Error", tx_be); -+ PR_INT_STAT("RX Packet Received", rx_pr); -+ PR_INT_STAT("RX Overflow", rx_of); -+ PR_INT_STAT("RX Bus Error", rx_be); -+ len += snprintf(buf + len, sizeof(buf) - len, "\n"); -+ PR_INT_STAT("Total", total); ++config SERIAL_RM9000 ++ bool + -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+#undef PR_INT_STAT -+} ++config SGI_HAS_INDYDOG ++ bool + -+static const struct file_operations ag71xx_fops_int_stats = { -+ .open = ag71xx_debugfs_generic_open, -+ .read = read_file_int_stats, -+ .owner = THIS_MODULE -+}; ++config SGI_HAS_HAL2 ++ bool + -+void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx) -+{ -+ struct ag71xx_napi_stats *stats = &ag->debug.napi_stats; ++config SGI_HAS_SEEQ ++ bool + -+ if (rx) { -+ stats->rx_count++; -+ stats->rx_packets += rx; -+ if (rx <= AG71XX_NAPI_WEIGHT) -+ stats->rx[rx]++; -+ if (rx > stats->rx_packets_max) -+ stats->rx_packets_max = rx; -+ } ++config SGI_HAS_WD93 ++ bool + -+ if (tx) { -+ stats->tx_count++; -+ stats->tx_packets += tx; -+ if (tx <= AG71XX_NAPI_WEIGHT) -+ stats->tx[tx]++; -+ if (tx > stats->tx_packets_max) -+ stats->tx_packets_max = tx; -+ } -+} ++config SGI_HAS_ZILOG ++ bool + -+static ssize_t read_file_napi_stats(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ag71xx *ag = file->private_data; -+ struct ag71xx_napi_stats *stats = &ag->debug.napi_stats; -+ char buf[2048]; -+ unsigned int len = 0; -+ unsigned long rx_avg = 0; -+ unsigned long tx_avg = 0; -+ int i; ++config SGI_HAS_I8042 ++ bool + -+ if (stats->rx_count) -+ rx_avg = stats->rx_packets / stats->rx_count; ++config DEFAULT_SGI_PARTITION ++ bool + -+ if (stats->tx_count) -+ tx_avg = stats->tx_packets / stats->tx_count; ++config ARC32 ++ bool + -+ len += snprintf(buf + len, sizeof(buf) - len, "%3s %10s %10s\n", -+ "len", "rx", "tx"); ++config SNIPROM ++ bool + -+ for (i = 1; i <= AG71XX_NAPI_WEIGHT; i++) -+ len += snprintf(buf + len, sizeof(buf) - len, -+ "%3d: %10lu %10lu\n", -+ i, stats->rx[i], stats->tx[i]); ++config BOOT_ELF32 ++ bool + -+ len += snprintf(buf + len, sizeof(buf) - len, "\n"); ++config MIPS_L1_CACHE_SHIFT ++ int ++ default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL ++ default "6" if MIPS_CPU_SCACHE ++ default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON ++ default "5" + -+ len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n", -+ "sum", stats->rx_count, stats->tx_count); -+ len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n", -+ "avg", rx_avg, tx_avg); -+ len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n", -+ "max", stats->rx_packets_max, stats->tx_packets_max); -+ len += snprintf(buf + len, sizeof(buf) - len, "%3s: %10lu %10lu\n", -+ "pkt", stats->rx_packets, stats->tx_packets); ++config HAVE_STD_PC_SERIAL_PORT ++ bool + -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+} ++config ARC_CONSOLE ++ bool "ARC console support" ++ depends on SGI_IP22 || SGI_IP28 || (SNI_RM && CPU_LITTLE_ENDIAN) + -+static const struct file_operations ag71xx_fops_napi_stats = { -+ .open = ag71xx_debugfs_generic_open, -+ .read = read_file_napi_stats, -+ .owner = THIS_MODULE -+}; ++config ARC_MEMORY ++ bool ++ depends on MACH_JAZZ || SNI_RM || SGI_IP32 ++ default y + -+void ag71xx_debugfs_exit(struct ag71xx *ag) -+{ -+ debugfs_remove(ag->debug.debugfs_napi_stats); -+ debugfs_remove(ag->debug.debugfs_int_stats); -+ debugfs_remove(ag->debug.debugfs_dir); -+} ++config ARC_PROMLIB ++ bool ++ depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP28 || SGI_IP32 ++ default y + -+int ag71xx_debugfs_init(struct ag71xx *ag) -+{ -+ ag->debug.debugfs_dir = debugfs_create_dir(ag->dev->name, -+ ag71xx_debugfs_root); -+ if (!ag->debug.debugfs_dir) -+ goto err; ++config ARC64 ++ bool + -+ ag->debug.debugfs_int_stats = -+ debugfs_create_file("int_stats", -+ S_IRUGO, -+ ag->debug.debugfs_dir, -+ ag, -+ &ag71xx_fops_int_stats); -+ if (!ag->debug.debugfs_int_stats) -+ goto err; ++config BOOT_ELF64 ++ bool + -+ ag->debug.debugfs_napi_stats = -+ debugfs_create_file("napi_stats", -+ S_IRUGO, -+ ag->debug.debugfs_dir, -+ ag, -+ &ag71xx_fops_napi_stats); -+ if (!ag->debug.debugfs_napi_stats) -+ goto err; ++menu "CPU selection" + -+ return 0; ++choice ++ prompt "CPU type" ++ default CPU_R4X00 + -+ err: -+ ag71xx_debugfs_exit(ag); -+ return -ENOMEM; -+} ++config CPU_LOONGSON2E ++ bool "Loongson 2E" ++ depends on SYS_HAS_CPU_LOONGSON2E ++ select CPU_LOONGSON2 ++ help ++ The Loongson 2E processor implements the MIPS III instruction set ++ with many extensions. + -+int ag71xx_debugfs_root_init(void) -+{ -+ if (ag71xx_debugfs_root) -+ return -EBUSY; ++ It has an internal FPGA northbridge, which is compatible to ++ bonito64. + -+ ag71xx_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); -+ if (!ag71xx_debugfs_root) -+ return -ENOENT; ++config CPU_LOONGSON2F ++ bool "Loongson 2F" ++ depends on SYS_HAS_CPU_LOONGSON2F ++ select CPU_LOONGSON2 ++ select GENERIC_GPIO ++ select ARCH_REQUIRE_GPIOLIB ++ help ++ The Loongson 2F processor implements the MIPS III instruction set ++ with many extensions. ++ ++ Loongson2F have built-in DDR2 and PCIX controller. The PCIX controller ++ have a similar programming interface with FPGA northbridge used in ++ Loongson2E. ++ ++config CPU_MIPS32_R1 ++ bool "MIPS32 Release 1" ++ depends on SYS_HAS_CPU_MIPS32_R1 ++ select CPU_HAS_PREFETCH ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ help ++ Choose this option to build a kernel for release 1 or later of the ++ MIPS32 architecture. Most modern embedded systems with a 32-bit ++ MIPS processor are based on a MIPS32 processor. If you know the ++ specific type of processor in your system, choose those that one ++ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system. ++ Release 2 of the MIPS32 architecture is available since several ++ years so chances are you even have a MIPS32 Release 2 processor ++ in which case you should choose CPU_MIPS32_R2 instead for better ++ performance. ++ ++config CPU_MIPS32_R2 ++ bool "MIPS32 Release 2" ++ depends on SYS_HAS_CPU_MIPS32_R2 ++ select CPU_HAS_PREFETCH ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ help ++ Choose this option to build a kernel for release 2 or later of the ++ MIPS32 architecture. Most modern embedded systems with a 32-bit ++ MIPS processor are based on a MIPS32 processor. If you know the ++ specific type of processor in your system, choose those that one ++ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system. ++ ++config CPU_MIPS64_R1 ++ bool "MIPS64 Release 1" ++ depends on SYS_HAS_CPU_MIPS64_R1 ++ select CPU_HAS_PREFETCH ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ select CPU_SUPPORTS_HUGEPAGES ++ help ++ Choose this option to build a kernel for release 1 or later of the ++ MIPS64 architecture. Many modern embedded systems with a 64-bit ++ MIPS processor are based on a MIPS64 processor. If you know the ++ specific type of processor in your system, choose those that one ++ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system. ++ Release 2 of the MIPS64 architecture is available since several ++ years so chances are you even have a MIPS64 Release 2 processor ++ in which case you should choose CPU_MIPS64_R2 instead for better ++ performance. ++ ++config CPU_MIPS64_R2 ++ bool "MIPS64 Release 2" ++ depends on SYS_HAS_CPU_MIPS64_R2 ++ select CPU_HAS_PREFETCH ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ select CPU_SUPPORTS_HUGEPAGES ++ help ++ Choose this option to build a kernel for release 2 or later of the ++ MIPS64 architecture. Many modern embedded systems with a 64-bit ++ MIPS processor are based on a MIPS64 processor. If you know the ++ specific type of processor in your system, choose those that one ++ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system. ++ ++config CPU_R3000 ++ bool "R3000" ++ depends on SYS_HAS_CPU_R3000 ++ select CPU_HAS_WB ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ help ++ Please make sure to pick the right CPU type. Linux/MIPS is not ++ designed to be generic, i.e. Kernels compiled for R3000 CPUs will ++ *not* work on R4000 machines and vice versa. However, since most ++ of the supported machines have an R4000 (or similar) CPU, R4x00 ++ might be a safe bet. If the resulting kernel does not work, ++ try to recompile with R3000. ++ ++config CPU_TX39XX ++ bool "R39XX" ++ depends on SYS_HAS_CPU_TX39XX ++ select CPU_SUPPORTS_32BIT_KERNEL ++ ++config CPU_VR41XX ++ bool "R41xx" ++ depends on SYS_HAS_CPU_VR41XX ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ help ++ The options selects support for the NEC VR4100 series of processors. ++ Only choose this option if you have one of these processors as a ++ kernel built with this option will not run on any other type of ++ processor or vice versa. ++ ++config CPU_R4300 ++ bool "R4300" ++ depends on SYS_HAS_CPU_R4300 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ help ++ MIPS Technologies R4300-series processors. + -+ return 0; -+} ++config CPU_R4X00 ++ bool "R4x00" ++ depends on SYS_HAS_CPU_R4X00 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ help ++ MIPS Technologies R4000-series processors other than 4300, including ++ the R4000, R4400, R4600, and 4700. ++ ++config CPU_TX49XX ++ bool "R49XX" ++ depends on SYS_HAS_CPU_TX49XX ++ select CPU_HAS_PREFETCH ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ ++config CPU_R5000 ++ bool "R5000" ++ depends on SYS_HAS_CPU_R5000 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ help ++ MIPS Technologies R5000-series processors other than the Nevada. ++ ++config CPU_R5432 ++ bool "R5432" ++ depends on SYS_HAS_CPU_R5432 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ ++config CPU_R5500 ++ bool "R5500" ++ depends on SYS_HAS_CPU_R5500 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ select CPU_SUPPORTS_HUGEPAGES ++ help ++ NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV ++ instruction set. ++ ++config CPU_R6000 ++ bool "R6000" ++ depends on EXPERIMENTAL ++ depends on SYS_HAS_CPU_R6000 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ help ++ MIPS Technologies R6000 and R6000A series processors. Note these ++ processors are extremely rare and the support for them is incomplete. ++ ++config CPU_NEVADA ++ bool "RM52xx" ++ depends on SYS_HAS_CPU_NEVADA ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ help ++ QED / PMC-Sierra RM52xx-series ("Nevada") processors. ++ ++config CPU_R8000 ++ bool "R8000" ++ depends on EXPERIMENTAL ++ depends on SYS_HAS_CPU_R8000 ++ select CPU_HAS_PREFETCH ++ select CPU_SUPPORTS_64BIT_KERNEL ++ help ++ MIPS Technologies R8000 processors. Note these processors are ++ uncommon and the support for them is incomplete. ++ ++config CPU_R10000 ++ bool "R10000" ++ depends on SYS_HAS_CPU_R10000 ++ select CPU_HAS_PREFETCH ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ help ++ MIPS Technologies R10000-series processors. ++ ++config CPU_RM7000 ++ bool "RM7000" ++ depends on SYS_HAS_CPU_RM7000 ++ select CPU_HAS_PREFETCH ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ ++config CPU_RM9000 ++ bool "RM9000" ++ depends on SYS_HAS_CPU_RM9000 ++ select CPU_HAS_PREFETCH ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ select WEAK_ORDERING ++ ++config CPU_SB1 ++ bool "SB1" ++ depends on SYS_HAS_CPU_SB1 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ select WEAK_ORDERING ++ ++config CPU_CAVIUM_OCTEON ++ bool "Cavium Octeon processor" ++ depends on SYS_HAS_CPU_CAVIUM_OCTEON ++ select CPU_HAS_PREFETCH ++ select CPU_SUPPORTS_64BIT_KERNEL ++ select SYS_SUPPORTS_SMP ++ select NR_CPUS_DEFAULT_16 ++ select WEAK_ORDERING ++ select CPU_SUPPORTS_HIGHMEM ++ select CPU_SUPPORTS_HUGEPAGES ++ help ++ The Cavium Octeon processor is a highly integrated chip containing ++ many ethernet hardware widgets for networking tasks. The processor ++ can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets. ++ Full details can be found at http://www.caviumnetworks.com. ++ ++config CPU_BMIPS3300 ++ bool "BMIPS3300" ++ depends on SYS_HAS_CPU_BMIPS3300 ++ select DMA_NONCOHERENT ++ select IRQ_CPU ++ select SWAP_IO_SPACE ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select WEAK_ORDERING ++ help ++ Broadcom BMIPS3300 processors. + -+void ag71xx_debugfs_root_exit(void) -+{ -+ debugfs_remove(ag71xx_debugfs_root); -+ ag71xx_debugfs_root = NULL; -+} -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ethtool.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ethtool.c ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ethtool.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ethtool.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,71 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++config CPU_BMIPS4350 ++ bool "BMIPS4350" ++ depends on SYS_HAS_CPU_BMIPS4350 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select DMA_NONCOHERENT ++ select IRQ_CPU ++ select SWAP_IO_SPACE ++ select SYS_SUPPORTS_SMP ++ select SYS_SUPPORTS_HOTPLUG_CPU ++ select WEAK_ORDERING ++ help ++ Broadcom BMIPS4350 ("VIPER") processors. + -+#include "ag71xx.h" ++config CPU_BMIPS4380 ++ bool "BMIPS4380" ++ depends on SYS_HAS_CPU_BMIPS4380 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select DMA_NONCOHERENT ++ select IRQ_CPU ++ select SWAP_IO_SPACE ++ select SYS_SUPPORTS_SMP ++ select SYS_SUPPORTS_HOTPLUG_CPU ++ select WEAK_ORDERING ++ help ++ Broadcom BMIPS4380 processors. + -+static int ag71xx_ethtool_get_settings(struct net_device *dev, -+ struct ethtool_cmd *cmd) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct phy_device *phydev = ag->phy_dev; ++config CPU_BMIPS5000 ++ bool "BMIPS5000" ++ depends on SYS_HAS_CPU_BMIPS5000 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ select DMA_NONCOHERENT ++ select IRQ_CPU ++ select SWAP_IO_SPACE ++ select SYS_SUPPORTS_SMP ++ select SYS_SUPPORTS_HOTPLUG_CPU ++ select WEAK_ORDERING ++ help ++ Broadcom BMIPS5000 processors. + -+ if (!phydev) -+ return -ENODEV; ++endchoice + -+ return phy_ethtool_gset(phydev, cmd); -+} ++if CPU_LOONGSON2F ++config CPU_NOP_WORKAROUNDS ++ bool + -+static int ag71xx_ethtool_set_settings(struct net_device *dev, -+ struct ethtool_cmd *cmd) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct phy_device *phydev = ag->phy_dev; ++config CPU_JUMP_WORKAROUNDS ++ bool + -+ if (!phydev) -+ return -ENODEV; ++config CPU_LOONGSON2F_WORKAROUNDS ++ bool "Loongson 2F Workarounds" ++ default y ++ select CPU_NOP_WORKAROUNDS ++ select CPU_JUMP_WORKAROUNDS ++ help ++ Loongson 2F01 / 2F02 processors have the NOP & JUMP issues which ++ require workarounds. Without workarounds the system may hang ++ unexpectedly. For more information please refer to the gas ++ -mfix-loongson2f-nop and -mfix-loongson2f-jump options. + -+ return phy_ethtool_sset(phydev, cmd); -+} ++ Loongson 2F03 and later have fixed these issues and no workarounds ++ are needed. The workarounds have no significant side effect on them ++ but may decrease the performance of the system so this option should ++ be disabled unless the kernel is intended to be run on 2F01 or 2F02 ++ systems. + -+static void ag71xx_ethtool_get_drvinfo(struct net_device *dev, -+ struct ethtool_drvinfo *info) -+{ -+ struct ag71xx *ag = netdev_priv(dev); ++ If unsure, please say Y. ++endif # CPU_LOONGSON2F + -+ strcpy(info->driver, ag->pdev->dev.driver->name); -+ strcpy(info->version, AG71XX_DRV_VERSION); -+ strcpy(info->bus_info, dev_name(&ag->pdev->dev)); -+} ++config SYS_SUPPORTS_ZBOOT ++ bool ++ select HAVE_KERNEL_GZIP ++ select HAVE_KERNEL_BZIP2 ++ select HAVE_KERNEL_LZMA ++ select HAVE_KERNEL_LZO + -+static u32 ag71xx_ethtool_get_msglevel(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); ++config SYS_SUPPORTS_ZBOOT_UART16550 ++ bool ++ select SYS_SUPPORTS_ZBOOT + -+ return ag->msg_enable; -+} ++config CPU_LOONGSON2 ++ bool ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_64BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM + -+static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level) -+{ -+ struct ag71xx *ag = netdev_priv(dev); ++config SYS_HAS_CPU_LOONGSON2E ++ bool + -+ ag->msg_enable = msg_level; -+} ++config SYS_HAS_CPU_LOONGSON2F ++ bool ++ select CPU_SUPPORTS_CPUFREQ ++ select CPU_SUPPORTS_ADDRWINCFG if 64BIT ++ select CPU_SUPPORTS_UNCACHED_ACCELERATED + -+struct ethtool_ops ag71xx_ethtool_ops = { -+ .set_settings = ag71xx_ethtool_set_settings, -+ .get_settings = ag71xx_ethtool_get_settings, -+ .get_drvinfo = ag71xx_ethtool_get_drvinfo, -+ .get_msglevel = ag71xx_ethtool_get_msglevel, -+ .set_msglevel = ag71xx_ethtool_set_msglevel, -+ .get_link = ethtool_op_get_link, -+}; -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,1184 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++config SYS_HAS_CPU_MIPS32_R1 ++ bool + -+#include "ag71xx.h" ++config SYS_HAS_CPU_MIPS32_R2 ++ bool + -+#define AG71XX_DEFAULT_MSG_ENABLE \ -+ ( NETIF_MSG_DRV \ -+ | NETIF_MSG_PROBE \ -+ | NETIF_MSG_LINK \ -+ | NETIF_MSG_TIMER \ -+ | NETIF_MSG_IFDOWN \ -+ | NETIF_MSG_IFUP \ -+ | NETIF_MSG_RX_ERR \ -+ | NETIF_MSG_TX_ERR ) ++config SYS_HAS_CPU_MIPS64_R1 ++ bool + -+static int ag71xx_msg_level = -1; ++config SYS_HAS_CPU_MIPS64_R2 ++ bool + -+module_param_named(msg_level, ag71xx_msg_level, int, 0); -+MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)"); ++config SYS_HAS_CPU_R3000 ++ bool + -+static void ag71xx_dump_dma_regs(struct ag71xx *ag) -+{ -+ DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_TX_CTRL), -+ ag71xx_rr(ag, AG71XX_REG_TX_DESC), -+ ag71xx_rr(ag, AG71XX_REG_TX_STATUS)); ++config SYS_HAS_CPU_TX39XX ++ bool + -+ DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_RX_CTRL), -+ ag71xx_rr(ag, AG71XX_REG_RX_DESC), -+ ag71xx_rr(ag, AG71XX_REG_RX_STATUS)); -+} ++config SYS_HAS_CPU_VR41XX ++ bool + -+static void ag71xx_dump_regs(struct ag71xx *ag) -+{ -+ DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG1), -+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), -+ ag71xx_rr(ag, AG71XX_REG_MAC_IPG), -+ ag71xx_rr(ag, AG71XX_REG_MAC_HDX), -+ ag71xx_rr(ag, AG71XX_REG_MAC_MFL)); -+ DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), -+ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1), -+ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2)); -+ DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); -+ DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); -+} ++config SYS_HAS_CPU_R4300 ++ bool + -+static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr) -+{ -+ DBG("%s: %s intr=%08x %s%s%s%s%s%s\n", -+ ag->dev->name, label, intr, -+ (intr & AG71XX_INT_TX_PS) ? "TXPS " : "", -+ (intr & AG71XX_INT_TX_UR) ? "TXUR " : "", -+ (intr & AG71XX_INT_TX_BE) ? "TXBE " : "", -+ (intr & AG71XX_INT_RX_PR) ? "RXPR " : "", -+ (intr & AG71XX_INT_RX_OF) ? "RXOF " : "", -+ (intr & AG71XX_INT_RX_BE) ? "RXBE " : ""); -+} ++config SYS_HAS_CPU_R4X00 ++ bool + -+static void ag71xx_ring_free(struct ag71xx_ring *ring) -+{ -+ kfree(ring->buf); ++config SYS_HAS_CPU_TX49XX ++ bool + -+ if (ring->descs_cpu) -+ dma_free_coherent(NULL, ring->size * ring->desc_size, -+ ring->descs_cpu, ring->descs_dma); -+} ++config SYS_HAS_CPU_R5000 ++ bool + -+static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size) -+{ -+ int err; -+ int i; ++config SYS_HAS_CPU_R5432 ++ bool + -+ ring->desc_size = sizeof(struct ag71xx_desc); -+ if (ring->desc_size % cache_line_size()) { -+ DBG("ag71xx: ring %p, desc size %u rounded to %u\n", -+ ring, ring->desc_size, -+ roundup(ring->desc_size, cache_line_size())); -+ ring->desc_size = roundup(ring->desc_size, cache_line_size()); -+ } ++config SYS_HAS_CPU_R5500 ++ bool + -+ ring->descs_cpu = dma_alloc_coherent(NULL, size * ring->desc_size, -+ &ring->descs_dma, GFP_ATOMIC); -+ if (!ring->descs_cpu) { -+ err = -ENOMEM; -+ goto err; -+ } ++config SYS_HAS_CPU_R6000 ++ bool + -+ ring->size = size; ++config SYS_HAS_CPU_NEVADA ++ bool + -+ ring->buf = kzalloc(size * sizeof(*ring->buf), GFP_KERNEL); -+ if (!ring->buf) { -+ err = -ENOMEM; -+ goto err; -+ } ++config SYS_HAS_CPU_R8000 ++ bool + -+ for (i = 0; i < size; i++) { -+ ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[i * ring->desc_size]; -+ DBG("ag71xx: ring %p, desc %d at %p\n", -+ ring, i, ring->buf[i].desc); -+ } ++config SYS_HAS_CPU_R10000 ++ bool + -+ return 0; ++config SYS_HAS_CPU_RM7000 ++ bool + -+ err: -+ return err; -+} ++config SYS_HAS_CPU_RM9000 ++ bool + -+static void ag71xx_ring_tx_clean(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ struct net_device *dev = ag->dev; ++config SYS_HAS_CPU_SB1 ++ bool + -+ while (ring->curr != ring->dirty) { -+ u32 i = ring->dirty % AG71XX_TX_RING_SIZE; ++config SYS_HAS_CPU_CAVIUM_OCTEON ++ bool + -+ if (!ag71xx_desc_empty(ring->buf[i].desc)) { -+ ring->buf[i].desc->ctrl = 0; -+ dev->stats.tx_errors++; -+ } ++config SYS_HAS_CPU_BMIPS3300 ++ bool + -+ if (ring->buf[i].skb) -+ dev_kfree_skb_any(ring->buf[i].skb); ++config SYS_HAS_CPU_BMIPS4350 ++ bool + -+ ring->buf[i].skb = NULL; ++config SYS_HAS_CPU_BMIPS4380 ++ bool + -+ ring->dirty++; -+ } ++config SYS_HAS_CPU_BMIPS5000 ++ bool + -+ /* flush descriptors */ -+ wmb(); ++# ++# CPU may reorder R->R, R->W, W->R, W->W ++# Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC ++# ++config WEAK_ORDERING ++ bool + -+} ++# ++# CPU may reorder reads and writes beyond LL/SC ++# CPU may reorder R->LL, R->LL, W->LL, W->LL, R->SC, R->SC, W->SC, W->SC ++# ++config WEAK_REORDERING_BEYOND_LLSC ++ bool ++endmenu + -+static void ag71xx_ring_tx_init(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ int i; ++# ++# These two indicate any level of the MIPS32 and MIPS64 architecture ++# ++config CPU_MIPS32 ++ bool ++ default y if CPU_MIPS32_R1 || CPU_MIPS32_R2 + -+ for (i = 0; i < AG71XX_TX_RING_SIZE; i++) { -+ ring->buf[i].desc->next = (u32) (ring->descs_dma + -+ ring->desc_size * ((i + 1) % AG71XX_TX_RING_SIZE)); ++config CPU_MIPS64 ++ bool ++ default y if CPU_MIPS64_R1 || CPU_MIPS64_R2 + -+ ring->buf[i].desc->ctrl = DESC_EMPTY; -+ ring->buf[i].skb = NULL; -+ } ++# ++# These two indicate the revision of the architecture, either Release 1 or Release 2 ++# ++config CPU_MIPSR1 ++ bool ++ default y if CPU_MIPS32_R1 || CPU_MIPS64_R1 ++ ++config CPU_MIPSR2 ++ bool ++ default y if CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_CAVIUM_OCTEON ++ ++config SYS_SUPPORTS_32BIT_KERNEL ++ bool ++config SYS_SUPPORTS_64BIT_KERNEL ++ bool ++config CPU_SUPPORTS_32BIT_KERNEL ++ bool ++config CPU_SUPPORTS_64BIT_KERNEL ++ bool ++config CPU_SUPPORTS_CPUFREQ ++ bool ++config CPU_SUPPORTS_ADDRWINCFG ++ bool ++config CPU_SUPPORTS_HUGEPAGES ++ bool ++config CPU_SUPPORTS_UNCACHED_ACCELERATED ++ bool ++config MIPS_PGD_C0_CONTEXT ++ bool ++ default y if 64BIT && CPU_MIPSR2 + -+ /* flush descriptors */ -+ wmb(); ++# ++# Set to y for ptrace access to watch registers. ++# ++config HARDWARE_WATCHPOINTS ++ bool ++ default y if CPU_MIPSR1 || CPU_MIPSR2 + -+ ring->curr = 0; -+ ring->dirty = 0; -+} ++menu "Kernel type" + -+static void ag71xx_ring_rx_clean(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ int i; ++choice + -+ if (!ring->buf) -+ return; ++ prompt "Kernel code model" ++ help ++ You should only select this option if you have a workload that ++ actually benefits from 64-bit processing or if your machine has ++ large memory. You will only be presented a single option in this ++ menu if your system does not support both 32-bit and 64-bit kernels. ++ ++config 32BIT ++ bool "32-bit kernel" ++ depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL ++ select TRAD_SIGNALS ++ help ++ Select this option if you want to build a 32-bit kernel. ++config 64BIT ++ bool "64-bit kernel" ++ depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL ++ select HAVE_SYSCALL_WRAPPERS ++ help ++ Select this option if you want to build a 64-bit kernel. + -+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) -+ if (ring->buf[i].skb) { -+ dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, -+ AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); -+ kfree_skb(ring->buf[i].skb); -+ } -+} ++endchoice + -+static int ag71xx_rx_reserve(struct ag71xx *ag) -+{ -+ int reserve = 0; ++choice ++ prompt "Kernel page size" ++ default PAGE_SIZE_4KB + -+ if (ag71xx_get_pdata(ag)->is_ar724x) { -+ if (!ag71xx_has_ar8216(ag)) -+ reserve = 2; ++config PAGE_SIZE_4KB ++ bool "4kB" ++ depends on !CPU_LOONGSON2 ++ help ++ This option select the standard 4kB Linux page size. On some ++ R3000-family processors this is the only available page size. Using ++ 4kB page size will minimize memory consumption and is therefore ++ recommended for low memory systems. ++ ++config PAGE_SIZE_8KB ++ bool "8kB" ++ depends on (EXPERIMENTAL && CPU_R8000) || CPU_CAVIUM_OCTEON ++ help ++ Using 8kB page size will result in higher performance kernel at ++ the price of higher memory consumption. This option is available ++ only on R8000 and cnMIPS processors. Note that you will need a ++ suitable Linux distribution to support this. ++ ++config PAGE_SIZE_16KB ++ bool "16kB" ++ depends on !CPU_R3000 && !CPU_TX39XX ++ help ++ Using 16kB page size will result in higher performance kernel at ++ the price of higher memory consumption. This option is available on ++ all non-R3000 family processors. Note that you will need a suitable ++ Linux distribution to support this. ++ ++config PAGE_SIZE_32KB ++ bool "32kB" ++ depends on CPU_CAVIUM_OCTEON ++ help ++ Using 32kB page size will result in higher performance kernel at ++ the price of higher memory consumption. This option is available ++ only on cnMIPS cores. Note that you will need a suitable Linux ++ distribution to support this. ++ ++config PAGE_SIZE_64KB ++ bool "64kB" ++ depends on EXPERIMENTAL && !CPU_R3000 && !CPU_TX39XX ++ help ++ Using 64kB page size will result in higher performance kernel at ++ the price of higher memory consumption. This option is available on ++ all non-R3000 family processor. Not that at the time of this ++ writing this option is still high experimental. ++ ++endchoice ++ ++config FORCE_MAX_ZONEORDER ++ int "Maximum zone order" ++ range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB ++ default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB ++ range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB ++ default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB ++ range 11 64 ++ default "11" ++ help ++ The kernel memory allocator divides physically contiguous memory ++ blocks into "zones", where each zone is a power of two number of ++ pages. This option selects the largest power of two that the kernel ++ keeps in the memory allocator. If you need to allocate very large ++ blocks of physically contiguous memory, then you may need to ++ increase this value. + -+ if (ag->phy_dev) -+ reserve += 4 - (ag->phy_dev->pkt_align % 4); ++ This config option is actually maximum order plus one. For example, ++ a value of 11 means that the largest free memory block is 2^10 pages. + -+ reserve %= 4; -+ } ++ The page size is not necessarily 4KB. Keep this in mind ++ when choosing a value for this option. + -+ return reserve + AG71XX_RX_PKT_RESERVE; -+} ++config BOARD_SCACHE ++ bool + ++config IP22_CPU_SCACHE ++ bool ++ select BOARD_SCACHE + -+static int ag71xx_ring_rx_init(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ unsigned int reserve = ag71xx_rx_reserve(ag); -+ unsigned int i; -+ int ret; ++# ++# Support for a MIPS32 / MIPS64 style S-caches ++# ++config MIPS_CPU_SCACHE ++ bool ++ select BOARD_SCACHE + -+ ret = 0; -+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { -+ ring->buf[i].desc->next = (u32) (ring->descs_dma + -+ ring->desc_size * ((i + 1) % AG71XX_RX_RING_SIZE)); ++config R5000_CPU_SCACHE ++ bool ++ select BOARD_SCACHE + -+ DBG("ag71xx: RX desc at %p, next is %08x\n", -+ ring->buf[i].desc, -+ ring->buf[i].desc->next); -+ } ++config RM7000_CPU_SCACHE ++ bool ++ select BOARD_SCACHE + -+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { -+ struct sk_buff *skb; -+ dma_addr_t dma_addr; ++config SIBYTE_DMA_PAGEOPS ++ bool "Use DMA to clear/copy pages" ++ depends on CPU_SB1 ++ help ++ Instead of using the CPU to zero and copy pages, use a Data Mover ++ channel. These DMA channels are otherwise unused by the standard ++ SiByte Linux port. Seems to give a small performance benefit. + -+ skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); -+ if (!skb) { -+ ret = -ENOMEM; -+ break; -+ } ++config CPU_HAS_PREFETCH ++ bool + -+ skb->dev = ag->dev; -+ skb_reserve(skb, reserve); ++choice ++ prompt "MIPS MT options" + -+ dma_addr = dma_map_single(&ag->dev->dev, skb->data, -+ AG71XX_RX_PKT_SIZE, -+ DMA_FROM_DEVICE); -+ ring->buf[i].skb = skb; -+ ring->buf[i].dma_addr = dma_addr; -+ ring->buf[i].desc->data = (u32) dma_addr; -+ ring->buf[i].desc->ctrl = DESC_EMPTY; -+ } ++config MIPS_MT_DISABLED ++ bool "Disable multithreading support." ++ help ++ Use this option if your workload can't take advantage of ++ MIPS hardware multithreading support. On systems that don't have ++ the option of an MT-enabled processor this option will be the only ++ option in this menu. ++ ++config MIPS_MT_SMP ++ bool "Use 1 TC on each available VPE for SMP" ++ depends on SYS_SUPPORTS_MULTITHREADING ++ select CPU_MIPSR2_IRQ_VI ++ select CPU_MIPSR2_IRQ_EI ++ select MIPS_MT ++ select NR_CPUS_DEFAULT_2 ++ select SMP ++ select SYS_SUPPORTS_SCHED_SMT if SMP ++ select SYS_SUPPORTS_SMP ++ select SMP_UP ++ help ++ This is a kernel model which is known a VSMP but lately has been ++ marketesed into SMVP. ++ Virtual SMP uses the processor's VPEs to implement virtual ++ processors. In currently available configuration of the 34K processor ++ this allows for a dual processor. Both processors will share the same ++ primary caches; each will obtain the half of the TLB for it's own ++ exclusive use. For a layman this model can be described as similar to ++ what Intel calls Hyperthreading. ++ ++ For further information see http://www.linux-mips.org/wiki/34K#VSMP ++ ++config MIPS_MT_SMTC ++ bool "SMTC: Use all TCs on all VPEs for SMP" ++ depends on CPU_MIPS32_R2 ++ #depends on CPU_MIPS64_R2 # once there is hardware ... ++ depends on SYS_SUPPORTS_MULTITHREADING ++ select CPU_MIPSR2_IRQ_VI ++ select CPU_MIPSR2_IRQ_EI ++ select MIPS_MT ++ select NR_CPUS_DEFAULT_8 ++ select SMP ++ select SYS_SUPPORTS_SMP ++ select SMP_UP ++ help ++ This is a kernel model which is known a SMTC or lately has been ++ marketesed into SMVP. ++ is presenting the available TC's of the core as processors to Linux. ++ On currently available 34K processors this means a Linux system will ++ see up to 5 processors. The implementation of the SMTC kernel differs ++ significantly from VSMP and cannot efficiently coexist in the same ++ kernel binary so the choice between VSMP and SMTC is a compile time ++ decision. + -+ /* flush descriptors */ -+ wmb(); ++ For further information see http://www.linux-mips.org/wiki/34K#SMTC + -+ ring->curr = 0; -+ ring->dirty = 0; ++endchoice + -+ return ret; -+} ++config MIPS_MT ++ bool + -+static int ag71xx_ring_rx_refill(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ unsigned int reserve = ag71xx_rx_reserve(ag); -+ unsigned int count; ++config SCHED_SMT ++ bool "SMT (multithreading) scheduler support" ++ depends on SYS_SUPPORTS_SCHED_SMT ++ default n ++ help ++ SMT scheduler support improves the CPU scheduler's decision making ++ when dealing with MIPS MT enabled cores at a cost of slightly ++ increased overhead in some places. If unsure say N here. + -+ count = 0; -+ for (; ring->curr - ring->dirty > 0; ring->dirty++) { -+ unsigned int i; ++config SYS_SUPPORTS_SCHED_SMT ++ bool + -+ i = ring->dirty % AG71XX_RX_RING_SIZE; + -+ if (ring->buf[i].skb == NULL) { -+ dma_addr_t dma_addr; -+ struct sk_buff *skb; ++config SYS_SUPPORTS_MULTITHREADING ++ bool + -+ skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); -+ if (skb == NULL) -+ break; ++config MIPS_MT_FPAFF ++ bool "Dynamic FPU affinity for FP-intensive threads" ++ default y ++ depends on MIPS_MT_SMP || MIPS_MT_SMTC ++ ++config MIPS_VPE_LOADER ++ bool "VPE loader support." ++ depends on SYS_SUPPORTS_MULTITHREADING ++ select CPU_MIPSR2_IRQ_VI ++ select CPU_MIPSR2_IRQ_EI ++ select MIPS_MT ++ help ++ Includes a loader for loading an elf relocatable object ++ onto another VPE and running it. + -+ skb_reserve(skb, reserve); -+ skb->dev = ag->dev; ++config MIPS_MT_SMTC_IM_BACKSTOP ++ bool "Use per-TC register bits as backstop for inhibited IM bits" ++ depends on MIPS_MT_SMTC ++ default n ++ help ++ To support multiple TC microthreads acting as "CPUs" within ++ a VPE, VPE-wide interrupt mask bits must be specially manipulated ++ during interrupt handling. To support legacy drivers and interrupt ++ controller management code, SMTC has a "backstop" to track and ++ if necessary restore the interrupt mask. This has some performance ++ impact on interrupt service overhead. ++ ++config MIPS_MT_SMTC_IRQAFF ++ bool "Support IRQ affinity API" ++ depends on MIPS_MT_SMTC ++ default n ++ help ++ Enables SMP IRQ affinity API (/proc/irq/*/smp_affinity, etc.) ++ for SMTC Linux kernel. Requires platform support, of which ++ an example can be found in the MIPS kernel i8259 and Malta ++ platform code. Adds some overhead to interrupt dispatch, and ++ should be used only if you know what you are doing. ++ ++config MIPS_VPE_LOADER_TOM ++ bool "Load VPE program into memory hidden from linux" ++ depends on MIPS_VPE_LOADER ++ default y ++ help ++ The loader can use memory that is present but has been hidden from ++ Linux using the kernel command line option "mem=xxMB". It's up to ++ you to ensure the amount you put in the option and the space your ++ program requires is less or equal to the amount physically present. ++ ++# this should possibly be in drivers/char, but it is rather cpu related. Hmmm ++config MIPS_VPE_APSP_API ++ bool "Enable support for AP/SP API (RTLX)" ++ depends on MIPS_VPE_LOADER ++ help + -+ dma_addr = dma_map_single(&ag->dev->dev, skb->data, -+ AG71XX_RX_PKT_SIZE, -+ DMA_FROM_DEVICE); ++config MIPS_APSP_KSPD ++ bool "Enable KSPD" ++ depends on MIPS_VPE_APSP_API ++ default y ++ help ++ KSPD is a kernel daemon that accepts syscall requests from the SP ++ side, actions them and returns the results. It also handles the ++ "exit" syscall notifying other kernel modules the SP program is ++ exiting. You probably want to say yes here. ++ ++config MIPS_CMP ++ bool "MIPS CMP framework support" ++ depends on SYS_SUPPORTS_MIPS_CMP ++ select SYNC_R4K ++ select SYS_SUPPORTS_SMP ++ select SYS_SUPPORTS_SCHED_SMT if SMP ++ select WEAK_ORDERING ++ default n ++ help ++ This is a placeholder option for the GCMP work. It will need to ++ be handled differently... + -+ ring->buf[i].skb = skb; -+ ring->buf[i].dma_addr = dma_addr; -+ ring->buf[i].desc->data = (u32) dma_addr; -+ } ++config SB1_PASS_1_WORKAROUNDS ++ bool ++ depends on CPU_SB1_PASS_1 ++ default y + -+ ring->buf[i].desc->ctrl = DESC_EMPTY; -+ count++; -+ } ++config SB1_PASS_2_WORKAROUNDS ++ bool ++ depends on CPU_SB1 && (CPU_SB1_PASS_2_2 || CPU_SB1_PASS_2) ++ default y + -+ /* flush descriptors */ -+ wmb(); ++config SB1_PASS_2_1_WORKAROUNDS ++ bool ++ depends on CPU_SB1 && CPU_SB1_PASS_2 ++ default y + -+ DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count); ++config 64BIT_PHYS_ADDR ++ bool + -+ return count; -+} ++config ARCH_PHYS_ADDR_T_64BIT ++ def_bool 64BIT_PHYS_ADDR + -+static int ag71xx_rings_init(struct ag71xx *ag) -+{ -+ int ret; ++config CPU_HAS_SMARTMIPS ++ depends on SYS_SUPPORTS_SMARTMIPS ++ bool "Support for the SmartMIPS ASE" ++ help ++ SmartMIPS is a extension of the MIPS32 architecture aimed at ++ increased security at both hardware and software level for ++ smartcards. Enabling this option will allow proper use of the ++ SmartMIPS instructions by Linux applications. However a kernel with ++ this option will not work on a MIPS core without SmartMIPS core. If ++ you don't know you probably don't have SmartMIPS and should say N ++ here. + -+ ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE); -+ if (ret) -+ return ret; ++config CPU_HAS_WB ++ bool + -+ ag71xx_ring_tx_init(ag); ++# ++# Vectored interrupt mode is an R2 feature ++# ++config CPU_MIPSR2_IRQ_VI ++ bool + -+ ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE); -+ if (ret) -+ return ret; ++# ++# Extended interrupt mode is an R2 feature ++# ++config CPU_MIPSR2_IRQ_EI ++ bool + -+ ret = ag71xx_ring_rx_init(ag); -+ return ret; -+} ++config CPU_HAS_SYNC ++ bool ++ depends on !CPU_R3000 ++ default y + -+static void ag71xx_rings_cleanup(struct ag71xx *ag) -+{ -+ ag71xx_ring_rx_clean(ag); -+ ag71xx_ring_free(&ag->rx_ring); ++config GENERIC_CLOCKEVENTS_BROADCAST ++ bool + -+ ag71xx_ring_tx_clean(ag); -+ ag71xx_ring_free(&ag->tx_ring); -+} ++# ++# CPU non-features ++# ++config CPU_DADDI_WORKAROUNDS ++ bool + -+static unsigned char *ag71xx_speed_str(struct ag71xx *ag) -+{ -+ switch (ag->speed) { -+ case SPEED_1000: -+ return "1000"; -+ case SPEED_100: -+ return "100"; -+ case SPEED_10: -+ return "10"; -+ } ++config CPU_R4000_WORKAROUNDS ++ bool ++ select CPU_R4400_WORKAROUNDS + -+ return "?"; -+} ++config CPU_R4400_WORKAROUNDS ++ bool + -+void ag71xx_link_adjust(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ u32 cfg2; -+ u32 ifctl; -+ u32 fifo5; -+ u32 mii_speed; ++# ++# - Highmem only makes sense for the 32-bit kernel. ++# - The current highmem code will only work properly on physically indexed ++# caches such as R3000, SB1, R7000 or those that look like they're virtually ++# indexed such as R4000/R4400 SC and MC versions or R10000. So for the ++# moment we protect the user and offer the highmem option only on machines ++# where it's known to be safe. This will not offer highmem on a few systems ++# such as MIPS32 and MIPS64 CPUs which may have virtual and physically ++# indexed CPUs but we're playing safe. ++# - We use SYS_SUPPORTS_HIGHMEM to offer highmem only for systems where we ++# know they might have memory configurations that could make use of highmem ++# support. ++# ++config HIGHMEM ++ bool "High Memory Support" ++ depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM + -+ if (!ag->link) { -+ netif_carrier_off(ag->dev); -+ if (netif_msg_link(ag)) -+ printk(KERN_INFO "%s: link down\n", ag->dev->name); -+ return; -+ } ++config CPU_SUPPORTS_HIGHMEM ++ bool + -+ cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); -+ cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); -+ cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; ++config SYS_SUPPORTS_HIGHMEM ++ bool + -+ ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); -+ ifctl &= ~(MAC_IFCTL_SPEED); ++config SYS_SUPPORTS_SMARTMIPS ++ bool + -+ fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); -+ fifo5 &= ~FIFO_CFG5_BM; ++config ARCH_FLATMEM_ENABLE ++ def_bool y ++ depends on !NUMA && !CPU_LOONGSON2 + -+ switch (ag->speed) { -+ case SPEED_1000: -+ mii_speed = MII_CTRL_SPEED_1000; -+ cfg2 |= MAC_CFG2_IF_1000; -+ fifo5 |= FIFO_CFG5_BM; -+ break; -+ case SPEED_100: -+ mii_speed = MII_CTRL_SPEED_100; -+ cfg2 |= MAC_CFG2_IF_10_100; -+ ifctl |= MAC_IFCTL_SPEED; -+ break; -+ case SPEED_10: -+ mii_speed = MII_CTRL_SPEED_10; -+ cfg2 |= MAC_CFG2_IF_10_100; -+ break; -+ default: -+ BUG(); -+ return; -+ } ++config ARCH_DISCONTIGMEM_ENABLE ++ bool ++ default y if SGI_IP27 ++ help ++ Say Y to support efficient handling of discontiguous physical memory, ++ for architectures which are either NUMA (Non-Uniform Memory Access) ++ or have huge holes in the physical address space for other reasons. ++ See for more. + -+ if (pdata->is_ar91xx) -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); -+ else if (pdata->is_ar724x) -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3); -+ else -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff); ++config ARCH_POPULATES_NODE_MAP ++ def_bool y + -+ if (pdata->set_pll) -+ pdata->set_pll(ag->speed); ++config ARCH_SPARSEMEM_ENABLE ++ bool ++ select SPARSEMEM_STATIC + -+ ag71xx_mii_ctrl_set_speed(ag, mii_speed); ++config NUMA ++ bool "NUMA Support" ++ depends on SYS_SUPPORTS_NUMA ++ help ++ Say Y to compile the kernel to support NUMA (Non-Uniform Memory ++ Access). This option improves performance on systems with more ++ than two nodes; on two node systems it is generally better to ++ leave it disabled; on single node systems disable this option ++ disabled. ++ ++config SYS_SUPPORTS_NUMA ++ bool ++ ++config NODES_SHIFT ++ int ++ default "6" ++ depends on NEED_MULTIPLE_NODES ++ ++config HW_PERF_EVENTS ++ bool "Enable hardware performance counter support for perf events" ++ depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && CPU_MIPS32 ++ default y ++ help ++ Enable hardware performance counter support for perf events. If ++ disabled, perf events will use software events only. + -+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); -+ ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); ++source "mm/Kconfig" + -+ netif_carrier_on(ag->dev); -+ if (netif_msg_link(ag)) -+ printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n", -+ ag->dev->name, -+ ag71xx_speed_str(ag), -+ (DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); ++config SMP ++ bool "Multi-Processing support" ++ depends on SYS_SUPPORTS_SMP ++ select IRQ_PER_CPU ++ select USE_GENERIC_SMP_HELPERS ++ help ++ This enables support for systems with more than one CPU. If you have ++ a system with only one CPU, like most personal computers, say N. If ++ you have a system with more than one CPU, say Y. + -+ DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); ++ If you say N here, the kernel will run on single and multiprocessor ++ machines, but will use only one CPU of a multiprocessor machine. If ++ you say Y here, the kernel will run on many, but not all, ++ singleprocessor machines. On a singleprocessor machine, the kernel ++ will run faster if you say N here. + -+ DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); ++ People using multiprocessor machines who say Y here should also say ++ Y to "Enhanced Real Time Clock Support", below. + -+ DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), -+ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), -+ ag71xx_mii_ctrl_rr(ag)); -+} ++ See also the SMP-HOWTO available at ++ . + -+static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) -+{ -+ u32 t; ++ If you don't know what to do here, say N. + -+ t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16) -+ | (((u32) mac[3]) << 8) | ((u32) mac[2]); ++config SMP_UP ++ bool + -+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t); ++config SYS_SUPPORTS_MIPS_CMP ++ bool + -+ t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16); -+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); -+} ++config SYS_SUPPORTS_SMP ++ bool + -+static void ag71xx_dma_reset(struct ag71xx *ag) -+{ -+ u32 val; -+ int i; ++config NR_CPUS_DEFAULT_1 ++ bool + -+ ag71xx_dump_dma_regs(ag); ++config NR_CPUS_DEFAULT_2 ++ bool + -+ /* stop RX and TX */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); -+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); ++config NR_CPUS_DEFAULT_4 ++ bool + -+ /* clear descriptor addresses */ -+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0); -+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0); ++config NR_CPUS_DEFAULT_8 ++ bool + -+ /* clear pending RX/TX interrupts */ -+ for (i = 0; i < 256; i++) { -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); -+ } ++config NR_CPUS_DEFAULT_16 ++ bool + -+ /* clear pending errors */ -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); ++config NR_CPUS_DEFAULT_32 ++ bool + -+ val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); -+ if (val) -+ printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n", -+ ag->dev->name, val); ++config NR_CPUS_DEFAULT_64 ++ bool + -+ val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); ++config NR_CPUS ++ int "Maximum number of CPUs (2-64)" ++ range 1 64 if NR_CPUS_DEFAULT_1 ++ depends on SMP ++ default "1" if NR_CPUS_DEFAULT_1 ++ default "2" if NR_CPUS_DEFAULT_2 ++ default "4" if NR_CPUS_DEFAULT_4 ++ default "8" if NR_CPUS_DEFAULT_8 ++ default "16" if NR_CPUS_DEFAULT_16 ++ default "32" if NR_CPUS_DEFAULT_32 ++ default "64" if NR_CPUS_DEFAULT_64 ++ help ++ This allows you to specify the maximum number of CPUs which this ++ kernel will support. The maximum supported value is 32 for 32-bit ++ kernel and 64 for 64-bit kernels; the minimum value which makes ++ sense is 1 for Qemu (useful only for kernel debugging purposes) ++ and 2 for all others. + -+ /* mask out reserved bits */ -+ val &= ~0xff000000; ++ This is purely to save memory - each supported CPU adds ++ approximately eight kilobytes to the kernel image. For best ++ performance should round up your number of processors to the next ++ power of two. + -+ if (val) -+ printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n", -+ ag->dev->name, val); ++source "kernel/time/Kconfig" + -+ ag71xx_dump_dma_regs(ag); -+} ++# ++# Timer Interrupt Frequency Configuration ++# + -+#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \ -+ MAC_CFG1_SRX | MAC_CFG1_STX) ++choice ++ prompt "Timer frequency" ++ default HZ_250 ++ help ++ Allows the configuration of the timer frequency. + -+#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT) ++ config HZ_48 ++ bool "48 HZ" if SYS_SUPPORTS_48HZ || SYS_SUPPORTS_ARBIT_HZ + -+#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \ -+ FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \ -+ FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \ -+ FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \ -+ FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \ -+ FIFO_CFG4_VT) ++ config HZ_100 ++ bool "100 HZ" if SYS_SUPPORTS_100HZ || SYS_SUPPORTS_ARBIT_HZ + -+#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \ -+ FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \ -+ FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \ -+ FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \ -+ FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \ -+ FIFO_CFG5_17 | FIFO_CFG5_SF) ++ config HZ_128 ++ bool "128 HZ" if SYS_SUPPORTS_128HZ || SYS_SUPPORTS_ARBIT_HZ + -+static void ag71xx_hw_init(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ config HZ_250 ++ bool "250 HZ" if SYS_SUPPORTS_250HZ || SYS_SUPPORTS_ARBIT_HZ + -+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); -+ udelay(20); ++ config HZ_256 ++ bool "256 HZ" if SYS_SUPPORTS_256HZ || SYS_SUPPORTS_ARBIT_HZ + -+ ar71xx_device_stop(pdata->reset_bit); -+ mdelay(100); -+ ar71xx_device_start(pdata->reset_bit); -+ mdelay(100); ++ config HZ_1000 ++ bool "1000 HZ" if SYS_SUPPORTS_1000HZ || SYS_SUPPORTS_ARBIT_HZ + -+ /* setup MAC configuration registers */ -+ if (pdata->is_ar724x) -+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, -+ MAC_CFG1_INIT | MAC_CFG1_TFC | MAC_CFG1_RFC); -+ else -+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT); ++ config HZ_1024 ++ bool "1024 HZ" if SYS_SUPPORTS_1024HZ || SYS_SUPPORTS_ARBIT_HZ + -+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG2, -+ MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK); ++endchoice + -+ /* setup max frame length */ -+ ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN); ++config SYS_SUPPORTS_48HZ ++ bool + -+ /* setup MII interface type */ -+ ag71xx_mii_ctrl_set_if(ag, pdata->mii_if); ++config SYS_SUPPORTS_100HZ ++ bool + -+ /* setup FIFO configuration registers */ -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT); -+ if (pdata->is_ar724x) { -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, pdata->fifo_cfg1); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, pdata->fifo_cfg2); -+ } else { -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); -+ } -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT); ++config SYS_SUPPORTS_128HZ ++ bool + -+ ag71xx_dma_reset(ag); -+} ++config SYS_SUPPORTS_250HZ ++ bool + -+static void ag71xx_hw_start(struct ag71xx *ag) -+{ -+ /* start RX engine */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); ++config SYS_SUPPORTS_256HZ ++ bool + -+ /* enable interrupts */ -+ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT); -+} ++config SYS_SUPPORTS_1000HZ ++ bool + -+static void ag71xx_hw_stop(struct ag71xx *ag) -+{ -+ /* disable all interrupts */ -+ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0); ++config SYS_SUPPORTS_1024HZ ++ bool + -+ ag71xx_dma_reset(ag); -+} ++config SYS_SUPPORTS_ARBIT_HZ ++ bool ++ default y if !SYS_SUPPORTS_48HZ && !SYS_SUPPORTS_100HZ && \ ++ !SYS_SUPPORTS_128HZ && !SYS_SUPPORTS_250HZ && \ ++ !SYS_SUPPORTS_256HZ && !SYS_SUPPORTS_1000HZ && \ ++ !SYS_SUPPORTS_1024HZ + -+static int ag71xx_open(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ int ret; ++config HZ ++ int ++ default 48 if HZ_48 ++ default 100 if HZ_100 ++ default 128 if HZ_128 ++ default 250 if HZ_250 ++ default 256 if HZ_256 ++ default 1000 if HZ_1000 ++ default 1024 if HZ_1024 + -+ ret = ag71xx_rings_init(ag); -+ if (ret) -+ goto err; ++source "kernel/Kconfig.preempt" + -+ napi_enable(&ag->napi); ++config MIPS_INSANE_LARGE ++ bool "Support for large 64-bit configurations" ++ depends on CPU_R10000 && 64BIT ++ help ++ MIPS R10000 does support a 44 bit / 16TB address space as opposed to ++ previous 64-bit processors which only supported 40 bit / 1TB. If you ++ need processes of more than 1TB virtual address space, say Y here. ++ This will result in additional memory usage, so it is not ++ recommended for normal users. ++ ++config KEXEC ++ bool "Kexec system call (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ help ++ kexec is a system call that implements the ability to shutdown your ++ current kernel, and to start another kernel. It is like a reboot ++ but it is independent of the system firmware. And like a reboot ++ you can start any kernel with it, not just Linux. ++ ++ The name comes from the similarity to the exec system call. ++ ++ It is an ongoing process to be certain the hardware in a machine ++ is properly shutdown, so do not be surprised if this code does not ++ initially work for you. It may help to enable device hotplugging ++ support. As of this writing the exact hardware interface is ++ strongly in flux, so no good recommendation can be made. ++ ++config SECCOMP ++ bool "Enable seccomp to safely compute untrusted bytecode" ++ depends on PROC_FS ++ default y ++ help ++ This kernel feature is useful for number crunching applications ++ that may need to compute untrusted bytecode during their ++ execution. By using pipes or other transports made available to ++ the process as file descriptors supporting the read/write ++ syscalls, it's possible to isolate those applications in ++ their own address space using seccomp. Once seccomp is ++ enabled via /proc//seccomp, it cannot be disabled ++ and the task is only allowed to execute a few safe syscalls ++ defined by each seccomp mode. ++ ++ If unsure, say Y. Only embedded should say N here. ++ ++config USE_OF ++ bool "Flattened Device Tree support" ++ select OF ++ select OF_EARLY_FLATTREE ++ help ++ Include support for flattened device tree machine descriptions. + -+ netif_carrier_off(dev); -+ ag71xx_phy_start(ag); ++endmenu + -+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma); -+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma); ++config LOCKDEP_SUPPORT ++ bool ++ default y + -+ ag71xx_hw_set_macaddr(ag, dev->dev_addr); ++config STACKTRACE_SUPPORT ++ bool ++ default y + -+ ag71xx_hw_start(ag); ++source "init/Kconfig" + -+ netif_start_queue(dev); ++source "kernel/Kconfig.freezer" + -+ return 0; ++menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" + -+ err: -+ ag71xx_rings_cleanup(ag); -+ return ret; -+} ++config HW_HAS_EISA ++ bool ++config HW_HAS_PCI ++ bool + -+static int ag71xx_stop(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ unsigned long flags; ++config PCI ++ bool "Support for PCI controller" ++ depends on HW_HAS_PCI ++ select PCI_DOMAINS ++ help ++ Find out whether you have a PCI motherboard. PCI is the name of a ++ bus system, i.e. the way the CPU talks to the other stuff inside ++ your box. Other bus systems are ISA, EISA, or VESA. If you have PCI, ++ say Y, otherwise N. + -+ netif_carrier_off(dev); -+ ag71xx_phy_stop(ag); ++config PCI_DOMAINS ++ bool + -+ spin_lock_irqsave(&ag->lock, flags); ++source "drivers/pci/Kconfig" + -+ netif_stop_queue(dev); ++# ++# ISA support is now enabled via select. Too many systems still have the one ++# or other ISA chip on the board that users don't know about so don't expect ++# users to choose the right thing ... ++# ++config ISA ++ bool + -+ ag71xx_hw_stop(ag); ++config EISA ++ bool "EISA support" ++ depends on HW_HAS_EISA ++ select ISA ++ select GENERIC_ISA_DMA ++ ---help--- ++ The Extended Industry Standard Architecture (EISA) bus was ++ developed as an open alternative to the IBM MicroChannel bus. + -+ napi_disable(&ag->napi); -+ del_timer_sync(&ag->oom_timer); ++ The EISA bus provided some of the features of the IBM MicroChannel ++ bus while maintaining backward compatibility with cards made for ++ the older ISA bus. The EISA bus saw limited use between 1988 and ++ 1995 when it was made obsolete by the PCI bus. + -+ spin_unlock_irqrestore(&ag->lock, flags); ++ Say Y here if you are building a kernel for an EISA-based machine. + -+ ag71xx_rings_cleanup(ag); ++ Otherwise, say N. + -+ return 0; -+} ++source "drivers/eisa/Kconfig" + -+static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb, -+ struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ struct ag71xx_desc *desc; -+ dma_addr_t dma_addr; -+ int i; ++config TC ++ bool "TURBOchannel support" ++ depends on MACH_DECSTATION ++ help ++ TURBOchannel is a DEC (now Compaq (now HP)) bus for Alpha and MIPS ++ processors. TURBOchannel programming specifications are available ++ at: ++ ++ and: ++ ++ Linux driver support status is documented at: ++ ++ ++#config ACCESSBUS ++# bool "Access.Bus support" ++# depends on TC ++ ++config MMU ++ bool ++ default y + -+ i = ring->curr % AG71XX_TX_RING_SIZE; -+ desc = ring->buf[i].desc; ++config I8253 ++ bool ++ select MIPS_EXTERNAL_TIMER + -+ if (!ag71xx_desc_empty(desc)) -+ goto err_drop; ++config ZONE_DMA32 ++ bool + -+ if (ag71xx_has_ar8216(ag)) -+ ag71xx_add_ar8216_header(ag, skb); ++source "drivers/pcmcia/Kconfig" + -+ if (skb->len <= 0) { -+ DBG("%s: packet len is too small\n", ag->dev->name); -+ goto err_drop; -+ } ++source "drivers/pci/hotplug/Kconfig" + -+ dma_addr = dma_map_single(&dev->dev, skb->data, skb->len, -+ DMA_TO_DEVICE); ++config RAPIDIO ++ bool "RapidIO support" ++ depends on PCI ++ default n ++ help ++ If you say Y here, the kernel will include drivers and ++ infrastructure code to support RapidIO interconnect devices. + -+ ring->buf[i].skb = skb; ++source "drivers/rapidio/Kconfig" + -+ /* setup descriptor fields */ -+ desc->data = (u32) dma_addr; -+ desc->ctrl = (skb->len & DESC_PKTLEN_M); ++endmenu + -+ /* flush descriptor */ -+ wmb(); ++menu "Executable file formats" + -+ ring->curr++; -+ if (ring->curr == (ring->dirty + AG71XX_TX_THRES_STOP)) { -+ DBG("%s: tx queue full\n", ag->dev->name); -+ netif_stop_queue(dev); -+ } ++source "fs/Kconfig.binfmt" + -+ DBG("%s: packet injected into TX queue\n", ag->dev->name); ++config TRAD_SIGNALS ++ bool + -+ /* enable TX engine */ -+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); ++config MIPS32_COMPAT ++ bool "Kernel support for Linux/MIPS 32-bit binary compatibility" ++ depends on 64BIT ++ help ++ Select this option if you want Linux/MIPS 32-bit binary ++ compatibility. Since all software available for Linux/MIPS is ++ currently 32-bit you should say Y here. + -+ return NETDEV_TX_OK; ++config COMPAT ++ bool ++ depends on MIPS32_COMPAT ++ default y + -+ err_drop: -+ dev->stats.tx_dropped++; ++config SYSVIPC_COMPAT ++ bool ++ depends on COMPAT && SYSVIPC ++ default y + -+ dev_kfree_skb(skb); -+ return NETDEV_TX_OK; -+} ++config MIPS32_O32 ++ bool "Kernel support for o32 binaries" ++ depends on MIPS32_COMPAT ++ help ++ Select this option if you want to run o32 binaries. These are pure ++ 32-bit binaries as used by the 32-bit Linux/MIPS port. Most of ++ existing binaries are in this format. + -+static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ struct mii_ioctl_data *data = (struct mii_ioctl_data *) &ifr->ifr_data; -+ struct ag71xx *ag = netdev_priv(dev); -+ int ret; ++ If unsure, say Y. + -+ switch (cmd) { -+ case SIOCETHTOOL: -+ if (ag->phy_dev == NULL) -+ break; ++config MIPS32_N32 ++ bool "Kernel support for n32 binaries" ++ depends on MIPS32_COMPAT ++ help ++ Select this option if you want to run n32 binaries. These are ++ 64-bit binaries using 32-bit quantities for addressing and certain ++ data that would normally be 64-bit. They are used in special ++ cases. + -+ spin_lock_irq(&ag->lock); -+ ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data); -+ spin_unlock_irq(&ag->lock); -+ return ret; ++ If unsure, say N. + -+ case SIOCSIFHWADDR: -+ if (copy_from_user -+ (dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr))) -+ return -EFAULT; -+ return 0; ++config BINFMT_ELF32 ++ bool ++ default y if MIPS32_O32 || MIPS32_N32 + -+ case SIOCGIFHWADDR: -+ if (copy_to_user -+ (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr))) -+ return -EFAULT; -+ return 0; ++endmenu + -+ case SIOCGMIIPHY: -+ case SIOCGMIIREG: -+ case SIOCSMIIREG: -+ if (ag->phy_dev == NULL) -+ break; ++menu "Power management options" + -+ return phy_mii_ioctl(ag->phy_dev, data, cmd); ++config ARCH_HIBERNATION_POSSIBLE ++ def_bool y ++ depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP + -+ default: -+ break; -+ } ++config ARCH_SUSPEND_POSSIBLE ++ def_bool y ++ depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP + -+ return -EOPNOTSUPP; -+} ++source "kernel/power/Kconfig" + -+static void ag71xx_oom_timer_handler(unsigned long data) -+{ -+ struct net_device *dev = (struct net_device *) data; -+ struct ag71xx *ag = netdev_priv(dev); ++endmenu + -+ napi_schedule(&ag->napi); -+} ++source "arch/mips/kernel/cpufreq/Kconfig" + -+static void ag71xx_tx_timeout(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); ++source "net/Kconfig" + -+ if (netif_msg_tx_err(ag)) -+ printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name); ++source "drivers/Kconfig" + -+ schedule_work(&ag->restart_work); -+} ++source "fs/Kconfig" + -+static void ag71xx_restart_work_func(struct work_struct *work) -+{ -+ struct ag71xx *ag = container_of(work, struct ag71xx, restart_work); ++source "arch/mips/Kconfig.debug" + -+ ag71xx_stop(ag->dev); -+ ag71xx_open(ag->dev); -+} ++source "security/Kconfig" + -+static int ag71xx_tx_packets(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ int sent; ++source "crypto/Kconfig" + -+ DBG("%s: processing TX ring\n", ag->dev->name); ++menuconfig VIRTUALIZATION ++ bool "Virtualization" ++ default n ++ ---help--- ++ Say Y here to get to see options for using your Linux host to run other ++ operating systems inside virtual machines (guests). ++ This option alone does not add any kernel code. + -+ sent = 0; -+ while (ring->dirty != ring->curr) { -+ unsigned int i = ring->dirty % AG71XX_TX_RING_SIZE; -+ struct ag71xx_desc *desc = ring->buf[i].desc; -+ struct sk_buff *skb = ring->buf[i].skb; ++ If you say N, all options in this submenu will be skipped and disabled. + -+ if (!ag71xx_desc_empty(desc)) -+ break; ++if VIRTUALIZATION + -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); ++source drivers/virtio/Kconfig + -+ ag->dev->stats.tx_bytes += skb->len; -+ ag->dev->stats.tx_packets++; ++endif # VIRTUALIZATION + -+ dev_kfree_skb_any(skb); -+ ring->buf[i].skb = NULL; ++source "lib/Kconfig" +diff -Nur linux-2.6.39.orig/arch/mips/kernel/traps.c linux-2.6.39/arch/mips/kernel/traps.c +--- linux-2.6.39.orig/arch/mips/kernel/traps.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/kernel/traps.c 2011-08-24 05:53:05.179230891 +0200 +@@ -54,6 +54,7 @@ + #include + #include + #include ++#include + + extern void check_wait(void); + extern asmlinkage void r4k_wait(void); +@@ -1576,6 +1577,8 @@ + if (cpu_has_mips_r2) { + cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; + cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; ++ if (get_c0_compare_irq) ++ cp0_compare_irq = get_c0_compare_irq(); + cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7; + if (cp0_perfcount_irq == cp0_compare_irq) + cp0_perfcount_irq = -1; +diff -Nur linux-2.6.39.orig/arch/mips/Makefile linux-2.6.39/arch/mips/Makefile +--- linux-2.6.39.orig/arch/mips/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/Makefile 2011-08-24 02:42:39.917989402 +0200 +@@ -158,6 +158,13 @@ + endif + cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1 + ++# ++# Atheros AR71xx ++# ++core-$(CONFIG_ATHEROS_AR71XX) += arch/mips/ar71xx/ ++cflags-$(CONFIG_ATHEROS_AR71XX) += -I$(srctree)/arch/mips/include/asm/mach-ar71xx ++load-$(CONFIG_ATHEROS_AR71XX) += 0xffffffff80060000 + -+ ring->dirty++; -+ sent++; -+ } + cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,) + cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,) + cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,) +@@ -174,6 +181,7 @@ + # + libs-$(CONFIG_ARC) += arch/mips/fw/arc/ + libs-$(CONFIG_CFE) += arch/mips/fw/cfe/ ++libs-$(CONFIG_MYLOADER) += arch/mips/fw/myloader/ + libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/ + libs-y += arch/mips/fw/lib/ + +diff -Nur linux-2.6.39.orig/arch/mips/pci/Makefile linux-2.6.39/arch/mips/pci/Makefile +--- linux-2.6.39.orig/arch/mips/pci/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/pci/Makefile 2011-08-22 16:21:37.437981205 +0200 +@@ -18,6 +18,7 @@ + obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o + obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ + ops-bcm63xx.o ++obj-$(CONFIG_ATHEROS_AR71XX) += pci-ar71xx.o pci-ar724x.o + + # + # These are still pretty much in the old state, watch, go blind. +diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c linux-2.6.39/arch/mips/pci/pci-ar71xx.c +--- linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/pci/pci-ar71xx.c 2011-08-06 09:32:37.098016752 +0200 +@@ -0,0 +1,415 @@ ++/* ++ * Atheros AR71xx PCI host controller driver ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ DBG("%s: %d packets sent out\n", ag->dev->name, sent); ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+ if ((ring->curr - ring->dirty) < AG71XX_TX_THRES_WAKEUP) -+ netif_wake_queue(ag->dev); ++#include ++#include + -+ return sent; -+} ++#undef DEBUG ++#ifdef DEBUG ++#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args) ++#else ++#define DBG(fmt, args...) ++#endif + -+static int ag71xx_rx_packets(struct ag71xx *ag, int limit) -+{ -+ struct net_device *dev = ag->dev; -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ int done = 0; ++#define AR71XX_PCI_DELAY 100 /* msecs */ + -+ DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n", -+ dev->name, limit, ring->curr, ring->dirty); ++#if 0 ++#define PCI_IDSEL_BASE PCI_IDSEL_ADL_START ++#else ++#define PCI_IDSEL_BASE 0 ++#endif + -+ while (done < limit) { -+ unsigned int i = ring->curr % AG71XX_RX_RING_SIZE; -+ struct ag71xx_desc *desc = ring->buf[i].desc; -+ struct sk_buff *skb; -+ int pktlen; -+ int err = 0; ++static void __iomem *ar71xx_pcicfg_base; ++static DEFINE_SPINLOCK(ar71xx_pci_lock); ++static int ar71xx_pci_fixup_enable; + -+ if (ag71xx_desc_empty(desc)) -+ break; ++static inline void ar71xx_pci_delay(void) ++{ ++ mdelay(AR71XX_PCI_DELAY); ++} + -+ if ((ring->dirty + AG71XX_RX_RING_SIZE) == ring->curr) { -+ ag71xx_assert(0); -+ break; -+ } ++/* Byte lane enable bits */ ++static u8 ble_table[4][4] = { ++ {0x0, 0xf, 0xf, 0xf}, ++ {0xe, 0xd, 0xb, 0x7}, ++ {0xc, 0xf, 0x3, 0xf}, ++ {0xf, 0xf, 0xf, 0xf}, ++}; + -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); ++static inline u32 ar71xx_pci_get_ble(int where, int size, int local) ++{ ++ u32 t; + -+ skb = ring->buf[i].skb; -+ pktlen = ag71xx_desc_pktlen(desc); -+ pktlen -= ETH_FCS_LEN; ++ t = ble_table[size & 3][where & 3]; ++ BUG_ON(t == 0xf); ++ t <<= (local) ? 20 : 4; ++ return t; ++} + -+ dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, -+ AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); ++static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn, ++ int where) ++{ ++ u32 ret; + -+ dev->last_rx = jiffies; -+ dev->stats.rx_packets++; -+ dev->stats.rx_bytes += pktlen; ++ if (!bus->number) { ++ /* type 0 */ ++ ret = (1 << (PCI_IDSEL_BASE + PCI_SLOT(devfn))) ++ | (PCI_FUNC(devfn) << 8) | (where & ~3); ++ } else { ++ /* type 1 */ ++ ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11) ++ | (PCI_FUNC(devfn) << 8) | (where & ~3) | 1; ++ } + -+ skb_put(skb, pktlen); -+ if (ag71xx_has_ar8216(ag)) -+ err = ag71xx_remove_ar8216_header(ag, skb, pktlen); ++ return ret; ++} + -+ if (err) { -+ dev->stats.rx_dropped++; -+ kfree_skb(skb); -+ } else { -+ skb->dev = dev; -+ skb->ip_summed = CHECKSUM_NONE; -+ if (ag->phy_dev) { -+ ag->phy_dev->netif_receive_skb(skb); -+ } else { -+ skb->protocol = eth_type_trans(skb, dev); -+ netif_receive_skb(skb); -+ } -+ } ++int ar71xx_pci_be_handler(int is_fixup) ++{ ++ void __iomem *base = ar71xx_pcicfg_base; ++ u32 pci_err; ++ u32 ahb_err; + -+ ring->buf[i].skb = NULL; -+ done++; ++ pci_err = __raw_readl(base + PCI_REG_PCI_ERR) & 3; ++ if (pci_err) { ++ if (!is_fixup) ++ printk(KERN_ALERT "PCI error %d at PCI addr 0x%x\n", ++ pci_err, ++ __raw_readl(base + PCI_REG_PCI_ERR_ADDR)); + -+ ring->curr++; ++ __raw_writel(pci_err, base + PCI_REG_PCI_ERR); + } + -+ ag71xx_ring_rx_refill(ag); ++ ahb_err = __raw_readl(base + PCI_REG_AHB_ERR) & 1; ++ if (ahb_err) { ++ if (!is_fixup) ++ printk(KERN_ALERT "AHB error at AHB address 0x%x\n", ++ __raw_readl(base + PCI_REG_AHB_ERR_ADDR)); + -+ DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n", -+ dev->name, ring->curr, ring->dirty, done); ++ __raw_writel(ahb_err, base + PCI_REG_AHB_ERR); ++ } + -+ return done; ++ return (ahb_err | pci_err) ? 1 : 0; +} + -+static int ag71xx_poll(struct napi_struct *napi, int limit) ++static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus, ++ unsigned int devfn, int where, int size, u32 cmd) +{ -+ struct ag71xx *ag = container_of(napi, struct ag71xx, napi); -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct net_device *dev = ag->dev; -+ struct ag71xx_ring *rx_ring; -+ unsigned long flags; -+ u32 status; -+ int tx_done; -+ int rx_done; -+ -+ pdata->ddr_flush(); -+ tx_done = ag71xx_tx_packets(ag); -+ -+ DBG("%s: processing RX ring\n", dev->name); -+ rx_done = ag71xx_rx_packets(ag, limit); -+ -+ ag71xx_debugfs_update_napi_stats(ag, rx_done, tx_done); ++ void __iomem *base = ar71xx_pcicfg_base; ++ u32 addr; + -+ rx_ring = &ag->rx_ring; -+ if (rx_ring->buf[rx_ring->dirty % AG71XX_RX_RING_SIZE].skb == NULL) -+ goto oom; ++ addr = ar71xx_pci_bus_addr(bus, devfn, where); + -+ status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); -+ if (unlikely(status & RX_STATUS_OF)) { -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF); -+ dev->stats.rx_fifo_errors++; ++ DBG("PCI: set cfgaddr: %02x:%02x.%01x/%02x:%01d, addr=%08x\n", ++ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), ++ where, size, addr); + -+ /* restart RX */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); -+ } ++ __raw_writel(addr, base + PCI_REG_CFG_AD); ++ __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0), ++ base + PCI_REG_CFG_CBE); + -+ if (rx_done < limit) { -+ if (status & RX_STATUS_PR) -+ goto more; ++ return ar71xx_pci_be_handler(1); ++} + -+ status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); -+ if (status & TX_STATUS_PS) -+ goto more; ++static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 *value) ++{ ++ void __iomem *base = ar71xx_pcicfg_base; ++ static u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0}; ++ unsigned long flags; ++ u32 data; ++ int retry = 0; ++ int ret; + -+ DBG("%s: disable polling mode, rx=%d, tx=%d,limit=%d\n", -+ dev->name, rx_done, tx_done, limit); ++ ret = PCIBIOS_SUCCESSFUL; + -+ napi_complete(napi); ++ DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d\n", bus->number, ++ PCI_SLOT(devfn), PCI_FUNC(devfn), where, size); + -+ /* enable interrupts */ -+ spin_lock_irqsave(&ag->lock, flags); -+ ag71xx_int_enable(ag, AG71XX_INT_POLL); -+ spin_unlock_irqrestore(&ag->lock, flags); -+ return rx_done; -+ } ++retry: ++ spin_lock_irqsave(&ar71xx_pci_lock, flags); + -+ more: -+ DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n", -+ dev->name, rx_done, tx_done, limit); -+ return rx_done; ++ if (bus->number == 0 && devfn == 0) { ++ u32 t; + -+ oom: -+ if (netif_msg_rx_err(ag)) -+ printk(KERN_DEBUG "%s: out of memory\n", dev->name); ++ t = PCI_CRP_CMD_READ | (where & ~3); + -+ mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL); -+ napi_complete(napi); -+ return 0; -+} ++ __raw_writel(t, base + PCI_REG_CRP_AD_CBE); ++ data = __raw_readl(base + PCI_REG_CRP_RDDATA); + -+static irqreturn_t ag71xx_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *dev = dev_id; -+ struct ag71xx *ag = netdev_priv(dev); -+ u32 status; ++ DBG("PCI: rd local cfg, ad_cbe:%08x, data:%08x\n", t, data); + -+ status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS); -+ ag71xx_dump_intr(ag, "raw", status); ++ } else { ++ int err; + -+ if (unlikely(!status)) -+ return IRQ_NONE; ++ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, ++ PCI_CFG_CMD_READ); + -+ if (unlikely(status & AG71XX_INT_ERR)) { -+ if (status & AG71XX_INT_TX_BE) { -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE); -+ dev_err(&dev->dev, "TX BUS error\n"); -+ } -+ if (status & AG71XX_INT_RX_BE) { -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE); -+ dev_err(&dev->dev, "RX BUS error\n"); ++ if (err == 0) { ++ data = __raw_readl(base + PCI_REG_CFG_RDDATA); ++ } else { ++ ret = PCIBIOS_DEVICE_NOT_FOUND; ++ data = ~0; + } + } + -+ if (likely(status & AG71XX_INT_POLL)) { -+ ag71xx_int_disable(ag, AG71XX_INT_POLL); -+ DBG("%s: enable polling mode\n", dev->name); -+ napi_schedule(&ag->napi); -+ } ++ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); + -+ ag71xx_debugfs_update_int_stats(ag, status); ++ DBG("PCI: read config: data=%08x raw=%08x\n", ++ (data >> (8 * (where & 3))) & mask[size & 7], data); + -+ return IRQ_HANDLED; -+} ++ *value = (data >> (8 * (where & 3))) & mask[size & 7]; + -+static void ag71xx_set_multicast_list(struct net_device *dev) -+{ -+ /* TODO */ -+} ++ /* ++ * PCI controller bug: sometimes reads to the PCI_COMMAND register ++ * return 0xffff, even though the PCI trace shows the correct value. ++ * Work around this by retrying reads to this register ++ */ ++ if (where == PCI_COMMAND && (*value & 0xffff) == 0xffff && retry++ < 2) ++ goto retry; + -+#ifdef CONFIG_NET_POLL_CONTROLLER -+/* -+ * Polling 'interrupt' - used by things like netconsole to send skbs -+ * without having to re-enable interrupts. It's not called while -+ * the interrupt routine is executing. -+ */ -+static void ag71xx_netpoll(struct net_device *dev) -+{ -+ disable_irq(dev->irq); -+ ag71xx_interrupt(dev->irq, dev); -+ enable_irq(dev->irq); ++ return ret; +} -+#endif -+ -+static const struct net_device_ops ag71xx_netdev_ops = { -+ .ndo_open = ag71xx_open, -+ .ndo_stop = ag71xx_stop, -+ .ndo_start_xmit = ag71xx_hard_start_xmit, -+ .ndo_set_multicast_list = ag71xx_set_multicast_list, -+ .ndo_do_ioctl = ag71xx_do_ioctl, -+ .ndo_tx_timeout = ag71xx_tx_timeout, -+ .ndo_change_mtu = eth_change_mtu, -+ .ndo_set_mac_address = eth_mac_addr, -+ .ndo_validate_addr = eth_validate_addr, -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ .ndo_poll_controller = ag71xx_netpoll, -+#endif -+}; + -+static int __init ag71xx_probe(struct platform_device *pdev) ++static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 value) +{ -+ struct net_device *dev; -+ struct resource *res; -+ struct ag71xx *ag; -+ struct ag71xx_platform_data *pdata; -+ int err; ++ void __iomem *base = ar71xx_pcicfg_base; ++ unsigned long flags; ++ int ret; + -+ pdata = pdev->dev.platform_data; -+ if (!pdata) { -+ dev_err(&pdev->dev, "no platform data specified\n"); -+ err = -ENXIO; -+ goto err_out; -+ } ++ DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d value=%08x\n", ++ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), ++ where, size, value); + -+ if (pdata->mii_bus_dev == NULL) { -+ dev_err(&pdev->dev, "no MII bus device specified\n"); -+ err = -EINVAL; -+ goto err_out; -+ } ++ value = value << (8 * (where & 3)); ++ ret = PCIBIOS_SUCCESSFUL; + -+ dev = alloc_etherdev(sizeof(*ag)); -+ if (!dev) { -+ dev_err(&pdev->dev, "alloc_etherdev failed\n"); -+ err = -ENOMEM; -+ goto err_out; -+ } ++ spin_lock_irqsave(&ar71xx_pci_lock, flags); ++ if (bus->number == 0 && devfn == 0) { ++ u32 t; + -+ SET_NETDEV_DEV(dev, &pdev->dev); ++ t = PCI_CRP_CMD_WRITE | (where & ~3); ++ t |= ar71xx_pci_get_ble(where, size, 1); + -+ ag = netdev_priv(dev); -+ ag->pdev = pdev; -+ ag->dev = dev; -+ ag->msg_enable = netif_msg_init(ag71xx_msg_level, -+ AG71XX_DEFAULT_MSG_ENABLE); -+ spin_lock_init(&ag->lock); ++ DBG("PCI: wr local cfg, ad_cbe:%08x, value:%08x\n", t, value); + -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base"); -+ if (!res) { -+ dev_err(&pdev->dev, "no mac_base resource found\n"); -+ err = -ENXIO; -+ goto err_out; -+ } ++ __raw_writel(t, base + PCI_REG_CRP_AD_CBE); ++ __raw_writel(value, base + PCI_REG_CRP_WRDATA); ++ } else { ++ int err; + -+ ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!ag->mac_base) { -+ dev_err(&pdev->dev, "unable to ioremap mac_base\n"); -+ err = -ENOMEM; -+ goto err_free_dev; -+ } ++ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, ++ PCI_CFG_CMD_WRITE); + -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mii_ctrl"); -+ if (!res) { -+ dev_err(&pdev->dev, "no mii_ctrl resource found\n"); -+ err = -ENXIO; -+ goto err_unmap_base; ++ if (err == 0) ++ __raw_writel(value, base + PCI_REG_CFG_WRDATA); ++ else ++ ret = PCIBIOS_DEVICE_NOT_FOUND; + } ++ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); + -+ ag->mii_ctrl = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!ag->mii_ctrl) { -+ dev_err(&pdev->dev, "unable to ioremap mii_ctrl\n"); -+ err = -ENOMEM; -+ goto err_unmap_base; -+ } ++ return ret; ++} + -+ dev->irq = platform_get_irq(pdev, 0); -+ err = request_irq(dev->irq, ag71xx_interrupt, -+ IRQF_DISABLED | IRQF_SAMPLE_RANDOM, -+ dev->name, dev); -+ if (err) { -+ dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq); -+ goto err_unmap_mii_ctrl; -+ } ++static void ar71xx_pci_fixup(struct pci_dev *dev) ++{ ++ u32 t; + -+ dev->base_addr = (unsigned long)ag->mac_base; -+ dev->netdev_ops = &ag71xx_netdev_ops; -+ dev->ethtool_ops = &ag71xx_ethtool_ops; ++ if (!ar71xx_pci_fixup_enable) ++ return; + -+ INIT_WORK(&ag->restart_work, ag71xx_restart_work_func); ++ if (dev->bus->number != 0 || dev->devfn != 0) ++ return; + -+ init_timer(&ag->oom_timer); -+ ag->oom_timer.data = (unsigned long) dev; -+ ag->oom_timer.function = ag71xx_oom_timer_handler; ++ DBG("PCI: fixup host controller %s (%04x:%04x)\n", pci_name(dev), ++ dev->vendor, dev->device); + -+ memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN); ++ /* setup COMMAND register */ ++ t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE ++ | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; + -+ netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT); ++ pci_write_config_word(dev, PCI_COMMAND, t); ++} ++DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar71xx_pci_fixup); + -+ err = register_netdev(dev); -+ if (err) { -+ dev_err(&pdev->dev, "unable to register net device\n"); -+ goto err_free_irq; ++int __init ar71xx_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, ++ uint8_t pin) ++{ ++ int irq = -1; ++ int i; ++ ++ slot -= PCI_IDSEL_ADL_START - PCI_IDSEL_BASE; ++ ++ for (i = 0; i < ar71xx_pci_nr_irqs; i++) { ++ struct ar71xx_pci_irq *entry; ++ ++ entry = &ar71xx_pci_irq_map[i]; ++ if (entry->slot == slot && entry->pin == pin) { ++ irq = entry->irq; ++ break; ++ } + } + -+ printk(KERN_INFO "%s: Atheros AG71xx at 0x%08lx, irq %d\n", -+ dev->name, dev->base_addr, dev->irq); ++ if (irq < 0) { ++ printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n", ++ pin, pci_name((struct pci_dev *)dev)); ++ } else { ++ printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n", ++ irq, pin, pci_name((struct pci_dev *)dev)); ++ } + -+ ag71xx_dump_regs(ag); ++ return irq; ++} + -+ ag71xx_hw_init(ag); ++static struct pci_ops ar71xx_pci_ops = { ++ .read = ar71xx_pci_read_config, ++ .write = ar71xx_pci_write_config, ++}; + -+ ag71xx_dump_regs(ag); ++static struct resource ar71xx_pci_io_resource = { ++ .name = "PCI IO space", ++ .start = 0, ++ .end = 0, ++ .flags = IORESOURCE_IO, ++}; + -+ err = ag71xx_phy_connect(ag); -+ if (err) -+ goto err_unregister_netdev; ++static struct resource ar71xx_pci_mem_resource = { ++ .name = "PCI memory space", ++ .start = AR71XX_PCI_MEM_BASE, ++ .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, ++ .flags = IORESOURCE_MEM ++}; + -+ err = ag71xx_debugfs_init(ag); -+ if (err) -+ goto err_phy_disconnect; ++static struct pci_controller ar71xx_pci_controller = { ++ .pci_ops = &ar71xx_pci_ops, ++ .mem_resource = &ar71xx_pci_mem_resource, ++ .io_resource = &ar71xx_pci_io_resource, ++}; + -+ platform_set_drvdata(pdev, dev); ++static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) ++{ ++ void __iomem *base = ar71xx_reset_base; ++ u32 pending; + -+ return 0; ++ pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) & ++ __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); + -+ err_phy_disconnect: -+ ag71xx_phy_disconnect(ag); -+ err_unregister_netdev: -+ unregister_netdev(dev); -+ err_free_irq: -+ free_irq(dev->irq, dev); -+ err_unmap_mii_ctrl: -+ iounmap(ag->mii_ctrl); -+ err_unmap_base: -+ iounmap(ag->mac_base); -+ err_free_dev: -+ kfree(dev); -+ err_out: -+ platform_set_drvdata(pdev, NULL); -+ return err; ++ if (pending & PCI_INT_DEV0) ++ generic_handle_irq(AR71XX_PCI_IRQ_DEV0); ++ ++ else if (pending & PCI_INT_DEV1) ++ generic_handle_irq(AR71XX_PCI_IRQ_DEV1); ++ ++ else if (pending & PCI_INT_DEV2) ++ generic_handle_irq(AR71XX_PCI_IRQ_DEV2); ++ ++ else if (pending & PCI_INT_CORE) ++ generic_handle_irq(AR71XX_PCI_IRQ_CORE); ++ ++ else ++ spurious_interrupt(); +} + -+static int __exit ag71xx_remove(struct platform_device *pdev) ++static void ar71xx_pci_irq_unmask(struct irq_data *d) +{ -+ struct net_device *dev = platform_get_drvdata(pdev); ++ unsigned int irq = d->irq - AR71XX_PCI_IRQ_BASE; ++ void __iomem *base = ar71xx_reset_base; ++ u32 t; + -+ if (dev) { -+ struct ag71xx *ag = netdev_priv(dev); ++ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); + -+ ag71xx_debugfs_exit(ag); -+ ag71xx_phy_disconnect(ag); -+ unregister_netdev(dev); -+ free_irq(dev->irq, dev); -+ iounmap(ag->mii_ctrl); -+ iounmap(ag->mac_base); -+ kfree(dev); -+ platform_set_drvdata(pdev, NULL); -+ } ++ /* flush write */ ++ (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++} + -+ return 0; ++static void ar71xx_pci_irq_mask(struct irq_data *d) ++{ ++ unsigned int irq = d->irq - AR71XX_PCI_IRQ_BASE; ++ void __iomem *base = ar71xx_reset_base; ++ u32 t; ++ ++ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ ++ /* flush write */ ++ (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); +} + -+static struct platform_driver ag71xx_driver = { -+ .probe = ag71xx_probe, -+ .remove = __exit_p(ag71xx_remove), -+ .driver = { -+ .name = AG71XX_DRV_NAME, -+ } ++static struct irq_chip ar71xx_pci_irq_chip = { ++ .name = "AR71XX PCI ", ++ .irq_mask = ar71xx_pci_irq_mask, ++ .irq_unmask = ar71xx_pci_irq_unmask, ++ .irq_mask_ack = ar71xx_pci_irq_mask, +}; + -+static int __init ag71xx_module_init(void) ++static void __init ar71xx_pci_irq_init(void) +{ -+ int ret; -+ -+ ret = ag71xx_debugfs_root_init(); -+ if (ret) -+ goto err_out; -+ -+ ret = ag71xx_mdio_driver_init(); -+ if (ret) -+ goto err_debugfs_exit; ++ void __iomem *base = ar71xx_reset_base; ++ int i; + -+ ret = platform_driver_register(&ag71xx_driver); -+ if (ret) -+ goto err_mdio_exit; ++ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS); + -+ return 0; ++ for (i = AR71XX_PCI_IRQ_BASE; ++ i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) ++ irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip, ++ handle_level_irq); + -+ err_mdio_exit: -+ ag71xx_mdio_driver_exit(); -+ err_debugfs_exit: -+ ag71xx_debugfs_root_exit(); -+ err_out: -+ return ret; ++ irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar71xx_pci_irq_handler); +} + -+static void __exit ag71xx_module_exit(void) ++int __init ar71xx_pcibios_init(void) +{ -+ platform_driver_unregister(&ag71xx_driver); -+ ag71xx_mdio_driver_exit(); -+ ag71xx_debugfs_root_exit(); -+} ++ void __iomem *ddr_base = ar71xx_ddr_base; + -+module_init(ag71xx_module_init); -+module_exit(ag71xx_module_exit); ++ ar71xx_device_stop(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE); ++ ar71xx_pci_delay(); + -+MODULE_VERSION(AG71XX_DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_AUTHOR("Imre Kaloz "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" AG71XX_DRV_NAME); -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,243 @@ ++ ar71xx_device_start(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE); ++ ar71xx_pci_delay(); ++ ++ ar71xx_pcicfg_base = ioremap_nocache(AR71XX_PCI_CFG_BASE, ++ AR71XX_PCI_CFG_SIZE); ++ if (ar71xx_pcicfg_base == NULL) ++ return -ENOMEM; ++ ++ __raw_writel(PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0); ++ __raw_writel(PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1); ++ __raw_writel(PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2); ++ __raw_writel(PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3); ++ __raw_writel(PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4); ++ __raw_writel(PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5); ++ __raw_writel(PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6); ++ __raw_writel(PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7); ++ ++ ar71xx_pci_delay(); ++ ++ /* clear bus errors */ ++ (void)ar71xx_pci_be_handler(1); ++ ++ ar71xx_pci_fixup_enable = 1; ++ ar71xx_pci_irq_init(); ++ register_pci_controller(&ar71xx_pci_controller); ++ ++ return 0; ++} +diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c linux-2.6.39/arch/mips/pci/pci-ar724x.c +--- linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/pci/pci-ar724x.c 2011-08-06 09:32:37.088017079 +0200 +@@ -0,0 +1,389 @@ +/* -+ * Atheros AR71xx built-in ethernet mac driver ++ * Atheros AR724x PCI host controller driver + * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009-2010 Gabor Juhos + * -+ * Based on Atheros' AG7100 driver ++ * Parts of this file are based on Atheros' 2.6.15 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include "ag71xx.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+#define AG71XX_MDIO_RETRY 1000 -+#define AG71XX_MDIO_DELAY 5 ++#include ++#include + -+static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg, -+ u32 value) -+{ -+ void __iomem *r; ++#undef DEBUG ++#ifdef DEBUG ++#define DBG(fmt, args...) printk(KERN_INFO fmt, ## args) ++#else ++#define DBG(fmt, args...) ++#endif + -+ r = am->mdio_base + reg; -+ __raw_writel(value, r); ++static void __iomem *ar724x_pci_localcfg_base; ++static void __iomem *ar724x_pci_devcfg_base; ++static void __iomem *ar724x_pci_ctrl_base; ++static int ar724x_pci_fixup_enable; + -+ /* flush write */ -+ (void) __raw_readl(r); -+} ++static DEFINE_SPINLOCK(ar724x_pci_lock); + -+static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg) ++static void ar724x_pci_read(void __iomem *base, int where, int size, u32 *value) +{ -+ return __raw_readl(am->mdio_base + reg); -+} ++ unsigned long flags; ++ u32 data; + -+static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am) -+{ -+ DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n", -+ am->mii_bus->name, -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR)); -+ DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n", -+ am->mii_bus->name, -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_IND)); ++ spin_lock_irqsave(&ar724x_pci_lock, flags); ++ data = __raw_readl(base + (where & ~3)); ++ ++ switch (size) { ++ case 1: ++ if (where & 1) ++ data >>= 8; ++ if (where & 2) ++ data >>= 16; ++ data &= 0xFF; ++ break; ++ case 2: ++ if (where & 2) ++ data >>= 16; ++ data &= 0xFFFF; ++ break; ++ } ++ ++ *value = data; ++ spin_unlock_irqrestore(&ar724x_pci_lock, flags); +} + -+static int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg) ++static void ar724x_pci_write(void __iomem *base, int where, int size, u32 value) +{ -+ int ret; -+ int i; ++ unsigned long flags; ++ u32 data; ++ int s; + -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, -+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ); ++ spin_lock_irqsave(&ar724x_pci_lock, flags); ++ data = __raw_readl(base + (where & ~3)); + -+ i = AG71XX_MDIO_RETRY; -+ while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { -+ if (i-- == 0) { -+ printk(KERN_ERR "%s: mii_read timed out\n", -+ am->mii_bus->name); -+ ret = 0xffff; -+ goto out; -+ } -+ udelay(AG71XX_MDIO_DELAY); ++ switch (size) { ++ case 1: ++ s = ((where & 3) << 3); ++ data &= ~(0xFF << s); ++ data |= ((value & 0xFF) << s); ++ break; ++ case 2: ++ s = ((where & 2) << 3); ++ data &= ~(0xFFFF << s); ++ data |= ((value & 0xFFFF) << s); ++ break; ++ case 4: ++ data = value; ++ break; + } + -+ ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff; -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); -+ -+ DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret); -+ -+ out: -+ return ret; ++ __raw_writel(data, base + (where & ~3)); ++ /* flush write */ ++ (void)__raw_readl(base + (where & ~3)); ++ spin_unlock_irqrestore(&ar724x_pci_lock, flags); +} + -+static void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, -+ int addr, int reg, u16 val) ++static int ar724x_pci_read_config(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 *value) +{ -+ int i; + -+ DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val); ++ if (bus->number != 0 || devfn != 0) ++ return PCIBIOS_DEVICE_NOT_FOUND; + -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, -+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val); ++ ar724x_pci_read(ar724x_pci_devcfg_base, where, size, value); + -+ i = AG71XX_MDIO_RETRY; -+ while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { -+ if (i-- == 0) { -+ printk(KERN_ERR "%s: mii_write timed out\n", -+ am->mii_bus->name); -+ break; -+ } -+ udelay(AG71XX_MDIO_DELAY); ++ DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d, value=%08x\n", ++ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), ++ where, size, *value); ++ ++ /* ++ * WAR for BAR issue - We are unable to access the PCI device space ++ * if we set the BAR with proper base address ++ */ ++ if ((where == 0x10) && (size == 4)) { ++ u32 val; ++ val = (ar71xx_soc == AR71XX_SOC_AR7240) ? 0xffff : 0x1000ffff; ++ ar724x_pci_write(ar724x_pci_devcfg_base, where, size, val); + } ++ ++ return PCIBIOS_SUCCESSFUL; +} + -+static int ag71xx_mdio_reset(struct mii_bus *bus) ++static int ar724x_pci_write_config(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 value) +{ -+ struct ag71xx_mdio *am = bus->priv; -+ u32 t; -+ -+ if (am->pdata->is_ar7240) -+ t = MII_CFG_CLK_DIV_6; -+ else -+ t = MII_CFG_CLK_DIV_28; ++ if (bus->number != 0 || devfn != 0) ++ return PCIBIOS_DEVICE_NOT_FOUND; + -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET); -+ udelay(100); ++ DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d, value=%08x\n", ++ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), ++ where, size, value); + -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t); -+ udelay(100); ++ ar724x_pci_write(ar724x_pci_devcfg_base, where, size, value); + -+ return 0; ++ return PCIBIOS_SUCCESSFUL; +} + -+static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg) ++static void ar724x_pci_fixup(struct pci_dev *dev) +{ -+ struct ag71xx_mdio *am = bus->priv; ++ u16 cmd; + -+ return ag71xx_mdio_mii_read(am, addr, reg); -+} ++ if (!ar724x_pci_fixup_enable) ++ return; + -+static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) -+{ -+ struct ag71xx_mdio *am = bus->priv; ++ if (dev->bus->number != 0 || dev->devfn != 0) ++ return; + -+ ag71xx_mdio_mii_write(am, addr, reg, val); -+ return 0; ++ /* setup COMMAND register */ ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | ++ PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | ++ PCI_COMMAND_FAST_BACK; ++ ++ pci_write_config_word(dev, PCI_COMMAND, cmd); +} ++DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar724x_pci_fixup); + -+static int __init ag71xx_mdio_probe(struct platform_device *pdev) ++int __init ar724x_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, ++ uint8_t pin) +{ -+ struct ag71xx_mdio_platform_data *pdata; -+ struct ag71xx_mdio *am; -+ struct resource *res; ++ int irq = -1; + int i; -+ int err; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) { -+ dev_err(&pdev->dev, "no platform data specified\n"); -+ return -EINVAL; -+ } -+ -+ am = kzalloc(sizeof(*am), GFP_KERNEL); -+ if (!am) { -+ err = -ENOMEM; -+ goto err_out; -+ } + -+ am->pdata = pdata; ++ for (i = 0; i < ar71xx_pci_nr_irqs; i++) { ++ struct ar71xx_pci_irq *entry; ++ entry = &ar71xx_pci_irq_map[i]; + -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "no iomem resource found\n"); -+ err = -ENXIO; -+ goto err_out; ++ if (entry->slot == slot && entry->pin == pin) { ++ irq = entry->irq; ++ break; ++ } + } + -+ am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!am->mdio_base) { -+ dev_err(&pdev->dev, "unable to ioremap registers\n"); -+ err = -ENOMEM; -+ goto err_free_mdio; -+ } ++ if (irq < 0) ++ printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n", ++ pin, pci_name((struct pci_dev *)dev)); ++ else ++ printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n", ++ irq, pin, pci_name((struct pci_dev *)dev)); + -+ am->mii_bus = mdiobus_alloc(); -+ if (am->mii_bus == NULL) { -+ err = -ENOMEM; -+ goto err_iounmap; -+ } ++ return irq; ++} + -+ am->mii_bus->name = "ag71xx_mdio"; -+ am->mii_bus->read = ag71xx_mdio_read; -+ am->mii_bus->write = ag71xx_mdio_write; -+ am->mii_bus->reset = ag71xx_mdio_reset; -+ am->mii_bus->irq = am->mii_irq; -+ am->mii_bus->priv = am; -+ am->mii_bus->parent = &pdev->dev; -+ snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev)); -+ am->mii_bus->phy_mask = pdata->phy_mask; ++static struct pci_ops ar724x_pci_ops = { ++ .read = ar724x_pci_read_config, ++ .write = ar724x_pci_write_config, ++}; + -+ for (i = 0; i < PHY_MAX_ADDR; i++) -+ am->mii_irq[i] = PHY_POLL; ++static struct resource ar724x_pci_io_resource = { ++ .name = "PCI IO space", ++ .start = 0, ++ .end = 0, ++ .flags = IORESOURCE_IO, ++}; + -+ ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0); ++static struct resource ar724x_pci_mem_resource = { ++ .name = "PCI memory space", ++ .start = AR71XX_PCI_MEM_BASE, ++ .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, ++ .flags = IORESOURCE_MEM ++}; + -+ err = mdiobus_register(am->mii_bus); -+ if (err) -+ goto err_free_bus; -+ -+ ag71xx_mdio_dump_regs(am); ++static struct pci_controller ar724x_pci_controller = { ++ .pci_ops = &ar724x_pci_ops, ++ .mem_resource = &ar724x_pci_mem_resource, ++ .io_resource = &ar724x_pci_io_resource, ++}; + -+ platform_set_drvdata(pdev, am); -+ return 0; ++static void __init ar724x_pci_reset(void) ++{ ++ ar71xx_device_stop(AR724X_RESET_PCIE); ++ ar71xx_device_stop(AR724X_RESET_PCIE_PHY); ++ ar71xx_device_stop(AR724X_RESET_PCIE_PHY_SERIAL); ++ udelay(100); + -+ err_free_bus: -+ mdiobus_free(am->mii_bus); -+ err_iounmap: -+ iounmap(am->mdio_base); -+ err_free_mdio: -+ kfree(am); -+ err_out: -+ return err; ++ ar71xx_device_start(AR724X_RESET_PCIE_PHY_SERIAL); ++ udelay(100); ++ ar71xx_device_start(AR724X_RESET_PCIE_PHY); ++ ar71xx_device_start(AR724X_RESET_PCIE); +} + -+static int __exit ag71xx_mdio_remove(struct platform_device *pdev) ++static int __init ar724x_pci_setup(void) +{ -+ struct ag71xx_mdio *am = platform_get_drvdata(pdev); ++ void __iomem *base = ar724x_pci_ctrl_base; ++ u32 t; + -+ if (am) { -+ mdiobus_unregister(am->mii_bus); -+ mdiobus_free(am->mii_bus); -+ iounmap(am->mdio_base); -+ kfree(am); -+ platform_set_drvdata(pdev, NULL); ++ /* setup COMMAND register */ ++ t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | ++ PCI_COMMAND_PARITY|PCI_COMMAND_SERR|PCI_COMMAND_FAST_BACK; ++ ++ ar724x_pci_write(ar724x_pci_localcfg_base, PCI_COMMAND, 4, t); ++ ar724x_pci_write(ar724x_pci_localcfg_base, 0x20, 4, 0x1ff01000); ++ ar724x_pci_write(ar724x_pci_localcfg_base, 0x24, 4, 0x1ff01000); ++ ++ t = __raw_readl(base + AR724X_PCI_REG_RESET); ++ if (t != 0x7) { ++ udelay(100000); ++ __raw_writel(0, base + AR724X_PCI_REG_RESET); ++ udelay(100); ++ __raw_writel(4, base + AR724X_PCI_REG_RESET); ++ udelay(100000); + } + -+ return 0; -+} ++ if (ar71xx_soc == AR71XX_SOC_AR7240) ++ t = AR724X_PCI_APP_LTSSM_ENABLE; ++ else ++ t = 0x1ffc1; ++ __raw_writel(t, base + AR724X_PCI_REG_APP); ++ /* flush write */ ++ (void) __raw_readl(base + AR724X_PCI_REG_APP); ++ udelay(1000); + -+static struct platform_driver ag71xx_mdio_driver = { -+ .probe = ag71xx_mdio_probe, -+ .remove = __exit_p(ag71xx_mdio_remove), -+ .driver = { -+ .name = "ag71xx-mdio", ++ t = __raw_readl(base + AR724X_PCI_REG_RESET); ++ if ((t & AR724X_PCI_RESET_LINK_UP) == 0x0) { ++ printk(KERN_WARNING "PCI: no PCIe module found\n"); ++ return -ENODEV; + } -+}; + -+int ag71xx_mdio_driver_init(void) -+{ -+ return platform_driver_register(&ag71xx_mdio_driver); -+} ++ if (ar71xx_soc == AR71XX_SOC_AR7241 || ++ ar71xx_soc == AR71XX_SOC_AR7242) { ++ t = __raw_readl(base + AR724X_PCI_REG_APP); ++ t |= BIT(16); ++ __raw_writel(t, base + AR724X_PCI_REG_APP); ++ } + -+void ag71xx_mdio_driver_exit(void) -+{ -+ platform_driver_unregister(&ag71xx_mdio_driver); ++ return 0; +} -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,213 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ag71xx.h" + -+static void ag71xx_phy_link_adjust(struct net_device *dev) ++static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) +{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct phy_device *phydev = ag->phy_dev; -+ unsigned long flags; -+ int status_change = 0; -+ -+ spin_lock_irqsave(&ag->lock, flags); -+ -+ if (phydev->link) { -+ if (ag->duplex != phydev->duplex -+ || ag->speed != phydev->speed) { -+ status_change = 1; -+ } -+ } -+ -+ if (phydev->link != ag->link) -+ status_change = 1; ++ void __iomem *base = ar724x_pci_ctrl_base; ++ u32 pending; + -+ ag->link = phydev->link; -+ ag->duplex = phydev->duplex; -+ ag->speed = phydev->speed; ++ pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & ++ __raw_readl(base + AR724X_PCI_REG_INT_MASK); + -+ if (status_change) -+ ag71xx_link_adjust(ag); ++ if (pending & AR724X_PCI_INT_DEV0) ++ generic_handle_irq(AR71XX_PCI_IRQ_DEV0); + -+ spin_unlock_irqrestore(&ag->lock, flags); ++ else ++ spurious_interrupt(); +} + -+void ag71xx_phy_start(struct ag71xx *ag) ++static void ar724x_pci_irq_unmask(struct irq_data *d) +{ -+ if (ag->phy_dev) { -+ phy_start(ag->phy_dev); -+ } else { -+ ag->link = 1; -+ ag71xx_link_adjust(ag); ++ void __iomem *base = ar724x_pci_ctrl_base; ++ u32 t; ++ ++ switch (d->irq) { ++ case AR71XX_PCI_IRQ_DEV0: ++ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ __raw_writel(t | AR724X_PCI_INT_DEV0, ++ base + AR724X_PCI_REG_INT_MASK); ++ /* flush write */ ++ (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK); + } +} + -+void ag71xx_phy_stop(struct ag71xx *ag) ++static void ar724x_pci_irq_mask(struct irq_data *d) +{ -+ if (ag->phy_dev) { -+ phy_stop(ag->phy_dev); -+ } else { -+ ag->link = 0; -+ ag71xx_link_adjust(ag); ++ void __iomem *base = ar724x_pci_ctrl_base; ++ u32 t; ++ ++ switch (d->irq) { ++ case AR71XX_PCI_IRQ_DEV0: ++ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ __raw_writel(t & ~AR724X_PCI_INT_DEV0, ++ base + AR724X_PCI_REG_INT_MASK); ++ ++ /* flush write */ ++ (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ ++ t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS); ++ __raw_writel(t | AR724X_PCI_INT_DEV0, ++ base + AR724X_PCI_REG_INT_STATUS); ++ ++ /* flush write */ ++ (void) __raw_readl(base + AR724X_PCI_REG_INT_STATUS); + } +} + -+static int ag71xx_phy_connect_fixed(struct ag71xx *ag) ++static struct irq_chip ar724x_pci_irq_chip = { ++ .name = "AR724X PCI ", ++ .irq_mask = ar724x_pci_irq_mask, ++ .irq_unmask = ar724x_pci_irq_unmask, ++ .irq_mask_ack = ar724x_pci_irq_mask, ++}; ++ ++static void __init ar724x_pci_irq_init(void) +{ -+ struct net_device *dev = ag->dev; -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ int ret = 0; ++ void __iomem *base = ar724x_pci_ctrl_base; ++ u32 t; ++ int i; + -+ /* use fixed settings */ -+ switch (pdata->speed) { -+ case SPEED_10: -+ case SPEED_100: -+ case SPEED_1000: -+ break; -+ default: -+ printk(KERN_ERR "%s: invalid speed specified\n", dev->name); -+ ret = -EINVAL; -+ break; ++ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); ++ if (t & (AR724X_RESET_PCIE | AR724X_RESET_PCIE_PHY | ++ AR724X_RESET_PCIE_PHY_SERIAL)) { ++ return; + } + -+ printk(KERN_DEBUG "%s: using fixed link parameters\n", dev->name); ++ __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); ++ __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); + -+ ag->duplex = pdata->duplex; -+ ag->speed = pdata->speed; ++ for (i = AR71XX_PCI_IRQ_BASE; ++ i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) ++ irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, ++ handle_level_irq); + -+ return ret; ++ irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar724x_pci_irq_handler); +} + -+static int ag71xx_phy_connect_multi(struct ag71xx *ag) ++int __init ar724x_pcibios_init(void) +{ -+ struct net_device *dev = ag->dev; -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct phy_device *phydev = NULL; -+ int phy_addr; -+ int ret = 0; ++ int ret = -ENOMEM; + -+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { -+ if (!(pdata->phy_mask & (1 << phy_addr))) -+ continue; ++ ar724x_pci_localcfg_base = ioremap_nocache(AR724X_PCI_CRP_BASE, ++ AR724X_PCI_CRP_SIZE); ++ if (ar724x_pci_localcfg_base == NULL) ++ goto err; + -+ if (ag->mii_bus->phy_map[phy_addr] == NULL) -+ continue; ++ ar724x_pci_devcfg_base = ioremap_nocache(AR724X_PCI_CFG_BASE, ++ AR724X_PCI_CFG_SIZE); ++ if (ar724x_pci_devcfg_base == NULL) ++ goto err_unmap_localcfg; + -+ DBG("%s: PHY found at %s, uid=%08x\n", -+ dev->name, -+ dev_name(&ag->mii_bus->phy_map[phy_addr]->dev), -+ ag->mii_bus->phy_map[phy_addr]->phy_id); ++ ar724x_pci_ctrl_base = ioremap_nocache(AR724X_PCI_CTRL_BASE, ++ AR724X_PCI_CTRL_SIZE); ++ if (ar724x_pci_ctrl_base == NULL) ++ goto err_unmap_devcfg; + -+ if (phydev == NULL) -+ phydev = ag->mii_bus->phy_map[phy_addr]; -+ } ++ ar724x_pci_reset(); ++ ret = ar724x_pci_setup(); ++ if (ret) ++ goto err_unmap_ctrl; + -+ if (!phydev) { -+ printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n", -+ dev->name, pdata->phy_mask); -+ return -ENODEV; -+ } ++ ar724x_pci_fixup_enable = 1; ++ ar724x_pci_irq_init(); ++ register_pci_controller(&ar724x_pci_controller); + -+ ag->phy_dev = phy_connect(dev, dev_name(&phydev->dev), -+ &ag71xx_phy_link_adjust, 0, -+ pdata->phy_if_mode); -+ -+ if (IS_ERR(ag->phy_dev)) { -+ printk(KERN_ERR "%s: could not connect to PHY at %s\n", -+ dev->name, dev_name(&phydev->dev)); -+ return PTR_ERR(ag->phy_dev); -+ } ++ return 0; + -+ /* mask with MAC supported features */ -+ if (pdata->has_gbit) -+ phydev->supported &= PHY_GBIT_FEATURES; -+ else -+ phydev->supported &= PHY_BASIC_FEATURES; ++err_unmap_ctrl: ++ iounmap(ar724x_pci_ctrl_base); ++err_unmap_devcfg: ++ iounmap(ar724x_pci_devcfg_base); ++err_unmap_localcfg: ++ iounmap(ar724x_pci_localcfg_base); ++err: ++ return ret; ++} +diff -Nur linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c linux-2.6.39/drivers/gpio/nxp_74hc153.c +--- linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/gpio/nxp_74hc153.c 2011-04-27 12:19:22.327664626 +0200 +@@ -0,0 +1,247 @@ ++/* ++ * NXP 74HC153 - Dual 4-input multiplexer GPIO driver ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ + -+ phydev->advertising = phydev->supported; ++#include ++#include ++#include ++#include ++#include ++#include + -+ printk(KERN_DEBUG "%s: connected to PHY at %s [uid=%08x, driver=%s]\n", -+ dev->name, dev_name(&phydev->dev), -+ phydev->phy_id, phydev->drv->name); ++#define NXP_74HC153_NUM_GPIOS 8 ++#define NXP_74HC153_S0_MASK 0x1 ++#define NXP_74HC153_S1_MASK 0x2 ++#define NXP_74HC153_BANK_MASK 0x4 + -+ ag->link = 0; -+ ag->speed = 0; -+ ag->duplex = -1; ++struct nxp_74hc153_chip { ++ struct device *parent; ++ struct gpio_chip gpio_chip; ++ struct mutex lock; ++}; + -+ return ret; ++static struct nxp_74hc153_chip *gpio_to_nxp(struct gpio_chip *gc) ++{ ++ return container_of(gc, struct nxp_74hc153_chip, gpio_chip); +} + -+static int dev_is_class(struct device *dev, void *class) ++static int nxp_74hc153_direction_input(struct gpio_chip *gc, unsigned offset) +{ -+ if (dev->class != NULL && !strcmp(dev->class->name, class)) -+ return 1; -+ + return 0; +} + -+static struct device *dev_find_class(struct device *parent, char *class) ++static int nxp_74hc153_direction_output(struct gpio_chip *gc, ++ unsigned offset, int val) +{ -+ if (dev_is_class(parent, class)) { -+ get_device(parent); -+ return parent; -+ } -+ -+ return device_find_child(parent, class, dev_is_class); ++ return -EINVAL; +} + -+static struct mii_bus *dev_to_mii_bus(struct device *dev) ++static int nxp_74hc153_get_value(struct gpio_chip *gc, unsigned offset) +{ -+ struct device *d; ++ struct nxp_74hc153_chip *nxp; ++ struct nxp_74hc153_platform_data *pdata; ++ unsigned s0; ++ unsigned s1; ++ unsigned pin; ++ int ret; + -+ d = dev_find_class(dev, "mdio_bus"); -+ if (d != NULL) { -+ struct mii_bus *bus; ++ nxp = gpio_to_nxp(gc); ++ pdata = nxp->parent->platform_data; + -+ bus = to_mii_bus(d); -+ put_device(d); ++ s0 = !!(offset & NXP_74HC153_S0_MASK); ++ s1 = !!(offset & NXP_74HC153_S1_MASK); ++ pin = (offset & NXP_74HC153_BANK_MASK) ? pdata->gpio_pin_2y ++ : pdata->gpio_pin_1y; + -+ return bus; -+ } ++ mutex_lock(&nxp->lock); ++ gpio_set_value(pdata->gpio_pin_s0, s0); ++ gpio_set_value(pdata->gpio_pin_s1, s1); ++ ret = gpio_get_value(pin); ++ mutex_unlock(&nxp->lock); + -+ return NULL; ++ return ret; +} + -+int ag71xx_phy_connect(struct ag71xx *ag) ++static void nxp_74hc153_set_value(struct gpio_chip *gc, ++ unsigned offset, int val) +{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ /* not supported */ ++} + -+ ag->mii_bus = dev_to_mii_bus(pdata->mii_bus_dev); -+ if (ag->mii_bus == NULL) { -+ printk(KERN_ERR "%s: unable to find MII bus on device '%s'\n", -+ ag->dev->name, dev_name(pdata->mii_bus_dev)); -+ return -ENODEV; -+ } ++static int __devinit nxp_74hc153_probe(struct platform_device *pdev) ++{ ++ struct nxp_74hc153_platform_data *pdata; ++ struct nxp_74hc153_chip *nxp; ++ struct gpio_chip *gc; ++ int err; + -+ /* Reset the mdio bus explicitly */ -+ if (ag->mii_bus->reset) { -+ mutex_lock(&ag->mii_bus->mdio_lock); -+ ag->mii_bus->reset(ag->mii_bus); -+ mutex_unlock(&ag->mii_bus->mdio_lock); ++ pdata = pdev->dev.platform_data; ++ if (pdata == NULL) { ++ dev_dbg(&pdev->dev, "no platform data specified\n"); ++ return -EINVAL; + } + -+ if (pdata->phy_mask) -+ return ag71xx_phy_connect_multi(ag); ++ nxp = kzalloc(sizeof(struct nxp_74hc153_chip), GFP_KERNEL); ++ if (nxp == NULL) { ++ dev_err(&pdev->dev, "no memory for private data\n"); ++ return -ENOMEM; ++ } + -+ return ag71xx_phy_connect_fixed(ag); -+} ++ err = gpio_request(pdata->gpio_pin_s0, dev_name(&pdev->dev)); ++ if (err) { ++ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++ pdata->gpio_pin_s0, err); ++ goto err_free_nxp; ++ } + -+void ag71xx_phy_disconnect(struct ag71xx *ag) -+{ -+ if (ag->phy_dev) -+ phy_disconnect(ag->phy_dev); -+} -diff -Nur linux-2.6.39.orig/drivers/net/phy/Kconfig linux-2.6.39/drivers/net/phy/Kconfig ---- linux-2.6.39.orig/drivers/net/phy/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/phy/Kconfig 2011-05-27 14:36:51.000000000 +0200 -@@ -91,6 +91,10 @@ - ---help--- - Supports the KSZ9021, VSC8201, KS8001 PHYs. - -+config IP175C_PHY -+ tristate "Driver for IC+ IP175C/IP178C switches" -+ select SWCONFIG ++ err = gpio_request(pdata->gpio_pin_s1, dev_name(&pdev->dev)); ++ if (err) { ++ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++ pdata->gpio_pin_s1, err); ++ goto err_free_s0; ++ } + - config FIXED_PHY - bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" - depends on PHYLIB=y -diff -Nur linux-2.6.39.orig/drivers/net/phy/phy.c linux-2.6.39/drivers/net/phy/phy.c ---- linux-2.6.39.orig/drivers/net/phy/phy.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/phy/phy.c 2011-05-27 14:36:51.000000000 +0200 -@@ -297,6 +297,50 @@ - } - EXPORT_SYMBOL(phy_ethtool_gset); - -+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr) -+{ -+ u32 cmd; -+ int tmp; -+ struct ethtool_cmd ecmd = { ETHTOOL_GSET }; -+ struct ethtool_value edata = { ETHTOOL_GLINK }; ++ err = gpio_request(pdata->gpio_pin_1y, dev_name(&pdev->dev)); ++ if (err) { ++ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++ pdata->gpio_pin_1y, err); ++ goto err_free_s1; ++ } + -+ if (get_user(cmd, (u32 *) useraddr)) -+ return -EFAULT; ++ err = gpio_request(pdata->gpio_pin_2y, dev_name(&pdev->dev)); ++ if (err) { ++ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++ pdata->gpio_pin_2y, err); ++ goto err_free_1y; ++ } + -+ switch (cmd) { -+ case ETHTOOL_GSET: -+ phy_ethtool_gset(phydev, &ecmd); -+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) -+ return -EFAULT; -+ return 0; ++ err = gpio_direction_output(pdata->gpio_pin_s0, 0); ++ if (err) { ++ dev_err(&pdev->dev, ++ "unable to set direction of gpio %u, err=%d\n", ++ pdata->gpio_pin_s0, err); ++ goto err_free_2y; ++ } + -+ case ETHTOOL_SSET: -+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) -+ return -EFAULT; -+ return phy_ethtool_sset(phydev, &ecmd); ++ err = gpio_direction_output(pdata->gpio_pin_s1, 0); ++ if (err) { ++ dev_err(&pdev->dev, ++ "unable to set direction of gpio %u, err=%d\n", ++ pdata->gpio_pin_s1, err); ++ goto err_free_2y; ++ } + -+ case ETHTOOL_NWAY_RST: -+ /* if autoneg is off, it's an error */ -+ tmp = phy_read(phydev, MII_BMCR); -+ if (tmp & BMCR_ANENABLE) { -+ tmp |= (BMCR_ANRESTART); -+ phy_write(phydev, MII_BMCR, tmp); -+ return 0; -+ } -+ return -EINVAL; ++ err = gpio_direction_input(pdata->gpio_pin_1y); ++ if (err) { ++ dev_err(&pdev->dev, ++ "unable to set direction of gpio %u, err=%d\n", ++ pdata->gpio_pin_1y, err); ++ goto err_free_2y; ++ } + -+ case ETHTOOL_GLINK: -+ edata.data = (phy_read(phydev, -+ MII_BMSR) & BMSR_LSTATUS) ? 1 : 0; -+ if (copy_to_user(useraddr, &edata, sizeof(edata))) -+ return -EFAULT; -+ return 0; ++ err = gpio_direction_input(pdata->gpio_pin_2y); ++ if (err) { ++ dev_err(&pdev->dev, ++ "unable to set direction of gpio %u, err=%d\n", ++ pdata->gpio_pin_2y, err); ++ goto err_free_2y; + } + -+ return -EOPNOTSUPP; -+} -+EXPORT_SYMBOL(phy_ethtool_ioctl); ++ nxp->parent = &pdev->dev; ++ mutex_init(&nxp->lock); + - /** - * phy_mii_ioctl - generic PHY MII ioctl interface - * @phydev: the phy_device struct -@@ -472,7 +516,7 @@ - int idx; - - idx = phy_find_setting(phydev->speed, phydev->duplex); -- ++ gc = &nxp->gpio_chip; + - idx++; - - idx = phy_find_valid(idx, phydev->supported); -diff -Nur linux-2.6.39.orig/drivers/net/phy/phy_device.c linux-2.6.39/drivers/net/phy/phy_device.c ---- linux-2.6.39.orig/drivers/net/phy/phy_device.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/phy/phy_device.c 2011-05-27 14:36:51.000000000 +0200 -@@ -149,6 +149,19 @@ - } - EXPORT_SYMBOL(phy_scan_fixups); - -+static int generic_receive_skb(struct sk_buff *skb) -+{ -+ skb->protocol = eth_type_trans(skb, skb->dev); -+ return netif_receive_skb(skb); ++ gc->direction_input = nxp_74hc153_direction_input; ++ gc->direction_output = nxp_74hc153_direction_output; ++ gc->get = nxp_74hc153_get_value; ++ gc->set = nxp_74hc153_set_value; ++ gc->can_sleep = 1; ++ ++ gc->base = pdata->gpio_base; ++ gc->ngpio = NXP_74HC153_NUM_GPIOS; ++ gc->label = dev_name(nxp->parent); ++ gc->dev = nxp->parent; ++ gc->owner = THIS_MODULE; ++ ++ err = gpiochip_add(&nxp->gpio_chip); ++ if (err) { ++ dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); ++ goto err_free_2y; ++ } ++ ++ platform_set_drvdata(pdev, nxp); ++ return 0; ++ ++err_free_2y: ++ gpio_free(pdata->gpio_pin_2y); ++err_free_1y: ++ gpio_free(pdata->gpio_pin_1y); ++err_free_s1: ++ gpio_free(pdata->gpio_pin_s1); ++err_free_s0: ++ gpio_free(pdata->gpio_pin_s0); ++err_free_nxp: ++ kfree(nxp); ++ return err; +} + -+static int generic_rx(struct sk_buff *skb) ++static int nxp_74hc153_remove(struct platform_device *pdev) +{ -+ skb->protocol = eth_type_trans(skb, skb->dev); -+ return netif_rx(skb); ++ struct nxp_74hc153_chip *nxp = platform_get_drvdata(pdev); ++ struct nxp_74hc153_platform_data *pdata = pdev->dev.platform_data; ++ ++ if (nxp) { ++ int err; ++ ++ err = gpiochip_remove(&nxp->gpio_chip); ++ if (err) { ++ dev_err(&pdev->dev, ++ "unable to remove gpio chip, err=%d\n", ++ err); ++ return err; ++ } ++ ++ gpio_free(pdata->gpio_pin_2y); ++ gpio_free(pdata->gpio_pin_1y); ++ gpio_free(pdata->gpio_pin_s1); ++ gpio_free(pdata->gpio_pin_s0); ++ ++ kfree(nxp); ++ platform_set_drvdata(pdev, NULL); ++ } ++ ++ return 0; +} + ++static struct platform_driver nxp_74hc153_driver = { ++ .probe = nxp_74hc153_probe, ++ .remove = __devexit_p(nxp_74hc153_remove), ++ .driver = { ++ .name = NXP_74HC153_DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init nxp_74hc153_init(void) ++{ ++ return platform_driver_register(&nxp_74hc153_driver); ++} ++subsys_initcall(nxp_74hc153_init); + - static struct phy_device* phy_device_create(struct mii_bus *bus, - int addr, int phy_id) - { -@@ -180,6 +193,8 @@ - dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr); - - dev->state = PHY_DOWN; -+ dev->netif_receive_skb = &generic_receive_skb; -+ dev->netif_rx = &generic_rx; - - mutex_init(&dev->lock); - INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); -diff -Nur linux-2.6.39.orig/drivers/spi/Kconfig linux-2.6.39/drivers/spi/Kconfig ---- linux-2.6.39.orig/drivers/spi/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/spi/Kconfig 2011-05-27 14:36:51.000000000 +0200 -@@ -67,6 +67,13 @@ - This enables support for the SPI controller present on the - Atheros AR71XX/AR724X/AR913X SoCs. - -+config SPI_AR71XX -+ tristate "Atheros AR71xx SPI Controller" -+ depends on SPI_MASTER && ATHEROS_AR71XX -+ select SPI_BITBANG -+ help -+ This is the SPI contoller driver for Atheros AR71xx. ++static void __exit nxp_74hc153_exit(void) ++{ ++ platform_driver_unregister(&nxp_74hc153_driver); ++} ++module_exit(nxp_74hc153_exit); + - config SPI_ATMEL - tristate "Atmel SPI Controller" - depends on (ARCH_AT91 || AVR32) -diff -Nur linux-2.6.39.orig/drivers/spi/Makefile linux-2.6.39/drivers/spi/Makefile ---- linux-2.6.39.orig/drivers/spi/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/spi/Makefile 2011-05-27 14:36:51.000000000 +0200 -@@ -11,6 +11,7 @@ - # SPI master controller drivers (bus) - obj-$(CONFIG_SPI_ALTERA) += spi_altera.o - obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o -+obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o - obj-$(CONFIG_SPI_ATH79) += ath79_spi.o - obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o - obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o -diff -Nur linux-2.6.39.orig/drivers/spi/ap83_spi.c linux-2.6.39/drivers/spi/ap83_spi.c ---- linux-2.6.39.orig/drivers/spi/ap83_spi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/ap83_spi.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,282 @@ ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC153"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" NXP_74HC153_DRIVER_NAME); +diff -Nur linux-2.6.39.orig/drivers/leds/leds-rb750.c linux-2.6.39/drivers/leds/leds-rb750.c +--- linux-2.6.39.orig/drivers/leds/leds-rb750.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/leds/leds-rb750.c 2011-04-27 12:19:22.267661616 +0200 +@@ -0,0 +1,141 @@ +/* -+ * Atheros AP83 board specific SPI Controller driver ++ * LED driver for the RouterBOARD 750 + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ -+ +#include +#include -+#include -+#include -+#include +#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define DRV_DESC "Atheros AP83 board SPI Controller driver" -+#define DRV_VERSION "0.1.0" -+#define DRV_NAME "ap83-spi" ++#include ++#include + -+#define AP83_SPI_CLK_HIGH (1 << 23) -+#define AP83_SPI_CLK_LOW 0 -+#define AP83_SPI_MOSI_HIGH (1 << 22) -+#define AP83_SPI_MOSI_LOW 0 ++#include + -+#define AP83_SPI_GPIO_CS 1 -+#define AP83_SPI_GPIO_MISO 3 ++#define DRV_NAME "leds-rb750" + -+struct ap83_spi { -+ struct spi_bitbang bitbang; -+ void __iomem *base; -+ u32 addr; ++struct rb750_led_dev { ++ struct led_classdev cdev; ++ u32 mask; ++ int active_low; ++}; + -+ struct platform_device *pdev; ++struct rb750_led_drvdata { ++ struct rb750_led_dev *led_devs; ++ int num_leds; +}; + -+static inline u32 ap83_spi_rr(struct ap83_spi *sp, u32 reg) ++static inline struct rb750_led_dev *to_rbled(struct led_classdev *led_cdev) +{ -+ return __raw_readl(sp->base + reg); ++ return (struct rb750_led_dev *)container_of(led_cdev, ++ struct rb750_led_dev, cdev); +} + -+static inline struct ap83_spi *spidev_to_sp(struct spi_device *spi) ++static void rb750_led_brightness_set(struct led_classdev *led_cdev, ++ enum led_brightness value) +{ -+ return spi_master_get_devdata(spi->master); ++ struct rb750_led_dev *rbled = to_rbled(led_cdev); ++ int level; ++ ++ level = (value == LED_OFF) ? 0 : 1; ++ level ^= rbled->active_low; ++ ++ if (level) ++ rb750_latch_change(0, rbled->mask); ++ else ++ rb750_latch_change(rbled->mask, 0); +} + -+static inline void setsck(struct spi_device *spi, int val) ++static int __devinit rb750_led_probe(struct platform_device *pdev) +{ -+ struct ap83_spi *sp = spidev_to_sp(spi); ++ struct rb750_led_platform_data *pdata; ++ struct rb750_led_drvdata *drvdata; ++ int ret = 0; ++ int i; + -+ if (val) -+ sp->addr |= AP83_SPI_CLK_HIGH; -+ else -+ sp->addr &= ~AP83_SPI_CLK_HIGH; ++ pdata = pdev->dev.platform_data; ++ if (!pdata) ++ return -EINVAL; + -+ dev_dbg(&spi->dev, "addr=%08x, SCK set to %s\n", -+ sp->addr, (val) ? "HIGH" : "LOW"); ++ drvdata = kzalloc(sizeof(struct rb750_led_drvdata) + ++ sizeof(struct rb750_led_dev) * pdata->num_leds, ++ GFP_KERNEL); ++ if (!drvdata) ++ return -ENOMEM; + -+ ap83_spi_rr(sp, sp->addr); -+} ++ drvdata->num_leds = pdata->num_leds; ++ drvdata->led_devs = (struct rb750_led_dev *) &drvdata[1]; + -+static inline void setmosi(struct spi_device *spi, int val) -+{ -+ struct ap83_spi *sp = spidev_to_sp(spi); ++ for (i = 0; i < drvdata->num_leds; i++) { ++ struct rb750_led_dev *rbled = &drvdata->led_devs[i]; ++ struct rb750_led_data *led_data = &pdata->leds[i]; + -+ if (val) -+ sp->addr |= AP83_SPI_MOSI_HIGH; -+ else -+ sp->addr &= ~AP83_SPI_MOSI_HIGH; ++ rbled->cdev.name = led_data->name; ++ rbled->cdev.default_trigger = led_data->default_trigger; ++ rbled->cdev.brightness_set = rb750_led_brightness_set; ++ rbled->cdev.brightness = LED_OFF; + -+ dev_dbg(&spi->dev, "addr=%08x, MOSI set to %s\n", -+ sp->addr, (val) ? "HIGH" : "LOW"); ++ rbled->mask = led_data->mask; ++ rbled->active_low = !!led_data->active_low; + -+ ap83_spi_rr(sp, sp->addr); -+} ++ ret = led_classdev_register(&pdev->dev, &rbled->cdev); ++ if (ret) ++ goto err; ++ } + -+static inline u32 getmiso(struct spi_device *spi) -+{ -+ u32 ret; ++ platform_set_drvdata(pdev, drvdata); ++ return 0; + -+ ret = gpio_get_value(AP83_SPI_GPIO_MISO) ? 1 : 0; -+ dev_dbg(&spi->dev, "get MISO: %d\n", ret); ++err: ++ for (i = i - 1; i >= 0; i--) ++ led_classdev_unregister(&drvdata->led_devs[i].cdev); + ++ kfree(drvdata); + return ret; +} + -+static inline void do_spidelay(struct spi_device *spi, unsigned nsecs) -+{ -+ ndelay(nsecs); -+} -+ -+static void ap83_spi_chipselect(struct spi_device *spi, int on) ++static int __devexit rb750_led_remove(struct platform_device *pdev) +{ -+ struct ap83_spi *sp = spidev_to_sp(spi); ++ struct rb750_led_drvdata *drvdata; ++ int i; + -+ dev_dbg(&spi->dev, "set CS to %d\n", (on) ? 0 : 1); ++ drvdata = platform_get_drvdata(pdev); ++ for (i = 0; i < drvdata->num_leds; i++) ++ led_classdev_unregister(&drvdata->led_devs[i].cdev); + -+ if (on) { -+ ar71xx_flash_acquire(); ++ kfree(drvdata); ++ return 0; ++} + -+ sp->addr = 0; -+ ap83_spi_rr(sp, sp->addr); -+ -+ gpio_set_value(AP83_SPI_GPIO_CS, 0); -+ } else { -+ gpio_set_value(AP83_SPI_GPIO_CS, 1); -+ ar71xx_flash_release(); -+ } -+} -+ -+#define spidelay(nsecs) \ -+ do { \ -+ /* Steal the spi_device pointer from our caller. \ -+ * The bitbang-API should probably get fixed here... */ \ -+ do_spidelay(spi, nsecs); \ -+ } while (0) -+ -+#define EXPAND_BITBANG_TXRX -+#include -+ -+static u32 ap83_spi_txrx_mode0(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) -+{ -+ dev_dbg(&spi->dev, "TXRX0 word=%08x, bits=%u\n", word, bits); -+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits); -+} ++static struct platform_driver rb750_led_driver = { ++ .probe = rb750_led_probe, ++ .remove = __devexit_p(rb750_led_remove), ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; + -+static u32 ap83_spi_txrx_mode1(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) -+{ -+ dev_dbg(&spi->dev, "TXRX1 word=%08x, bits=%u\n", word, bits); -+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits); -+} ++MODULE_ALIAS("platform:leds-rb750"); + -+static u32 ap83_spi_txrx_mode2(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) ++static int __init rb750_led_init(void) +{ -+ dev_dbg(&spi->dev, "TXRX2 word=%08x, bits=%u\n", word, bits); -+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits); ++ return platform_driver_register(&rb750_led_driver); +} + -+static u32 ap83_spi_txrx_mode3(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) ++static void __exit rb750_led_exit(void) +{ -+ dev_dbg(&spi->dev, "TXRX3 word=%08x, bits=%u\n", word, bits); -+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits); ++ platform_driver_unregister(&rb750_led_driver); +} + -+static int ap83_spi_probe(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct ap83_spi *sp; -+ struct ap83_spi_platform_data *pdata; -+ struct resource *r; -+ int ret; -+ -+ ret = gpio_request(AP83_SPI_GPIO_MISO, "spi-miso"); -+ if (ret) { -+ dev_err(&pdev->dev, "gpio request failed for MISO\n"); -+ return ret; -+ } -+ -+ ret = gpio_request(AP83_SPI_GPIO_CS, "spi-cs"); -+ if (ret) { -+ dev_err(&pdev->dev, "gpio request failed for CS\n"); -+ goto err_free_miso; -+ } -+ -+ ret = gpio_direction_input(AP83_SPI_GPIO_MISO); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set direction of MISO\n"); -+ goto err_free_cs; -+ } -+ -+ ret = gpio_direction_output(AP83_SPI_GPIO_CS, 0); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set direction of CS\n"); -+ goto err_free_cs; -+ } -+ -+ master = spi_alloc_master(&pdev->dev, sizeof(*sp)); -+ if (master == NULL) { -+ dev_err(&pdev->dev, "failed to allocate spi master\n"); -+ return -ENOMEM; -+ } -+ -+ sp = spi_master_get_devdata(master); -+ platform_set_drvdata(pdev, sp); -+ -+ pdata = pdev->dev.platform_data; -+ -+ sp->bitbang.master = spi_master_get(master); -+ sp->bitbang.chipselect = ap83_spi_chipselect; -+ sp->bitbang.txrx_word[SPI_MODE_0] = ap83_spi_txrx_mode0; -+ sp->bitbang.txrx_word[SPI_MODE_1] = ap83_spi_txrx_mode1; -+ sp->bitbang.txrx_word[SPI_MODE_2] = ap83_spi_txrx_mode2; -+ sp->bitbang.txrx_word[SPI_MODE_3] = ap83_spi_txrx_mode3; ++module_init(rb750_led_init); ++module_exit(rb750_led_exit); + -+ sp->bitbang.master->bus_num = pdev->id; -+ sp->bitbang.master->num_chipselect = 1; ++MODULE_DESCRIPTION(DRV_NAME); ++MODULE_DESCRIPTION("LED driver for the RouterBOARD 750"); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c linux-2.6.39/drivers/leds/leds-wndr3700-usb.c +--- linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/leds/leds-wndr3700-usb.c 2011-04-27 12:19:22.267661616 +0200 +@@ -0,0 +1,75 @@ ++/* ++ * USB LED driver for the NETGEAR WNDR3700 ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (r == NULL) { -+ ret = -ENOENT; -+ goto err_spi_put; -+ } ++#include ++#include ++#include + -+ sp->base = ioremap_nocache(r->start, r->end - r->start + 1); -+ if (!sp->base) { -+ ret = -ENXIO; -+ goto err_spi_put; -+ } ++#include + -+ ret = spi_bitbang_start(&sp->bitbang); -+ if (!ret) -+ goto err_unmap; ++#define DRIVER_NAME "wndr3700-led-usb" + -+ dev_info(&pdev->dev, "AP83 SPI adapter at %08x\n", r->start); ++static void wndr3700_usb_led_set(struct led_classdev *cdev, ++ enum led_brightness brightness) ++{ ++ if (brightness) ++ ar71xx_device_start(RESET_MODULE_GE1_PHY); ++ else ++ ar71xx_device_stop(RESET_MODULE_GE1_PHY); ++} + -+ return 0; ++static enum led_brightness wndr3700_usb_led_get(struct led_classdev *cdev) ++{ ++ return ar71xx_device_stopped(RESET_MODULE_GE1_PHY) ? LED_OFF : LED_FULL; ++} + -+ err_unmap: -+ iounmap(sp->base); -+ err_spi_put: -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); ++static struct led_classdev wndr3700_usb_led = { ++ .name = "wndr3700:green:usb", ++ .brightness_set = wndr3700_usb_led_set, ++ .brightness_get = wndr3700_usb_led_get, ++}; + -+ err_free_cs: -+ gpio_free(AP83_SPI_GPIO_CS); -+ err_free_miso: -+ gpio_free(AP83_SPI_GPIO_MISO); -+ return ret; ++static int __devinit wndr3700_usb_led_probe(struct platform_device *pdev) ++{ ++ return led_classdev_register(&pdev->dev, &wndr3700_usb_led); +} + -+static int ap83_spi_remove(struct platform_device *pdev) ++static int __devexit wndr3700_usb_led_remove(struct platform_device *pdev) +{ -+ struct ap83_spi *sp = platform_get_drvdata(pdev); -+ -+ spi_bitbang_stop(&sp->bitbang); -+ iounmap(sp->base); -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); -+ ++ led_classdev_unregister(&wndr3700_usb_led); + return 0; +} + -+static struct platform_driver ap83_spi_drv = { -+ .probe = ap83_spi_probe, -+ .remove = ap83_spi_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, ++static struct platform_driver wndr3700_usb_led_driver = { ++ .probe = wndr3700_usb_led_probe, ++ .remove = __devexit_p(wndr3700_usb_led_remove), ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, + }, +}; + -+static int __init ap83_spi_init(void) ++static int __init wndr3700_usb_led_init(void) +{ -+ return platform_driver_register(&ap83_spi_drv); ++ return platform_driver_register(&wndr3700_usb_led_driver); +} -+module_init(ap83_spi_init); + -+static void __exit ap83_spi_exit(void) ++static void __exit wndr3700_usb_led_exit(void) +{ -+ platform_driver_unregister(&ap83_spi_drv); ++ platform_driver_unregister(&wndr3700_usb_led_driver); +} -+module_exit(ap83_spi_exit); + -+MODULE_ALIAS("platform:" DRV_NAME); -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); ++module_init(wndr3700_usb_led_init); ++module_exit(wndr3700_usb_led_exit); ++ ++MODULE_DESCRIPTION("USB LED driver for the NETGEAR WNDR3700"); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.39.orig/drivers/spi/ar71xx_spi.c linux-2.6.39/drivers/spi/ar71xx_spi.c ---- linux-2.6.39.orig/drivers/spi/ar71xx_spi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/ar71xx_spi.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,283 @@ ++MODULE_ALIAS("platform:" DRIVER_NAME); +diff -Nur linux-2.6.39.orig/drivers/Makefile linux-2.6.39/drivers/Makefile +--- linux-2.6.39.orig/drivers/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/Makefile 2011-08-23 15:10:42.370478643 +0200 +@@ -46,8 +46,8 @@ + obj-$(CONFIG_SCSI) += scsi/ + obj-$(CONFIG_ATA) += ata/ + obj-$(CONFIG_TARGET_CORE) += target/ +-obj-$(CONFIG_MTD) += mtd/ + obj-$(CONFIG_SPI) += spi/ ++obj-$(CONFIG_MTD) += mtd/ + obj-y += net/ + obj-$(CONFIG_ATM) += atm/ + obj-$(CONFIG_FUSION) += message/ +diff -Nur linux-2.6.39.orig/drivers/mtd/chips/cfi_cmdset_0002.c linux-2.6.39/drivers/mtd/chips/cfi_cmdset_0002.c +--- linux-2.6.39.orig/drivers/mtd/chips/cfi_cmdset_0002.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/mtd/chips/cfi_cmdset_0002.c 2011-08-22 16:22:28.477979654 +0200 +@@ -39,7 +39,7 @@ + #include + + #define AMD_BOOTLOC_BUG +-#define FORCE_WORD_WRITE 0 ++#define FORCE_WORD_WRITE 1 + + #define MAX_WORD_RETRIES 3 + +@@ -50,7 +50,9 @@ + + static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); + static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); ++#if !FORCE_WORD_WRITE + static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); ++#endif + static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *); + static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *); + static void cfi_amdstd_sync (struct mtd_info *); +@@ -186,6 +188,7 @@ + } + #endif + ++#if !FORCE_WORD_WRITE + static void fixup_use_write_buffers(struct mtd_info *mtd) + { + struct map_info *map = mtd->priv; +@@ -195,6 +198,7 @@ + mtd->write = cfi_amdstd_write_buffers; + } + } ++#endif /* !FORCE_WORD_WRITE */ + + /* Atmel chips don't use the same PRI format as AMD chips */ + static void fixup_convert_atmel_pri(struct mtd_info *mtd) +@@ -1377,6 +1381,7 @@ + /* + * FIXME: interleaved mode not tested, and probably not supported! + */ ++#if !FORCE_WORD_WRITE + static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, + unsigned long adr, const u_char *buf, + int len) +@@ -1487,7 +1492,6 @@ + return ret; + } + +- + static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) + { +@@ -1566,6 +1570,7 @@ + + return 0; + } ++#endif /* !FORCE_WORD_WRITE */ + + + /* +diff -Nur linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c +--- linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c 2011-04-27 12:19:22.177661504 +0200 +@@ -0,0 +1,310 @@ +/* -+ * Atheros AR71xx SPI Controller driver ++ * Parallel flash driver for the Atheros AR91xx SoC + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as @@ -15099,2909 +16534,11447 @@ diff -Nur linux-2.6.39.orig/drivers/spi/ar71xx_spi.c linux-2.6.39/drivers/spi/ar + * + */ + ++#include ++#include +#include +#include -+#include -+#include -+#include ++#include ++#include +#include ++#include ++#include ++#include +#include -+#include -+#include -+#include + +#include -+#include -+ -+#define DRV_DESC "Atheros AR71xx SPI Controller driver" -+#define DRV_VERSION "0.2.4" -+#define DRV_NAME "ar71xx-spi" ++#include + -+#undef PER_BIT_READ ++#define DRV_NAME "ar91xx-flash" + -+struct ar71xx_spi { -+ struct spi_bitbang bitbang; -+ u32 ioc_base; -+ u32 reg_ctrl; -+ -+ void __iomem *base; -+ -+ struct platform_device *pdev; -+ u32 (*get_ioc_base)(u8 chip_select, int cs_high, -+ int is_on); ++struct ar91xx_flash_info { ++ struct mtd_info *mtd; ++ struct map_info map; ++#ifdef CONFIG_MTD_PARTITIONS ++ int nr_parts; ++ struct mtd_partition *parts; ++#endif +}; + -+static inline u32 ar71xx_spi_rr(struct ar71xx_spi *sp, unsigned reg) ++static map_word ar91xx_flash_read(struct map_info *map, unsigned long ofs) +{ -+ return __raw_readl(sp->base + reg); -+} ++ map_word val; + -+static inline void ar71xx_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val) -+{ -+ __raw_writel(val, sp->base + reg); ++ if (map_bankwidth_is_1(map)) ++ val.x[0] = __raw_readb(map->virt + (ofs ^ 3)); ++ else if (map_bankwidth_is_2(map)) ++ val.x[0] = __raw_readw(map->virt + (ofs ^ 2)); ++ else ++ val = map_word_ff(map); ++ ++ return val; +} + -+static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi) ++static void ar91xx_flash_write(struct map_info *map, map_word d, ++ unsigned long ofs) +{ -+ return spi_master_get_devdata(spi->master); ++ if (map_bankwidth_is_1(map)) ++ __raw_writeb(d.x[0], map->virt + (ofs ^ 3)); ++ else if (map_bankwidth_is_2(map)) ++ __raw_writew(d.x[0], map->virt + (ofs ^ 2)); ++ ++ mb(); +} + -+static u32 ar71xx_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on) ++static map_word ar91xx_flash_read_lock(struct map_info *map, unsigned long ofs) +{ -+ u32 ret; ++ map_word ret; + -+ if (is_on == AR71XX_SPI_CS_INACTIVE) -+ ret = SPI_IOC_CS_ALL; -+ else -+ ret = SPI_IOC_CS_ALL & ~SPI_IOC_CS(chip_select); ++ ar71xx_flash_acquire(); ++ ret = ar91xx_flash_read(map, ofs); ++ ar71xx_flash_release(); + + return ret; +} + -+static void ar71xx_spi_chipselect(struct spi_device *spi, int value) ++static void ar91xx_flash_write_lock(struct map_info *map, map_word d, ++ unsigned long ofs) +{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ void __iomem *base = sp->base; -+ u32 ioc_base; -+ -+ switch (value) { -+ case BITBANG_CS_INACTIVE: -+ ioc_base = sp->get_ioc_base(spi->chip_select, -+ (spi->mode & SPI_CS_HIGH) != 0, -+ AR71XX_SPI_CS_INACTIVE); -+ __raw_writel(ioc_base, base + SPI_REG_IOC); -+ break; -+ -+ case BITBANG_CS_ACTIVE: -+ ioc_base = sp->get_ioc_base(spi->chip_select, -+ (spi->mode & SPI_CS_HIGH) != 0, -+ AR71XX_SPI_CS_ACTIVE); -+ -+ __raw_writel(ioc_base, base + SPI_REG_IOC); -+ sp->ioc_base = ioc_base; -+ break; -+ } ++ ar71xx_flash_acquire(); ++ ar91xx_flash_write(map, d, ofs); ++ ar71xx_flash_release(); +} + -+static void ar71xx_spi_setup_regs(struct spi_device *spi) ++static void ar91xx_flash_copy_from_lock(struct map_info *map, void *to, ++ unsigned long from, ssize_t len) +{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ -+ /* enable GPIO mode */ -+ ar71xx_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO); -+ -+ /* save CTRL register */ -+ sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_CTRL); -+ -+ /* TODO: setup speed? */ -+ ar71xx_spi_wr(sp, SPI_REG_CTRL, 0x43); ++ ar71xx_flash_acquire(); ++ inline_map_copy_from(map, to, from, len); ++ ar71xx_flash_release(); +} + -+static void ar71xx_spi_restore_regs(struct spi_device *spi) ++static void ar91xx_flash_copy_to_lock(struct map_info *map, unsigned long to, ++ const void *from, ssize_t len) +{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ -+ /* restore CTRL register */ -+ ar71xx_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl); -+ /* disable GPIO mode */ -+ ar71xx_spi_wr(sp, SPI_REG_FS, 0); ++ ar71xx_flash_acquire(); ++ inline_map_copy_to(map, to, from, len); ++ ar71xx_flash_release(); +} + -+static int ar71xx_spi_setup(struct spi_device *spi) ++static int ar91xx_flash_remove(struct platform_device *pdev) +{ -+ int status; ++ struct ar91xx_flash_platform_data *pdata; ++ struct ar91xx_flash_info *info; + -+ if (spi->bits_per_word > 32) -+ return -EINVAL; ++ info = platform_get_drvdata(pdev); ++ if (info == NULL) ++ return 0; + -+ if (!spi->controller_state) -+ ar71xx_spi_setup_regs(spi); ++ platform_set_drvdata(pdev, NULL); + -+ status = spi_bitbang_setup(spi); -+ if (status && !spi->controller_state) -+ ar71xx_spi_restore_regs(spi); ++ if (info->mtd == NULL) ++ return 0; + -+ return status; -+} ++ pdata = pdev->dev.platform_data; ++#ifdef CONFIG_MTD_PARTITIONS ++ if (info->nr_parts) { ++ del_mtd_partitions(info->mtd); ++ kfree(info->parts); ++ } else if (pdata->nr_parts) { ++ del_mtd_partitions(info->mtd); ++ } else { ++ del_mtd_device(info->mtd); ++ } ++#else ++ del_mtd_device(info->mtd); ++#endif ++ map_destroy(info->mtd); + -+static void ar71xx_spi_cleanup(struct spi_device *spi) -+{ -+ ar71xx_spi_restore_regs(spi); -+ spi_bitbang_cleanup(spi); ++ return 0; +} + -+static u32 ar71xx_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs, -+ u32 word, u8 bits) -+{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ void __iomem *base = sp->base; -+ u32 ioc = sp->ioc_base; -+ u32 ret; ++static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; ++#ifdef CONFIG_MTD_PARTITIONS ++static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; ++#endif + -+ /* clock starts at inactive polarity */ -+ for (word <<= (32 - bits); likely(bits); bits--) { -+ u32 out; ++static int ar91xx_flash_probe(struct platform_device *pdev) ++{ ++ struct ar91xx_flash_platform_data *pdata; ++ struct ar91xx_flash_info *info; ++ struct resource *res; ++ struct resource *region; ++ const char **probe_type; ++ int err = 0; + -+ if (word & (1 << 31)) -+ out = ioc | SPI_IOC_DO; -+ else -+ out = ioc & ~SPI_IOC_DO; ++ pdata = pdev->dev.platform_data; ++ if (pdata == NULL) ++ return -EINVAL; + -+ /* setup MSB (to slave) on trailing edge */ -+ __raw_writel(out, base + SPI_REG_IOC); ++ info = devm_kzalloc(&pdev->dev, sizeof(struct ar91xx_flash_info), ++ GFP_KERNEL); ++ if (info == NULL) { ++ err = -ENOMEM; ++ goto err_out; ++ } + -+ __raw_writel(out | SPI_IOC_CLK, base + SPI_REG_IOC); ++ platform_set_drvdata(pdev, info); + -+ word <<= 1; ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (res == NULL) { ++ err = -ENOENT; ++ goto err_out; ++ } + -+#ifdef PER_BIT_READ -+ /* sample MSB (from slave) on leading edge */ -+ ret = __raw_readl(base + SPI_REG_RDS); -+ __raw_writel(out, base + SPI_REG_IOC); -+#endif ++ dev_info(&pdev->dev, "%.8llx at %.8llx\n", ++ (unsigned long long)(res->end - res->start + 1), ++ (unsigned long long)res->start); + ++ region = devm_request_mem_region(&pdev->dev, ++ res->start, res->end - res->start + 1, ++ dev_name(&pdev->dev)); ++ if (region == NULL) { ++ dev_err(&pdev->dev, "could not reserve memory region\n"); ++ err = -ENOMEM; ++ goto err_out; + } + -+#ifndef PER_BIT_READ -+ ret = __raw_readl(base + SPI_REG_RDS); -+#endif -+ return ret; -+} ++ info->map.name = dev_name(&pdev->dev); ++ info->map.phys = res->start; ++ info->map.size = res->end - res->start + 1; ++ info->map.bankwidth = pdata->width; + -+static int ar71xx_spi_probe(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct ar71xx_spi *sp; -+ struct ar71xx_spi_platform_data *pdata; -+ struct resource *r; -+ int ret; ++ info->map.virt = devm_ioremap(&pdev->dev, info->map.phys, ++ info->map.size); ++ if (info->map.virt == NULL) { ++ dev_err(&pdev->dev, "failed to ioremap flash region\n"); ++ err = -EIO; ++ goto err_out; ++ } + -+ master = spi_alloc_master(&pdev->dev, sizeof(*sp)); -+ if (master == NULL) { -+ dev_err(&pdev->dev, "failed to allocate spi master\n"); -+ return -ENOMEM; ++ simple_map_init(&info->map); ++ if (pdata->is_shared) { ++ info->map.read = ar91xx_flash_read_lock; ++ info->map.write = ar91xx_flash_write_lock; ++ info->map.copy_from = ar91xx_flash_copy_from_lock; ++ info->map.copy_to = ar91xx_flash_copy_to_lock; ++ } else { ++ info->map.read = ar91xx_flash_read; ++ info->map.write = ar91xx_flash_write; + } + -+ sp = spi_master_get_devdata(master); -+ platform_set_drvdata(pdev, sp); ++ probe_type = rom_probe_types; ++ for (; info->mtd == NULL && *probe_type != NULL; probe_type++) ++ info->mtd = do_map_probe(*probe_type, &info->map); + -+ pdata = pdev->dev.platform_data; ++ if (info->mtd == NULL) { ++ dev_err(&pdev->dev, "map_probe failed\n"); ++ err = -ENXIO; ++ goto err_out; ++ } + -+ master->setup = ar71xx_spi_setup; -+ master->cleanup = ar71xx_spi_cleanup; ++ info->mtd->owner = THIS_MODULE; + -+ sp->bitbang.master = spi_master_get(master); -+ sp->bitbang.chipselect = ar71xx_spi_chipselect; -+ sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0; -+ sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; -+ -+ sp->get_ioc_base = ar71xx_spi_get_ioc_base; -+ if (pdata) { -+ sp->bitbang.master->bus_num = pdata->bus_num; -+ sp->bitbang.master->num_chipselect = pdata->num_chipselect; -+ if (pdata->get_ioc_base) -+ sp->get_ioc_base = pdata->get_ioc_base; -+ } else { -+ sp->bitbang.master->bus_num = 0; -+ sp->bitbang.master->num_chipselect = 3; ++#ifdef CONFIG_MTD_PARTITIONS ++ if (pdata->nr_parts) { ++ dev_info(&pdev->dev, "using static partition mapping\n"); ++ add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); ++ return 0; + } + -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (r == NULL) { -+ ret = -ENOENT; -+ goto err1; ++ err = parse_mtd_partitions(info->mtd, part_probe_types, ++ &info->parts, 0); ++ if (err > 0) { ++ add_mtd_partitions(info->mtd, info->parts, err); ++ return 0; + } ++#endif + -+ sp->base = ioremap_nocache(r->start, r->end - r->start + 1); -+ if (!sp->base) { -+ ret = -ENXIO; -+ goto err1; -+ } ++ add_mtd_device(info->mtd); ++ return 0; + -+ ret = spi_bitbang_start(&sp->bitbang); -+ if (!ret) -+ return 0; ++err_out: ++ ar91xx_flash_remove(pdev); ++ return err; ++} + -+ iounmap(sp->base); -+ err1: -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); ++#ifdef CONFIG_PM ++static int ar91xx_flash_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ struct ar91xx_flash_info *info = platform_get_drvdata(dev); ++ int ret = 0; ++ ++ if (info->mtd->suspend) ++ ret = info->mtd->suspend(info->mtd); ++ ++ if (ret) ++ goto fail; ++ ++ return 0; ++ ++fail: ++ if (info->mtd->suspend) { ++ BUG_ON(!info->mtd->resume); ++ info->mtd->resume(info->mtd); ++ } + + return ret; +} + -+static int ar71xx_spi_remove(struct platform_device *pdev) ++static int ar91xx_flash_resume(struct platform_device *pdev) +{ -+ struct ar71xx_spi *sp = platform_get_drvdata(pdev); ++ struct ar91xx_flash_info *info = platform_get_drvdata(pdev); + -+ spi_bitbang_stop(&sp->bitbang); -+ iounmap(sp->base); -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); ++ if (info->mtd->resume) ++ info->mtd->resume(info->mtd); + + return 0; +} + -+static struct platform_driver ar71xx_spi_drv = { -+ .probe = ar71xx_spi_probe, -+ .remove = ar71xx_spi_remove, ++static void ar91xx_flash_shutdown(struct platform_device *pdev) ++{ ++ struct ar91xx_flash_info *info = platform_get_drvdata(pdev); ++ ++ if (info->mtd->suspend && info->mtd->resume) ++ if (info->mtd->suspend(info->mtd) == 0) ++ info->mtd->resume(info->mtd); ++} ++#else ++#define ar91xx_flash_suspend NULL ++#define ar91xx_flash_resume NULL ++#define ar91xx_flash_shutdown NULL ++#endif ++ ++static struct platform_driver ar91xx_flash_driver = { ++ .probe = ar91xx_flash_probe, ++ .remove = ar91xx_flash_remove, ++ .suspend = ar91xx_flash_suspend, ++ .resume = ar91xx_flash_resume, ++ .shutdown = ar91xx_flash_shutdown, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + -+static int __init ar71xx_spi_init(void) ++static int __init ar91xx_flash_init(void) +{ -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); -+ return platform_driver_register(&ar71xx_spi_drv); ++ return platform_driver_register(&ar91xx_flash_driver); +} -+module_init(ar71xx_spi_init); + -+static void __exit ar71xx_spi_exit(void) ++static void __exit ar91xx_flash_exit(void) +{ -+ platform_driver_unregister(&ar71xx_spi_drv); ++ platform_driver_unregister(&ar91xx_flash_driver); +} -+module_exit(ar71xx_spi_exit); + -+MODULE_ALIAS("platform:" DRV_NAME); -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_AUTHOR("Imre Kaloz "); ++module_init(ar91xx_flash_init); ++module_exit(ar91xx_flash_exit); ++ +MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.39.orig/drivers/spi/pb44_spi.c linux-2.6.39/drivers/spi/pb44_spi.c ---- linux-2.6.39.orig/drivers/spi/pb44_spi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/pb44_spi.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,299 @@ ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_DESCRIPTION("Parallel flash driver for the Atheros AR91xx SoC"); ++MODULE_ALIAS("platform:" DRV_NAME); +diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Kconfig linux-2.6.39/drivers/mtd/maps/Kconfig +--- linux-2.6.39.orig/drivers/mtd/maps/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/mtd/maps/Kconfig 2011-08-22 16:22:06.367979538 +0200 +@@ -260,6 +260,13 @@ + Support for parsing CFE image tag and creating MTD partitions on + Broadcom BCM63xx boards. + ++config MTD_AR91XX_FLASH ++ tristate "Atheros AR91xx parallel flash support" ++ depends on ATHEROS_AR71XX ++ select MTD_COMPLEX_MAPPINGS ++ help ++ Parallel flash driver for the Atheros AR91xx based boards. ++ + config MTD_DILNETPC + tristate "CFI Flash device mapped on DIL/Net PC" + depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN +diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Makefile linux-2.6.39/drivers/mtd/maps/Makefile +--- linux-2.6.39.orig/drivers/mtd/maps/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/mtd/maps/Makefile 2011-08-22 16:22:06.387979567 +0200 +@@ -40,6 +40,7 @@ + obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.o + obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o + obj-$(CONFIG_MTD_PCI) += pci.o ++obj-$(CONFIG_MTD_AR91XX_FLASH) += ar91xx_flash.o + obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o + obj-$(CONFIG_MTD_EDB7312) += edb7312.o + obj-$(CONFIG_MTD_IMPA7) += impa7.o +diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Kconfig linux-2.6.39/drivers/mtd/nand/Kconfig +--- linux-2.6.39.orig/drivers/mtd/nand/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/mtd/nand/Kconfig 2011-08-23 14:22:33.407989933 +0200 +@@ -531,4 +531,9 @@ + Enables support for NAND Flash chips on the ST Microelectronics + Flexible Static Memory Controller (FSMC) + ++config MTD_NAND_RB4XX ++ tristate "NAND flash driver for RouterBoard 4xx series" ++ depends on MTD_NAND && AR71XX_MACH_RB4XX ++ select SPI_AR71XX ++ + endif # MTD_NAND +diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Makefile linux-2.6.39/drivers/mtd/nand/Makefile +--- linux-2.6.39.orig/drivers/mtd/nand/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/mtd/nand/Makefile 2011-08-22 16:22:41.217981942 +0200 +@@ -34,6 +34,7 @@ + obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o + obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o + obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o ++obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o + obj-$(CONFIG_MTD_ALAUDA) += alauda.o + obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o + obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o +diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c +--- linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c 2011-08-23 11:36:58.637983055 +0200 +@@ -0,0 +1,311 @@ +/* -+ * Atheros PB44 board SPI controller driver ++ * NAND flash driver for the MikroTik RouterBoard 4xx series + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. ++ * This file was based on the driver for Linux 2.6.22 published by ++ * MikroTik for their RouterBoard 4xx series devices. + * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + */ + -+#include +#include -+#include -+#include -+#include ++#include ++#include ++#include +#include ++#include +#include -+#include -+#include -+#include +#include ++#include + +#include -+#include ++#include + -+#define DRV_DESC "Atheros PB44 SPI Controller driver" -+#define DRV_VERSION "0.1.0" -+#define DRV_NAME "pb44-spi" ++#define DRV_NAME "rb4xx-nand" ++#define DRV_VERSION "0.2.0" ++#define DRV_DESC "NAND flash driver for RouterBoard 4xx series" + -+#undef PER_BIT_READ ++#define RB4XX_NAND_GPIO_READY 5 ++#define RB4XX_NAND_GPIO_ALE 37 ++#define RB4XX_NAND_GPIO_CLE 38 ++#define RB4XX_NAND_GPIO_NCE 39 + -+struct ar71xx_spi { -+ struct spi_bitbang bitbang; -+ u32 ioc_base; -+ u32 reg_ctrl; ++struct rb4xx_nand_info { ++ struct nand_chip chip; ++ struct mtd_info mtd; ++}; + -+ void __iomem *base; ++/* ++ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader ++ * will not be able to find the kernel that we load. ++ */ ++static struct nand_ecclayout rb4xx_nand_ecclayout = { ++ .eccbytes = 6, ++ .eccpos = { 8, 9, 10, 13, 14, 15 }, ++ .oobavail = 9, ++ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } ++}; + -+ struct platform_device *pdev; ++static struct mtd_partition rb4xx_nand_partitions[] = { ++ { ++ .name = "booter", ++ .offset = 0, ++ .size = (256 * 1024), ++ .mask_flags = MTD_WRITEABLE, ++ }, ++ { ++ .name = "kernel", ++ .offset = (256 * 1024), ++ .size = (6 * 1024 * 1024) - (256 * 1024), ++ }, ++ { ++ .name = "rootfs", ++ .offset = MTDPART_OFS_NXTBLK, ++ .size = MTDPART_SIZ_FULL, ++ }, +}; + -+static inline u32 pb44_spi_rr(struct ar71xx_spi *sp, unsigned reg) ++static int rb4xx_nand_dev_ready(struct mtd_info *mtd) +{ -+ return __raw_readl(sp->base + reg); ++ return gpio_get_value_cansleep(RB4XX_NAND_GPIO_READY); +} + -+static inline void pb44_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val) ++static void rb4xx_nand_write_cmd(unsigned char cmd) +{ -+ __raw_writel(val, sp->base + reg); ++ unsigned char data = cmd; ++ int err; ++ ++ err = rb4xx_cpld_write(&data, 1); ++ if (err) ++ pr_err("rb4xx_nand: write cmd failed, err=%d\n", err); +} + -+static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi) ++static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, ++ unsigned int ctrl) +{ -+ return spi_master_get_devdata(spi->master); ++ if (ctrl & NAND_CTRL_CHANGE) { ++ gpio_set_value_cansleep(RB4XX_NAND_GPIO_CLE, ++ (ctrl & NAND_CLE) ? 1 : 0); ++ gpio_set_value_cansleep(RB4XX_NAND_GPIO_ALE, ++ (ctrl & NAND_ALE) ? 1 : 0); ++ gpio_set_value_cansleep(RB4XX_NAND_GPIO_NCE, ++ (ctrl & NAND_NCE) ? 0 : 1); ++ } ++ ++ if (cmd != NAND_CMD_NONE) ++ rb4xx_nand_write_cmd(cmd); +} + -+static void pb44_spi_chipselect(struct spi_device *spi, int is_active) ++static unsigned char rb4xx_nand_read_byte(struct mtd_info *mtd) +{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active; ++ unsigned char data = 0; ++ int err; + -+ if (is_active) { -+ /* set initial clock polarity */ -+ if (spi->mode & SPI_CPOL) -+ sp->ioc_base |= SPI_IOC_CLK; -+ else -+ sp->ioc_base &= ~SPI_IOC_CLK; -+ -+ pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base); -+ } -+ -+ if (spi->chip_select) { -+ unsigned long gpio = (unsigned long) spi->controller_data; -+ -+ /* SPI is normally active-low */ -+ gpio_set_value(gpio, cs_high); -+ } else { -+ if (cs_high) -+ sp->ioc_base |= SPI_IOC_CS0; -+ else -+ sp->ioc_base &= ~SPI_IOC_CS0; -+ -+ pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base); -+ } ++ err = rb4xx_cpld_read(&data, NULL, 1); ++ if (err) { ++ pr_err("rb4xx_nand: read data failed, err=%d\n", err); ++ data = 0xff; ++ } + ++ return data; +} + -+static int pb44_spi_setup_cs(struct spi_device *spi) ++static void rb4xx_nand_write_buf(struct mtd_info *mtd, const unsigned char *buf, ++ int len) +{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ -+ /* enable GPIO mode */ -+ pb44_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO); -+ -+ /* save CTRL register */ -+ sp->reg_ctrl = pb44_spi_rr(sp, SPI_REG_CTRL); -+ sp->ioc_base = pb44_spi_rr(sp, SPI_REG_IOC); -+ -+ /* TODO: setup speed? */ -+ pb44_spi_wr(sp, SPI_REG_CTRL, 0x43); -+ -+ if (spi->chip_select) { -+ unsigned long gpio = (unsigned long) spi->controller_data; -+ int status = 0; -+ -+ status = gpio_request(gpio, dev_name(&spi->dev)); -+ if (status) -+ return status; -+ -+ status = gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH); -+ if (status) { -+ gpio_free(gpio); -+ return status; -+ } -+ } else { -+ if (spi->mode & SPI_CS_HIGH) -+ sp->ioc_base |= SPI_IOC_CS0; -+ else -+ sp->ioc_base &= ~SPI_IOC_CS0; -+ pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base); -+ } ++ int err; + -+ return 0; ++ err = rb4xx_cpld_write(buf, len); ++ if (err) ++ pr_err("rb4xx_nand: write buf failed, err=%d\n", err); +} + -+static void pb44_spi_cleanup_cs(struct spi_device *spi) ++static void rb4xx_nand_read_buf(struct mtd_info *mtd, unsigned char *buf, ++ int len) +{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ -+ if (spi->chip_select) { -+ unsigned long gpio = (unsigned long) spi->controller_data; -+ gpio_free(gpio); -+ } ++ int err; + -+ /* restore CTRL register */ -+ pb44_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl); -+ /* disable GPIO mode */ -+ pb44_spi_wr(sp, SPI_REG_FS, 0); ++ err = rb4xx_cpld_read(buf, NULL, len); ++ if (err) ++ pr_err("rb4xx_nand: read buf failed, err=%d\n", err); +} + -+static int pb44_spi_setup(struct spi_device *spi) ++static int __init rb4xx_nand_probe(struct platform_device *pdev) +{ -+ int status = 0; ++ struct rb4xx_nand_info *info; ++ int ret; + -+ if (spi->bits_per_word > 32) -+ return -EINVAL; ++ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); + -+ if (!spi->controller_state) { -+ status = pb44_spi_setup_cs(spi); -+ if (status) -+ return status; ++ ret = gpio_request(RB4XX_NAND_GPIO_READY, "NAND RDY"); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to request gpio %d\n", ++ RB4XX_NAND_GPIO_READY); ++ goto err; + } + -+ status = spi_bitbang_setup(spi); -+ if (status && !spi->controller_state) -+ pb44_spi_cleanup_cs(spi); -+ -+ return status; -+} -+ -+static void pb44_spi_cleanup(struct spi_device *spi) -+{ -+ pb44_spi_cleanup_cs(spi); -+ spi_bitbang_cleanup(spi); -+} ++ ret = gpio_direction_input(RB4XX_NAND_GPIO_READY); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set input mode on gpio %d\n", ++ RB4XX_NAND_GPIO_READY); ++ goto err_free_gpio_ready; ++ } + -+static u32 pb44_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs, -+ u32 word, u8 bits) -+{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ u32 ioc = sp->ioc_base; -+ u32 ret; ++ ret = gpio_request(RB4XX_NAND_GPIO_ALE, "NAND ALE"); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to request gpio %d\n", ++ RB4XX_NAND_GPIO_ALE); ++ goto err_free_gpio_ready; ++ } + -+ /* clock starts at inactive polarity */ -+ for (word <<= (32 - bits); likely(bits); bits--) { -+ u32 out; ++ ret = gpio_direction_output(RB4XX_NAND_GPIO_ALE, 0); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", ++ RB4XX_NAND_GPIO_ALE); ++ goto err_free_gpio_ale; ++ } + -+ if (word & (1 << 31)) -+ out = ioc | SPI_IOC_DO; -+ else -+ out = ioc & ~SPI_IOC_DO; ++ ret = gpio_request(RB4XX_NAND_GPIO_CLE, "NAND CLE"); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to request gpio %d\n", ++ RB4XX_NAND_GPIO_CLE); ++ goto err_free_gpio_ale; ++ } + -+ /* setup MSB (to slave) on trailing edge */ -+ pb44_spi_wr(sp, SPI_REG_IOC, out); -+ pb44_spi_wr(sp, SPI_REG_IOC, out | SPI_IOC_CLK); ++ ret = gpio_direction_output(RB4XX_NAND_GPIO_CLE, 0); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", ++ RB4XX_NAND_GPIO_CLE); ++ goto err_free_gpio_cle; ++ } + -+ word <<= 1; ++ ret = gpio_request(RB4XX_NAND_GPIO_NCE, "NAND NCE"); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to request gpio %d\n", ++ RB4XX_NAND_GPIO_NCE); ++ goto err_free_gpio_cle; ++ } + -+#ifdef PER_BIT_READ -+ /* sample MSB (from slave) on leading edge */ -+ ret = pb44_spi_rr(sp, SPI_REG_RDS); -+ pb44_spi_wr(sp, SPI_REG_IOC, out); -+#endif ++ ret = gpio_direction_output(RB4XX_NAND_GPIO_NCE, 1); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", ++ RB4XX_NAND_GPIO_ALE); ++ goto err_free_gpio_nce; + } + -+#ifndef PER_BIT_READ -+ ret = pb44_spi_rr(sp, SPI_REG_RDS); -+#endif -+ return ret; -+} ++ info = kzalloc(sizeof(*info), GFP_KERNEL); ++ if (!info) { ++ dev_err(&pdev->dev, "rb4xx-nand: no memory for private data\n"); ++ ret = -ENOMEM; ++ goto err_free_gpio_nce; ++ } + -+static int pb44_spi_probe(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct ar71xx_spi *sp; -+ struct ar71xx_spi_platform_data *pdata; -+ struct resource *r; -+ int ret; ++ info->chip.priv = &info; ++ info->mtd.priv = &info->chip; ++ info->mtd.owner = THIS_MODULE; + -+ master = spi_alloc_master(&pdev->dev, sizeof(*sp)); -+ if (master == NULL) { -+ dev_err(&pdev->dev, "failed to allocate spi master\n"); -+ return -ENOMEM; -+ } ++ info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl; ++ info->chip.dev_ready = rb4xx_nand_dev_ready; ++ info->chip.read_byte = rb4xx_nand_read_byte; ++ info->chip.write_buf = rb4xx_nand_write_buf; ++ info->chip.read_buf = rb4xx_nand_read_buf; ++#if 0 ++ info->chip.verify_buf = rb4xx_nand_verify_buf; ++#endif + -+ sp = spi_master_get_devdata(master); -+ platform_set_drvdata(pdev, sp); ++ info->chip.chip_delay = 25; ++ info->chip.ecc.mode = NAND_ECC_SOFT; ++ info->chip.options |= NAND_NO_AUTOINCR; + -+ pdata = pdev->dev.platform_data; ++ platform_set_drvdata(pdev, info); + -+ master->setup = pb44_spi_setup; -+ master->cleanup = pb44_spi_cleanup; -+ if (pdata) { -+ master->bus_num = pdata->bus_num; -+ master->num_chipselect = pdata->num_chipselect; -+ } else { -+ master->bus_num = 0; -+ master->num_chipselect = 1; ++ ret = nand_scan_ident(&info->mtd, 1, NULL); ++ if (ret) { ++ ret = -ENXIO; ++ goto err_free_info; + } + -+ sp->bitbang.master = spi_master_get(master); -+ sp->bitbang.chipselect = pb44_spi_chipselect; -+ sp->bitbang.txrx_word[SPI_MODE_0] = pb44_spi_txrx_mode0; -+ sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; -+ sp->bitbang.flags = SPI_CS_HIGH; ++ if (info->mtd.writesize == 512) ++ info->chip.ecc.layout = &rb4xx_nand_ecclayout; + -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (r == NULL) { -+ ret = -ENOENT; -+ goto err1; ++ ret = nand_scan_tail(&info->mtd); ++ if (ret) { ++ return -ENXIO; ++ goto err_set_drvdata; + } + -+ sp->base = ioremap_nocache(r->start, r->end - r->start + 1); -+ if (!sp->base) { -+ ret = -ENXIO; -+ goto err1; -+ } ++#ifdef CONFIG_MTD_PARTITIONS ++ ret = add_mtd_partitions(&info->mtd, rb4xx_nand_partitions, ++ ARRAY_SIZE(rb4xx_nand_partitions)); ++#else ++ ret = add_mtd_device(&info->mtd); ++#endif ++ if (ret) ++ goto err_release_nand; + -+ ret = spi_bitbang_start(&sp->bitbang); -+ if (!ret) -+ return 0; ++ return 0; + -+ iounmap(sp->base); -+ err1: ++err_release_nand: ++ nand_release(&info->mtd); ++err_set_drvdata: + platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); -+ ++err_free_info: ++ kfree(info); ++err_free_gpio_nce: ++ gpio_free(RB4XX_NAND_GPIO_NCE); ++err_free_gpio_cle: ++ gpio_free(RB4XX_NAND_GPIO_CLE); ++err_free_gpio_ale: ++ gpio_free(RB4XX_NAND_GPIO_ALE); ++err_free_gpio_ready: ++ gpio_free(RB4XX_NAND_GPIO_READY); ++err: + return ret; +} + -+static int pb44_spi_remove(struct platform_device *pdev) ++static int __devexit rb4xx_nand_remove(struct platform_device *pdev) +{ -+ struct ar71xx_spi *sp = platform_get_drvdata(pdev); ++ struct rb4xx_nand_info *info = platform_get_drvdata(pdev); + -+ spi_bitbang_stop(&sp->bitbang); -+ iounmap(sp->base); ++ nand_release(&info->mtd); + platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); ++ kfree(info); ++ gpio_free(RB4XX_NAND_GPIO_NCE); ++ gpio_free(RB4XX_NAND_GPIO_CLE); ++ gpio_free(RB4XX_NAND_GPIO_ALE); ++ gpio_free(RB4XX_NAND_GPIO_READY); + + return 0; +} + -+static struct platform_driver pb44_spi_drv = { -+ .probe = pb44_spi_probe, -+ .remove = pb44_spi_remove, -+ .driver = { ++static struct platform_driver rb4xx_nand_driver = { ++ .probe = rb4xx_nand_probe, ++ .remove = __devexit_p(rb4xx_nand_remove), ++ .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + -+static int __init pb44_spi_init(void) ++static int __init rb4xx_nand_init(void) +{ -+ return platform_driver_register(&pb44_spi_drv); ++ return platform_driver_register(&rb4xx_nand_driver); +} -+module_init(pb44_spi_init); + -+static void __exit pb44_spi_exit(void) ++static void __exit rb4xx_nand_exit(void) +{ -+ platform_driver_unregister(&pb44_spi_drv); ++ platform_driver_unregister(&rb4xx_nand_driver); +} -+module_exit(pb44_spi_exit); + -+MODULE_ALIAS("platform:" DRV_NAME); ++module_init(rb4xx_nand_init); ++module_exit(rb4xx_nand_exit); ++ +MODULE_DESCRIPTION(DRV_DESC); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("Gabor Juhos "); ++MODULE_AUTHOR("Imre Kaloz "); +MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.39.orig/drivers/spi/spi_vsc7385.c linux-2.6.39/drivers/spi/spi_vsc7385.c ---- linux-2.6.39.orig/drivers/spi/spi_vsc7385.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/spi_vsc7385.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,620 @@ +diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c linux-2.6.39/drivers/mtd/nand/rb750_nand.c +--- linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/mtd/nand/rb750_nand.c 2011-04-27 12:19:22.177661504 +0200 +@@ -0,0 +1,361 @@ +/* -+ * SPI driver for the Vitesse VSC7385 ethernet switch -+ * -+ * Copyright (C) 2009 Gabor Juhos ++ * NAND flash driver for the MikroTik RouterBOARD 750 + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Copyright (C) 2010 Gabor Juhos + * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + */ + -+#include -+#include +#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#include ++#include ++#include ++#include ++#include ++#include + -+#define DRV_NAME "spi-vsc7385" -+#define DRV_DESC "Vitesse VSC7385 Gbit ethernet switch driver" -+#define DRV_VERSION "0.1.0" ++#include ++#include + -+#define VSC73XX_BLOCK_MAC 0x1 -+#define VSC73XX_BLOCK_2 0x2 -+#define VSC73XX_BLOCK_MII 0x3 -+#define VSC73XX_BLOCK_4 0x4 -+#define VSC73XX_BLOCK_5 0x5 -+#define VSC73XX_BLOCK_SYSTEM 0x7 ++#define DRV_NAME "rb750-nand" ++#define DRV_VERSION "0.1.0" ++#define DRV_DESC "NAND flash driver for the RouterBOARD 750" + -+#define VSC73XX_SUBBLOCK_PORT_0 0 -+#define VSC73XX_SUBBLOCK_PORT_1 1 -+#define VSC73XX_SUBBLOCK_PORT_2 2 -+#define VSC73XX_SUBBLOCK_PORT_3 3 -+#define VSC73XX_SUBBLOCK_PORT_4 4 -+#define VSC73XX_SUBBLOCK_PORT_MAC 6 ++#define RB750_NAND_IO0 BIT(RB750_GPIO_NAND_IO0) ++#define RB750_NAND_ALE BIT(RB750_GPIO_NAND_ALE) ++#define RB750_NAND_CLE BIT(RB750_GPIO_NAND_CLE) ++#define RB750_NAND_NRE BIT(RB750_GPIO_NAND_NRE) ++#define RB750_NAND_NWE BIT(RB750_GPIO_NAND_NWE) ++#define RB750_NAND_RDY BIT(RB750_GPIO_NAND_RDY) ++#define RB750_NAND_NCE BIT(RB750_GPIO_NAND_NCE) + -+/* MAC Block registers */ -+#define VSC73XX_MAC_CFG 0x0 -+#define VSC73XX_ADVPORTM 0x19 -+#define VSC73XX_RXOCT 0x50 -+#define VSC73XX_TXOCT 0x51 -+#define VSC73XX_C_RX0 0x52 -+#define VSC73XX_C_RX1 0x53 -+#define VSC73XX_C_RX2 0x54 -+#define VSC73XX_C_TX0 0x55 -+#define VSC73XX_C_TX1 0x56 -+#define VSC73XX_C_TX2 0x57 -+#define VSC73XX_C_CFG 0x58 ++#define RB750_NAND_DATA_SHIFT 1 ++#define RB750_NAND_DATA_BITS (0xff << RB750_NAND_DATA_SHIFT) ++#define RB750_NAND_INPUT_BITS (RB750_NAND_DATA_BITS | RB750_NAND_RDY) ++#define RB750_NAND_OUTPUT_BITS (RB750_NAND_ALE | RB750_NAND_CLE | \ ++ RB750_NAND_NRE | RB750_NAND_NWE | \ ++ RB750_NAND_NCE) + -+/* MAC_CFG register bits */ -+#define VSC73XX_MAC_CFG_WEXC_DIS (1 << 31) -+#define VSC73XX_MAC_CFG_PORT_RST (1 << 29) -+#define VSC73XX_MAC_CFG_TX_EN (1 << 28) -+#define VSC73XX_MAC_CFG_SEED_LOAD (1 << 27) -+#define VSC73XX_MAC_CFG_FDX (1 << 18) -+#define VSC73XX_MAC_CFG_GIGE (1 << 17) -+#define VSC73XX_MAC_CFG_RX_EN (1 << 16) -+#define VSC73XX_MAC_CFG_VLAN_DBLAWR (1 << 15) -+#define VSC73XX_MAC_CFG_VLAN_AWR (1 << 14) -+#define VSC73XX_MAC_CFG_100_BASE_T (1 << 13) -+#define VSC73XX_MAC_CFG_TX_IPG(x) (((x) & 0x1f) << 6) -+#define VSC73XX_MAC_CFG_MAC_RX_RST (1 << 5) -+#define VSC73XX_MAC_CFG_MAC_TX_RST (1 << 4) -+#define VSC73XX_MAC_CFG_BIT2 (1 << 2) -+#define VSC73XX_MAC_CFG_CLK_SEL(x) ((x) & 0x3) ++struct rb750_nand_info { ++ struct nand_chip chip; ++ struct mtd_info mtd; ++}; + -+/* ADVPORTM register bits */ -+#define VSC73XX_ADVPORTM_IFG_PPM (1 << 7) -+#define VSC73XX_ADVPORTM_EXC_COL_CONT (1 << 6) -+#define VSC73XX_ADVPORTM_EXT_PORT (1 << 5) -+#define VSC73XX_ADVPORTM_INV_GTX (1 << 4) -+#define VSC73XX_ADVPORTM_ENA_GTX (1 << 3) -+#define VSC73XX_ADVPORTM_DDR_MODE (1 << 2) -+#define VSC73XX_ADVPORTM_IO_LOOPBACK (1 << 1) -+#define VSC73XX_ADVPORTM_HOST_LOOPBACK (1 << 0) ++/* ++ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader ++ * will not be able to find the kernel that we load. ++ */ ++static struct nand_ecclayout rb750_nand_ecclayout = { ++ .eccbytes = 6, ++ .eccpos = { 8, 9, 10, 13, 14, 15 }, ++ .oobavail = 9, ++ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } ++}; + -+/* MII Block registers */ -+#define VSC73XX_MII_STAT 0x0 -+#define VSC73XX_MII_CMD 0x1 -+#define VSC73XX_MII_DATA 0x2 ++static struct mtd_partition rb750_nand_partitions[] = { ++ { ++ .name = "booter", ++ .offset = 0, ++ .size = (256 * 1024), ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "kernel", ++ .offset = (256 * 1024), ++ .size = (4 * 1024 * 1024) - (256 * 1024), ++ }, { ++ .name = "rootfs", ++ .offset = MTDPART_OFS_NXTBLK, ++ .size = MTDPART_SIZ_FULL, ++ }, ++}; + -+/* System Block registers */ -+#define VSC73XX_ICPU_SIPAD 0x01 -+#define VSC73XX_ICPU_CLOCK_DELAY 0x05 -+#define VSC73XX_ICPU_CTRL 0x10 -+#define VSC73XX_ICPU_ADDR 0x11 -+#define VSC73XX_ICPU_SRAM 0x12 -+#define VSC73XX_ICPU_MBOX_VAL 0x15 -+#define VSC73XX_ICPU_MBOX_SET 0x16 -+#define VSC73XX_ICPU_MBOX_CLR 0x17 -+#define VSC73XX_ICPU_CHIPID 0x18 -+#define VSC73XX_ICPU_GPIO 0x34 ++static void rb750_nand_write(const u8 *buf, unsigned len) ++{ ++ void __iomem *base = ar71xx_gpio_base; ++ u32 out; ++ unsigned i; + -+#define VSC73XX_ICPU_CTRL_CLK_DIV (1 << 8) -+#define VSC73XX_ICPU_CTRL_SRST_HOLD (1 << 7) -+#define VSC73XX_ICPU_CTRL_BOOT_EN (1 << 3) -+#define VSC73XX_ICPU_CTRL_EXT_ACC_EN (1 << 2) -+#define VSC73XX_ICPU_CTRL_CLK_EN (1 << 1) -+#define VSC73XX_ICPU_CTRL_SRST (1 << 0) ++ /* set data lines to output mode */ ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_DATA_BITS, ++ base + GPIO_REG_OE); + -+#define VSC73XX_ICPU_CHIPID_ID_SHIFT 12 -+#define VSC73XX_ICPU_CHIPID_ID_MASK 0xffff -+#define VSC73XX_ICPU_CHIPID_REV_SHIFT 28 -+#define VSC73XX_ICPU_CHIPID_REV_MASK 0xf -+#define VSC73XX_ICPU_CHIPID_ID_7385 0x7385 -+#define VSC73XX_ICPU_CHIPID_ID_7395 0x7395 ++ out = __raw_readl(base + GPIO_REG_OUT); ++ out &= ~(RB750_NAND_DATA_BITS | RB750_NAND_NWE); ++ for (i = 0; i != len; i++) { ++ u32 data; + -+#define VSC73XX_CMD_MODE_READ 0 -+#define VSC73XX_CMD_MODE_WRITE 1 -+#define VSC73XX_CMD_MODE_SHIFT 4 -+#define VSC73XX_CMD_BLOCK_SHIFT 5 -+#define VSC73XX_CMD_BLOCK_MASK 0x7 -+#define VSC73XX_CMD_SUBBLOCK_MASK 0xf ++ data = buf[i]; ++ data <<= RB750_NAND_DATA_SHIFT; ++ data |= out; ++ __raw_writel(data, base + GPIO_REG_OUT); + -+#define VSC7385_CLOCK_DELAY ((3 << 4) | 3) -+#define VSC7385_CLOCK_DELAY_MASK ((3 << 4) | 3) ++ __raw_writel(data | RB750_NAND_NWE, base + GPIO_REG_OUT); ++ /* flush write */ ++ __raw_readl(base + GPIO_REG_OUT); ++ } + -+#define VSC73XX_ICPU_CTRL_STOP (VSC73XX_ICPU_CTRL_SRST_HOLD | \ -+ VSC73XX_ICPU_CTRL_BOOT_EN | \ -+ VSC73XX_ICPU_CTRL_EXT_ACC_EN) ++ /* set data lines to input mode */ ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~RB750_NAND_DATA_BITS, ++ base + GPIO_REG_OE); ++ /* flush write */ ++ __raw_readl(base + GPIO_REG_OE); ++} + -+#define VSC73XX_ICPU_CTRL_START (VSC73XX_ICPU_CTRL_CLK_DIV | \ -+ VSC73XX_ICPU_CTRL_BOOT_EN | \ -+ VSC73XX_ICPU_CTRL_CLK_EN | \ -+ VSC73XX_ICPU_CTRL_SRST) ++static int rb750_nand_read_verify(u8 *read_buf, unsigned len, ++ const u8 *verify_buf) ++{ ++ void __iomem *base = ar71xx_gpio_base; ++ unsigned i; + -+#define VSC7385_ADVPORTM_MASK (VSC73XX_ADVPORTM_IFG_PPM | \ -+ VSC73XX_ADVPORTM_EXC_COL_CONT | \ -+ VSC73XX_ADVPORTM_EXT_PORT | \ -+ VSC73XX_ADVPORTM_INV_GTX | \ -+ VSC73XX_ADVPORTM_ENA_GTX | \ -+ VSC73XX_ADVPORTM_DDR_MODE | \ -+ VSC73XX_ADVPORTM_IO_LOOPBACK | \ -+ VSC73XX_ADVPORTM_HOST_LOOPBACK) ++ for (i = 0; i < len; i++) { ++ u8 data; + -+#define VSC7385_ADVPORTM_INIT (VSC73XX_ADVPORTM_EXT_PORT | \ -+ VSC73XX_ADVPORTM_ENA_GTX | \ -+ VSC73XX_ADVPORTM_DDR_MODE) ++ /* activate RE line */ ++ __raw_writel(RB750_NAND_NRE, base + GPIO_REG_CLEAR); ++ /* flush write */ ++ __raw_readl(base + GPIO_REG_CLEAR); + -+#define VSC7385_MAC_CFG_RESET (VSC73XX_MAC_CFG_PORT_RST | \ -+ VSC73XX_MAC_CFG_MAC_RX_RST | \ -+ VSC73XX_MAC_CFG_MAC_TX_RST) ++ /* read input lines */ ++ data = __raw_readl(base + GPIO_REG_IN) >> RB750_NAND_DATA_SHIFT; + -+#define VSC73XX_MAC_CFG_INIT (VSC73XX_MAC_CFG_TX_EN | \ -+ VSC73XX_MAC_CFG_FDX | \ -+ VSC73XX_MAC_CFG_GIGE | \ -+ VSC73XX_MAC_CFG_RX_EN) ++ /* deactivate RE line */ ++ __raw_writel(RB750_NAND_NRE, base + GPIO_REG_SET); + -+#define VSC73XX_RESET_DELAY 100 ++ if (read_buf) ++ read_buf[i] = data; ++ else if (verify_buf && verify_buf[i] != data) ++ return -EFAULT; ++ } + -+struct vsc7385 { -+ struct spi_device *spi; -+ struct mutex lock; -+ struct vsc7385_platform_data *pdata; -+}; ++ return 0; ++} + -+static int vsc7385_is_addr_valid(u8 block, u8 subblock) ++static void rb750_nand_select_chip(struct mtd_info *mtd, int chip) +{ -+ switch (block) { -+ case VSC73XX_BLOCK_MAC: -+ switch (subblock) { -+ case 0 ... 4: -+ case 6: -+ return 1; -+ } -+ break; ++ void __iomem *base = ar71xx_gpio_base; ++ u32 func; + -+ case VSC73XX_BLOCK_2: -+ case VSC73XX_BLOCK_SYSTEM: -+ switch (subblock) { -+ case 0: -+ return 1; -+ } -+ break; -+ -+ case VSC73XX_BLOCK_MII: -+ case VSC73XX_BLOCK_4: -+ case VSC73XX_BLOCK_5: -+ switch (subblock) { -+ case 0 ... 1: -+ return 1; -+ } -+ break; -+ } -+ -+ return 0; -+} -+ -+static inline u8 vsc7385_make_addr(u8 mode, u8 block, u8 subblock) -+{ -+ u8 ret; -+ -+ ret = (block & VSC73XX_CMD_BLOCK_MASK) << VSC73XX_CMD_BLOCK_SHIFT; -+ ret |= (mode & 1) << VSC73XX_CMD_MODE_SHIFT; -+ ret |= subblock & VSC73XX_CMD_SUBBLOCK_MASK; -+ -+ return ret; -+} -+ -+static int vsc7385_read(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg, -+ u32 *value) -+{ -+ u8 cmd[4]; -+ u8 buf[4]; -+ struct spi_transfer t[2]; -+ struct spi_message m; -+ int err; -+ -+ if (!vsc7385_is_addr_valid(block, subblock)) -+ return -EINVAL; -+ -+ spi_message_init(&m); -+ -+ memset(&t, 0, sizeof(t)); ++ func = __raw_readl(base + GPIO_REG_FUNC); ++ if (chip >= 0) { ++ /* disable latch */ ++ rb750_latch_change(RB750_LVC573_LE, 0); + -+ t[0].tx_buf = cmd; -+ t[0].len = sizeof(cmd); -+ spi_message_add_tail(&t[0], &m); ++ /* disable alternate functions */ ++ ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, ++ AR724X_GPIO_FUNC_SPI_EN); + -+ t[1].rx_buf = buf; -+ t[1].len = sizeof(buf); -+ spi_message_add_tail(&t[1], &m); ++ /* set input mode for data lines */ ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ++ ~RB750_NAND_INPUT_BITS, ++ base + GPIO_REG_OE); + -+ cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_READ, block, subblock); -+ cmd[1] = reg; -+ cmd[2] = 0; -+ cmd[3] = 0; ++ /* deactivate RE and WE lines */ ++ __raw_writel(RB750_NAND_NRE | RB750_NAND_NWE, ++ base + GPIO_REG_SET); ++ /* flush write */ ++ (void) __raw_readl(base + GPIO_REG_SET); + -+ mutex_lock(&vsc->lock); -+ err = spi_sync(vsc->spi, &m); -+ mutex_unlock(&vsc->lock); ++ /* activate CE line */ ++ __raw_writel(RB750_NAND_NCE, base + GPIO_REG_CLEAR); ++ } else { ++ /* deactivate CE line */ ++ __raw_writel(RB750_NAND_NCE, base + GPIO_REG_SET); ++ /* flush write */ ++ (void) __raw_readl(base + GPIO_REG_SET); + -+ if (err) -+ return err; ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) | ++ RB750_NAND_IO0 | RB750_NAND_RDY, ++ base + GPIO_REG_OE); + -+ *value = (((u32) buf[0]) << 24) | (((u32) buf[1]) << 16) | -+ (((u32) buf[2]) << 8) | ((u32) buf[3]); ++ /* restore alternate functions */ ++ ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN, ++ AR724X_GPIO_FUNC_JTAG_DISABLE); + -+ return 0; ++ /* enable latch */ ++ rb750_latch_change(0, RB750_LVC573_LE); ++ } +} + -+ -+static int vsc7385_write(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg, -+ u32 value) ++static int rb750_nand_dev_ready(struct mtd_info *mtd) +{ -+ u8 cmd[2]; -+ u8 buf[4]; -+ struct spi_transfer t[2]; -+ struct spi_message m; -+ int err; -+ -+ if (!vsc7385_is_addr_valid(block, subblock)) -+ return -EINVAL; -+ -+ spi_message_init(&m); -+ -+ memset(&t, 0, sizeof(t)); -+ -+ t[0].tx_buf = cmd; -+ t[0].len = sizeof(cmd); -+ spi_message_add_tail(&t[0], &m); -+ -+ t[1].tx_buf = buf; -+ t[1].len = sizeof(buf); -+ spi_message_add_tail(&t[1], &m); -+ -+ cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_WRITE, block, subblock); -+ cmd[1] = reg; -+ -+ buf[0] = (value >> 24) & 0xff; -+ buf[1] = (value >> 16) & 0xff; -+ buf[2] = (value >> 8) & 0xff; -+ buf[3] = value & 0xff; -+ -+ mutex_lock(&vsc->lock); -+ err = spi_sync(vsc->spi, &m); -+ mutex_unlock(&vsc->lock); ++ void __iomem *base = ar71xx_gpio_base; + -+ return err; ++ return !!(__raw_readl(base + GPIO_REG_IN) & RB750_NAND_RDY); +} + -+static inline int vsc7385_write_verify(struct vsc7385 *vsc, u8 block, -+ u8 subblock, u8 reg, u32 value, -+ u32 read_mask, u32 read_val) ++static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, ++ unsigned int ctrl) +{ -+ struct spi_device *spi = vsc->spi; -+ u32 t; -+ int err; ++ if (ctrl & NAND_CTRL_CHANGE) { ++ void __iomem *base = ar71xx_gpio_base; ++ u32 t; + -+ err = vsc7385_write(vsc, block, subblock, reg, value); -+ if (err) -+ return err; ++ t = __raw_readl(base + GPIO_REG_OUT); + -+ err = vsc7385_read(vsc, block, subblock, reg, &t); -+ if (err) -+ return err; ++ t &= ~(RB750_NAND_CLE | RB750_NAND_ALE); ++ t |= (ctrl & NAND_CLE) ? RB750_NAND_CLE : 0; ++ t |= (ctrl & NAND_ALE) ? RB750_NAND_ALE : 0; + -+ if ((t & read_mask) != read_val) { -+ dev_err(&spi->dev, "register write error\n"); -+ return -EIO; ++ __raw_writel(t, base + GPIO_REG_OUT); ++ /* flush write */ ++ __raw_readl(base + GPIO_REG_OUT); + } + -+ return 0; ++ if (cmd != NAND_CMD_NONE) { ++ u8 t = cmd; ++ rb750_nand_write(&t, 1); ++ } +} + -+static inline int vsc7385_set_clock_delay(struct vsc7385 *vsc, u32 val) ++static u8 rb750_nand_read_byte(struct mtd_info *mtd) +{ -+ return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_CLOCK_DELAY, val); ++ u8 data = 0; ++ rb750_nand_read_verify(&data, 1, NULL); ++ return data; +} + -+static inline int vsc7385_get_clock_delay(struct vsc7385 *vsc, u32 *val) ++static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) +{ -+ return vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_CLOCK_DELAY, val); ++ rb750_nand_read_verify(buf, len, NULL); +} + -+static inline int vsc7385_icpu_stop(struct vsc7385 *vsc) ++static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) +{ -+ return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL, -+ VSC73XX_ICPU_CTRL_STOP); ++ rb750_nand_write(buf, len); +} + -+static inline int vsc7385_icpu_start(struct vsc7385 *vsc) ++static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len) +{ -+ return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL, -+ VSC73XX_ICPU_CTRL_START); ++ return rb750_nand_read_verify(NULL, len, buf); +} + -+static inline int vsc7385_icpu_reset(struct vsc7385 *vsc) ++static void __init rb750_nand_gpio_init(void) +{ -+ int rc; ++ void __iomem *base = ar71xx_gpio_base; ++ u32 out; + -+ rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_ADDR, -+ 0x0000); -+ if (rc) -+ dev_err(&vsc->spi->dev, -+ "could not reset microcode, err=%d\n", rc); ++ out = __raw_readl(base + GPIO_REG_OUT); + -+ return rc; -+} ++ /* setup output levels */ ++ __raw_writel(RB750_NAND_NCE | RB750_NAND_NRE | RB750_NAND_NWE, ++ base + GPIO_REG_SET); + -+static int vsc7385_upload_ucode(struct vsc7385 *vsc) -+{ -+ struct spi_device *spi = vsc->spi; -+ const struct firmware *firmware; -+ char *ucode_name; -+ unsigned char *dp; -+ unsigned int curVal; -+ int i; -+ int diffs; -+ int rc; ++ __raw_writel(RB750_NAND_ALE | RB750_NAND_CLE, ++ base + GPIO_REG_CLEAR); + -+ ucode_name = (vsc->pdata->ucode_name) ? vsc->pdata->ucode_name -+ : "vsc7385_ucode.bin"; -+ rc = request_firmware(&firmware, ucode_name, &spi->dev); -+ if (rc) { -+ dev_err(&spi->dev, "request_firmware failed, err=%d\n", -+ rc); -+ return rc; -+ } ++ /* setup input lines */ ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(RB750_NAND_INPUT_BITS), ++ base + GPIO_REG_OE); + -+ rc = vsc7385_icpu_stop(vsc); -+ if (rc) -+ goto out; ++ /* setup output lines */ ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_OUTPUT_BITS, ++ base + GPIO_REG_OE); + -+ rc = vsc7385_icpu_reset(vsc); -+ if (rc) -+ goto out; ++ rb750_latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0); ++} + -+ dev_info(&spi->dev, "uploading microcode...\n"); ++static int __init rb750_nand_probe(struct platform_device *pdev) ++{ ++ struct rb750_nand_info *info; ++ int ret; + -+ dp = (unsigned char *) firmware->data; -+ for (i = 0; i < firmware->size; i++) { -+ rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_SRAM, *dp++); -+ if (rc) { -+ dev_err(&spi->dev, "could not load microcode, err=%d\n", -+ rc); -+ goto out; -+ } -+ } ++ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); + -+ rc = vsc7385_icpu_reset(vsc); -+ if (rc) -+ goto out; ++ rb750_nand_gpio_init(); + -+ dev_info(&spi->dev, "verifying microcode...\n"); -+ -+ dp = (unsigned char *) firmware->data; -+ diffs = 0; -+ for (i = 0; i < firmware->size; i++) { -+ rc = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_SRAM, &curVal); -+ if (rc) { -+ dev_err(&spi->dev, "could not read microcode %d\n",rc); -+ goto out; -+ } -+ -+ if (curVal > 0xff) { -+ dev_err(&spi->dev, "bad val read: %04x : %02x %02x\n", -+ i, *dp, curVal); -+ rc = -EIO; -+ goto out; -+ } -+ -+ if ((curVal & 0xff) != *dp) { -+ diffs++; -+ dev_err(&spi->dev, "verify error: %04x : %02x %02x\n", -+ i, *dp, curVal); -+ -+ if (diffs > 4) -+ break; -+ } -+ dp++; -+ } -+ -+ if (diffs) { -+ dev_err(&spi->dev, "microcode verification failed\n"); -+ rc = -EIO; -+ goto out; -+ } -+ -+ dev_info(&spi->dev, "microcode uploaded\n"); -+ -+ rc = vsc7385_icpu_start(vsc); -+ -+ out: -+ release_firmware(firmware); -+ return rc; -+} -+ -+static int vsc7385_setup(struct vsc7385 *vsc) -+{ -+ struct vsc7385_platform_data *pdata = vsc->pdata; -+ u32 t; -+ int err; -+ -+ err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_CLOCK_DELAY, -+ VSC7385_CLOCK_DELAY, -+ VSC7385_CLOCK_DELAY_MASK, -+ VSC7385_CLOCK_DELAY); -+ if (err) -+ goto err; -+ -+ err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_MAC, -+ VSC73XX_SUBBLOCK_PORT_MAC, VSC73XX_ADVPORTM, -+ VSC7385_ADVPORTM_INIT, -+ VSC7385_ADVPORTM_MASK, -+ VSC7385_ADVPORTM_INIT); -+ if (err) -+ goto err; -+ -+ err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC, -+ VSC73XX_MAC_CFG, VSC7385_MAC_CFG_RESET); -+ if (err) -+ goto err; -+ -+ t = VSC73XX_MAC_CFG_INIT; -+ t |= VSC73XX_MAC_CFG_TX_IPG(pdata->mac_cfg.tx_ipg); -+ t |= VSC73XX_MAC_CFG_CLK_SEL(pdata->mac_cfg.clk_sel); -+ if (pdata->mac_cfg.bit2) -+ t |= VSC73XX_MAC_CFG_BIT2; -+ -+ err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC, -+ VSC73XX_MAC_CFG, t); -+ if (err) -+ goto err; -+ -+ return 0; -+ -+ err: -+ return err; -+} -+ -+static int vsc7385_detect(struct vsc7385 *vsc) -+{ -+ struct spi_device *spi = vsc->spi; -+ u32 t; -+ u32 id; -+ u32 rev; -+ int err; -+ -+ err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_MBOX_VAL, &t); -+ if (err) { -+ dev_err(&spi->dev, "unable to read mailbox, err=%d\n", err); -+ return err; -+ } -+ -+ if (t == 0xffffffff) { -+ dev_dbg(&spi->dev, "assert chip reset\n"); -+ if (vsc->pdata->reset) -+ vsc->pdata->reset(); -+ -+ } -+ -+ err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_CHIPID, &t); -+ if (err) { -+ dev_err(&spi->dev, "unable to read chip id, err=%d\n", err); -+ return err; -+ } -+ -+ id = (t >> VSC73XX_ICPU_CHIPID_ID_SHIFT) & VSC73XX_ICPU_CHIPID_ID_MASK; -+ switch (id) { -+ case VSC73XX_ICPU_CHIPID_ID_7385: -+ case VSC73XX_ICPU_CHIPID_ID_7395: -+ break; -+ default: -+ dev_err(&spi->dev, "unsupported chip, id=%04x\n", id); -+ return -ENODEV; -+ } -+ -+ rev = (t >> VSC73XX_ICPU_CHIPID_REV_SHIFT) & -+ VSC73XX_ICPU_CHIPID_REV_MASK; -+ dev_info(&spi->dev, "VSC%04X (rev. %d) switch found \n", id, rev); ++ info = kzalloc(sizeof(*info), GFP_KERNEL); ++ if (!info) ++ return -ENOMEM; + -+ return 0; -+} ++ info->chip.priv = &info; ++ info->mtd.priv = &info->chip; ++ info->mtd.owner = THIS_MODULE; + -+static int __devinit vsc7385_probe(struct spi_device *spi) -+{ -+ struct vsc7385 *vsc; -+ struct vsc7385_platform_data *pdata; -+ int err; ++ info->chip.select_chip = rb750_nand_select_chip; ++ info->chip.cmd_ctrl = rb750_nand_cmd_ctrl; ++ info->chip.dev_ready = rb750_nand_dev_ready; ++ info->chip.read_byte = rb750_nand_read_byte; ++ info->chip.write_buf = rb750_nand_write_buf; ++ info->chip.read_buf = rb750_nand_read_buf; ++ info->chip.verify_buf = rb750_nand_verify_buf; + -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n"); ++ info->chip.chip_delay = 25; ++ info->chip.ecc.mode = NAND_ECC_SOFT; ++ info->chip.options |= NAND_NO_AUTOINCR; + -+ pdata = spi->dev.platform_data; -+ if (!pdata) { -+ dev_err(&spi->dev, "no platform data specified\n"); -+ return-ENODEV; -+ } ++ platform_set_drvdata(pdev, info); + -+ vsc = kzalloc(sizeof(*vsc), GFP_KERNEL); -+ if (!vsc) { -+ dev_err(&spi->dev, "no memory for private data\n"); -+ return-ENOMEM; ++ ret = nand_scan_ident(&info->mtd, 1); ++ if (ret) { ++ ret = -ENXIO; ++ goto err_free_info; + } + -+ mutex_init(&vsc->lock); -+ vsc->pdata = pdata; -+ vsc->spi = spi_dev_get(spi); -+ dev_set_drvdata(&spi->dev, vsc); -+ -+ spi->mode = SPI_MODE_0; -+ spi->bits_per_word = 8; -+ err = spi_setup(spi); -+ if (err) { -+ dev_err(&spi->dev, "spi_setup failed, err=%d \n", err); -+ goto err_drvdata; -+ } ++ if (info->mtd.writesize == 512) ++ info->chip.ecc.layout = &rb750_nand_ecclayout; + -+ err = vsc7385_detect(vsc); -+ if (err) { -+ dev_err(&spi->dev, "no chip found, err=%d \n", err); -+ goto err_drvdata; ++ ret = nand_scan_tail(&info->mtd); ++ if (ret) { ++ return -ENXIO; ++ goto err_set_drvdata; + } + -+ err = vsc7385_upload_ucode(vsc); -+ if (err) -+ goto err_drvdata; -+ -+ err = vsc7385_setup(vsc); -+ if (err) -+ goto err_drvdata; ++#ifdef CONFIG_MTD_PARTITIONS ++ ret = add_mtd_partitions(&info->mtd, rb750_nand_partitions, ++ ARRAY_SIZE(rb750_nand_partitions)); ++#else ++ ret = add_mtd_device(&info->mtd); ++#endif ++ if (ret) ++ goto err_release_nand; + + return 0; + -+ err_drvdata: -+ dev_set_drvdata(&spi->dev, NULL); -+ kfree(vsc); -+ return err; ++err_release_nand: ++ nand_release(&info->mtd); ++err_set_drvdata: ++ platform_set_drvdata(pdev, NULL); ++err_free_info: ++ kfree(info); ++ return ret; +} + -+static int __devexit vsc7385_remove(struct spi_device *spi) ++static int __devexit rb750_nand_remove(struct platform_device *pdev) +{ -+ struct vsc7385_data *vsc; ++ struct rb750_nand_info *info = platform_get_drvdata(pdev); + -+ vsc = dev_get_drvdata(&spi->dev); -+ dev_set_drvdata(&spi->dev, NULL); -+ kfree(vsc); ++ nand_release(&info->mtd); ++ platform_set_drvdata(pdev, NULL); ++ kfree(info); + + return 0; +} + -+static struct spi_driver vsc7385_driver = { -+ .driver = { -+ .name = DRV_NAME, -+ .bus = &spi_bus_type, -+ .owner = THIS_MODULE, ++static struct platform_driver rb750_nand_driver = { ++ .probe = rb750_nand_probe, ++ .remove = __devexit_p(rb750_nand_remove), ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, + }, -+ .probe = vsc7385_probe, -+ .remove = __devexit_p(vsc7385_remove), +}; + -+static int __init vsc7385_init(void) ++static int __init rb750_nand_init(void) +{ -+ return spi_register_driver(&vsc7385_driver); ++ return platform_driver_register(&rb750_nand_driver); +} -+module_init(vsc7385_init); + -+static void __exit vsc7385_exit(void) ++static void __exit rb750_nand_exit(void) +{ -+ spi_unregister_driver(&vsc7385_driver); ++ platform_driver_unregister(&rb750_nand_driver); +} -+module_exit(vsc7385_exit); ++ ++module_init(rb750_nand_init); ++module_exit(rb750_nand_exit); + +MODULE_DESCRIPTION(DRV_DESC); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_LICENSE("GPL v2"); -+ -diff -Nur linux-2.6.39.orig/drivers/usb/host/Kconfig linux-2.6.39/drivers/usb/host/Kconfig ---- linux-2.6.39.orig/drivers/usb/host/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/usb/host/Kconfig 2011-05-27 14:36:51.000000000 +0200 -@@ -129,6 +129,13 @@ - config USB_FSL_MPH_DR_OF - tristate - -+config USB_EHCI_AR71XX -+ bool "USB EHCI support for AR71xx" -+ depends on USB_EHCI_HCD && ATHEROS_AR71XX -+ default y -+ help -+ Support for Atheros AR71xx built-in EHCI controller -+ - config USB_EHCI_FSL - bool "Support for Freescale on-chip EHCI USB controller" - depends on USB_EHCI_HCD && FSL_SOC -@@ -287,6 +294,13 @@ - Enables support for the on-chip OHCI controller on - OMAP3 and later chips. - -+config USB_OHCI_AR71XX -+ bool "USB OHCI support for Atheros AR71xx" -+ depends on USB_OHCI_HCD && ATHEROS_AR71XX -+ default y -+ help -+ Support for Atheros AR71xx built-in OHCI controller -+ - config USB_OHCI_HCD_PPC_SOC - bool "OHCI support for on-chip PPC USB controller" - depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) -diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-ar71xx.c linux-2.6.39/drivers/usb/host/ehci-ar71xx.c ---- linux-2.6.39.orig/drivers/usb/host/ehci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/usb/host/ehci-ar71xx.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,242 @@ +diff -Nur linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c linux-2.6.39/drivers/mtd/wrt160nl_part.c +--- linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/mtd/wrt160nl_part.c 2011-08-06 09:32:37.138017083 +0200 +@@ -0,0 +1,190 @@ +/* -+ * Bus Glue for Atheros AR71xx built-in EHCI controller. ++ * Copyright (C) 2009 Christian Daniel ++ * Copyright (C) 2009 Gabor Juhos + * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * 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. + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * Copyright (C) 2007 Atheros Communications, Inc. ++ * 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. ++ * ++ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ * TRX flash partition table. ++ * Based on ar7 map by Felix Fietkau + * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. + */ + -+#include -+#include ++#include ++#include ++#include + -+#include ++#include ++#include + -+extern int usb_disabled(void); ++struct cybertan_header { ++ char magic[4]; ++ u8 res1[4]; ++ char fw_date[3]; ++ char fw_ver[3]; ++ char id[4]; ++ char hw_ver; ++ char unused; ++ u8 flags[2]; ++ u8 res2[10]; ++}; + -+static int ehci_ar71xx_init(struct usb_hcd *hcd) -+{ -+ struct ehci_hcd *ehci = hcd_to_ehci(hcd); -+ int ret; ++#define TRX_PARTS 6 ++#define TRX_MAGIC 0x30524448 ++#define TRX_MAX_OFFSET 3 + -+ ehci->caps = hcd->regs; -+ ehci->regs = hcd->regs + -+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); -+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); ++struct trx_header { ++ uint32_t magic; /* "HDR0" */ ++ uint32_t len; /* Length of file including header */ ++ uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ ++ uint32_t flag_version; /* 0:15 flags, 16:31 version */ ++ uint32_t offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ ++}; + -+ ehci->sbrn = 0x20; -+ ehci->has_synopsys_hc_bug = 1; ++#define IH_MAGIC 0x27051956 /* Image Magic Number */ ++#define IH_NMLEN 32 /* Image Name Length */ + -+ ehci_reset(ehci); ++struct uimage_header { ++ uint32_t ih_magic; /* Image Header Magic Number */ ++ uint32_t ih_hcrc; /* Image Header CRC Checksum */ ++ uint32_t ih_time; /* Image Creation Timestamp */ ++ uint32_t ih_size; /* Image Data Size */ ++ uint32_t ih_load; /* Data» Load Address */ ++ uint32_t ih_ep; /* Entry Point Address */ ++ uint32_t ih_dcrc; /* Image Data CRC Checksum */ ++ uint8_t ih_os; /* Operating System */ ++ uint8_t ih_arch; /* CPU architecture */ ++ uint8_t ih_type; /* Image Type */ ++ uint8_t ih_comp; /* Compression Type */ ++ uint8_t ih_name[IH_NMLEN]; /* Image Name */ ++}; + -+ ret = ehci_init(hcd); -+ if (ret) -+ return ret; ++struct wrt160nl_header { ++ struct cybertan_header cybertan; ++ struct trx_header trx; ++ struct uimage_header uimage; ++} __attribute__ ((packed)); + -+ ehci_port_power(ehci, 0); ++static struct mtd_partition trx_parts[TRX_PARTS]; + -+ return 0; -+} ++#define WRT160NL_UBOOT_LEN 0x40000 ++#define WRT160NL_ART_LEN 0x10000 ++#define WRT160NL_NVRAM_LEN 0x10000 + -+static int ehci_ar91xx_init(struct usb_hcd *hcd) ++static int wrt160nl_parse_partitions(struct mtd_info *master, ++ struct mtd_partition **pparts, ++ unsigned long origin) +{ -+ struct ehci_hcd *ehci = hcd_to_ehci(hcd); ++ struct wrt160nl_header *header; ++ struct trx_header *theader; ++ struct uimage_header *uheader; ++ size_t retlen; ++ unsigned int kernel_len; ++ unsigned int uboot_len = max(master->erasesize, WRT160NL_UBOOT_LEN); ++ unsigned int nvram_len = max(master->erasesize, WRT160NL_NVRAM_LEN); ++ unsigned int art_len = max(master->erasesize, WRT160NL_ART_LEN); + int ret; + -+ ehci->caps = hcd->regs + 0x100; -+ ehci->regs = hcd->regs + 0x100 + -+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); -+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); -+ -+ hcd->has_tt = 1; -+ ehci->sbrn = 0x20; -+ -+ ehci_reset(ehci); ++ header = vmalloc(sizeof(*header)); ++ if (!header) { ++ return -ENOMEM; ++ goto out; ++ } + -+ ret = ehci_init(hcd); ++ ret = master->read(master, uboot_len, sizeof(*header), ++ &retlen, (void *) header); + if (ret) -+ return ret; -+ -+ ehci_port_power(ehci, 0); ++ goto free_hdr; + -+ return 0; -+} ++ if (retlen != sizeof(*header)) { ++ ret = -EIO; ++ goto free_hdr; ++ } + -+static int ehci_ar71xx_probe(const struct hc_driver *driver, -+ struct usb_hcd **hcd_out, -+ struct platform_device *pdev) -+{ -+ struct usb_hcd *hcd; -+ struct resource *res; -+ int irq; -+ int ret; ++ if (strncmp(header->cybertan.magic, "NL16", 4) != 0) { ++ printk(KERN_NOTICE "%s: no WRT160NL signature found\n", ++ master->name); ++ goto free_hdr; ++ } + -+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (!res) { -+ dev_dbg(&pdev->dev, "no IRQ specified for %s\n", -+ dev_name(&pdev->dev)); -+ return -ENODEV; ++ theader = &header->trx; ++ if (le32_to_cpu(theader->magic) != TRX_MAGIC) { ++ printk(KERN_NOTICE "%s: no TRX header found\n", master->name); ++ goto free_hdr; + } -+ irq = res->start; + -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_dbg(&pdev->dev, "no base address specified for %s\n", -+ dev_name(&pdev->dev)); -+ return -ENODEV; ++ uheader = &header->uimage; ++ if (uheader->ih_magic != IH_MAGIC) { ++ printk(KERN_NOTICE "%s: no uImage found\n", master->name); ++ goto free_hdr; + } + -+ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); -+ if (!hcd) -+ return -ENOMEM; ++ kernel_len = le32_to_cpu(theader->offsets[1]) + ++ sizeof(struct cybertan_header); + -+ hcd->rsrc_start = res->start; -+ hcd->rsrc_len = res->end - res->start + 1; ++ trx_parts[0].name = "u-boot"; ++ trx_parts[0].offset = 0; ++ trx_parts[0].size = uboot_len; ++ trx_parts[0].mask_flags = MTD_WRITEABLE; + -+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { -+ dev_dbg(&pdev->dev, "controller already in use\n"); -+ ret = -EBUSY; -+ goto err_put_hcd; -+ } ++ trx_parts[1].name = "kernel"; ++ trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size; ++ trx_parts[1].size = kernel_len; ++ trx_parts[1].mask_flags = 0; + -+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -+ if (!hcd->regs) { -+ dev_dbg(&pdev->dev, "error mapping memory\n"); -+ ret = -EFAULT; -+ goto err_release_region; -+ } ++ trx_parts[2].name = "rootfs"; ++ trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size; ++ trx_parts[2].size = master->size - uboot_len - nvram_len - art_len - ++ trx_parts[1].size; ++ trx_parts[2].mask_flags = 0; + -+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); -+ if (ret) -+ goto err_iounmap; ++ trx_parts[3].name = "nvram"; ++ trx_parts[3].offset = master->size - nvram_len - art_len; ++ trx_parts[3].size = nvram_len; ++ trx_parts[3].mask_flags = MTD_WRITEABLE; + -+ return 0; ++ trx_parts[4].name = "art"; ++ trx_parts[4].offset = master->size - art_len; ++ trx_parts[4].size = art_len; ++ trx_parts[4].mask_flags = MTD_WRITEABLE; + -+ err_iounmap: -+ iounmap(hcd->regs); ++ trx_parts[5].name = "firmware"; ++ trx_parts[5].offset = uboot_len; ++ trx_parts[5].size = master->size - uboot_len - nvram_len - art_len; ++ trx_parts[5].mask_flags = 0; + -+ err_release_region: -+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -+ err_put_hcd: -+ usb_put_hcd(hcd); ++ *pparts = trx_parts; ++ ret = TRX_PARTS; ++ ++free_hdr: ++ vfree(header); ++out: + return ret; +} + -+static void ehci_ar71xx_remove(struct usb_hcd *hcd, -+ struct platform_device *pdev) ++static struct mtd_part_parser wrt160nl_parser = { ++ .owner = THIS_MODULE, ++ .parse_fn = wrt160nl_parse_partitions, ++ .name = "wrt160nl", ++}; ++ ++static int __init wrt160nl_parser_init(void) +{ -+ usb_remove_hcd(hcd); -+ iounmap(hcd->regs); -+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -+ usb_put_hcd(hcd); ++ return register_mtd_parser(&wrt160nl_parser); +} + -+static const struct hc_driver ehci_ar71xx_hc_driver = { -+ .description = hcd_name, -+ .product_desc = "Atheros AR71xx built-in EHCI controller", -+ .hcd_priv_size = sizeof(struct ehci_hcd), -+ -+ .irq = ehci_irq, -+ .flags = HCD_MEMORY | HCD_USB2, -+ -+ .reset = ehci_ar71xx_init, -+ .start = ehci_run, -+ .stop = ehci_stop, -+ .shutdown = ehci_shutdown, ++module_init(wrt160nl_parser_init); + -+ .urb_enqueue = ehci_urb_enqueue, -+ .urb_dequeue = ehci_urb_dequeue, -+ .endpoint_disable = ehci_endpoint_disable, -+ .endpoint_reset = ehci_endpoint_reset, ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Christian Daniel "); +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar7240.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ar7240.c +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar7240.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ar7240.c 2011-08-06 09:32:37.298018216 +0200 +@@ -0,0 +1,913 @@ ++/* ++ * Driver for the built-in ethernet switch of the Atheros AR7240 SoC ++ * Copyright (c) 2010 Gabor Juhos ++ * Copyright (c) 2010 Felix Fietkau ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ + -+ .get_frame_number = ehci_get_frame, ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "ag71xx.h" + -+ .hub_status_data = ehci_hub_status_data, -+ .hub_control = ehci_hub_control, -+#ifdef CONFIG_PM -+ .hub_suspend = ehci_hub_suspend, -+ .hub_resume = ehci_hub_resume, -+#endif -+ .relinquish_port = ehci_relinquish_port, -+ .port_handed_over = ehci_port_handed_over, ++#define BITM(_count) (BIT(_count) - 1) ++#define BITS(_shift, _count) (BITM(_count) << _shift) + -+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -+}; ++#define AR7240_REG_MASK_CTRL 0x00 ++#define AR7240_MASK_CTRL_REVISION_M BITM(8) ++#define AR7240_MASK_CTRL_VERSION_M BITM(8) ++#define AR7240_MASK_CTRL_VERSION_S 8 ++#define AR7240_MASK_CTRL_SOFT_RESET BIT(31) + -+static const struct hc_driver ehci_ar91xx_hc_driver = { -+ .description = hcd_name, -+ .product_desc = "Atheros AR91xx built-in EHCI controller", -+ .hcd_priv_size = sizeof(struct ehci_hcd), -+ .irq = ehci_irq, -+ .flags = HCD_MEMORY | HCD_USB2, ++#define AR7240_REG_MAC_ADDR0 0x20 ++#define AR7240_REG_MAC_ADDR1 0x24 + -+ .reset = ehci_ar91xx_init, -+ .start = ehci_run, -+ .stop = ehci_stop, -+ .shutdown = ehci_shutdown, ++#define AR7240_REG_FLOOD_MASK 0x2c ++#define AR7240_FLOOD_MASK_BROAD_TO_CPU BIT(26) + -+ .urb_enqueue = ehci_urb_enqueue, -+ .urb_dequeue = ehci_urb_dequeue, -+ .endpoint_disable = ehci_endpoint_disable, -+ .endpoint_reset = ehci_endpoint_reset, ++#define AR7240_REG_GLOBAL_CTRL 0x30 ++#define AR7240_GLOBAL_CTRL_MTU_M BITM(12) + -+ .get_frame_number = ehci_get_frame, ++#define AR7240_REG_VTU 0x0040 ++#define AR7240_VTU_OP BITM(3) ++#define AR7240_VTU_OP_NOOP 0x0 ++#define AR7240_VTU_OP_FLUSH 0x1 ++#define AR7240_VTU_OP_LOAD 0x2 ++#define AR7240_VTU_OP_PURGE 0x3 ++#define AR7240_VTU_OP_REMOVE_PORT 0x4 ++#define AR7240_VTU_ACTIVE BIT(3) ++#define AR7240_VTU_FULL BIT(4) ++#define AR7240_VTU_PORT BITS(8, 4) ++#define AR7240_VTU_PORT_S 8 ++#define AR7240_VTU_VID BITS(16, 12) ++#define AR7240_VTU_VID_S 16 ++#define AR7240_VTU_PRIO BITS(28, 3) ++#define AR7240_VTU_PRIO_S 28 ++#define AR7240_VTU_PRIO_EN BIT(31) ++ ++#define AR7240_REG_VTU_DATA 0x0044 ++#define AR7240_VTUDATA_MEMBER BITS(0, 10) ++#define AR7240_VTUDATA_VALID BIT(11) ++ ++#define AR7240_REG_ATU 0x50 ++#define AR7240_ATU_FLUSH_ALL 0x1 + -+ .hub_status_data = ehci_hub_status_data, -+ .hub_control = ehci_hub_control, -+#ifdef CONFIG_PM -+ .hub_suspend = ehci_hub_suspend, -+ .hub_resume = ehci_hub_resume, -+#endif -+ .relinquish_port = ehci_relinquish_port, -+ .port_handed_over = ehci_port_handed_over, ++#define AR7240_REG_AT_CTRL 0x5c ++#define AR7240_AT_CTRL_AGE_TIME BITS(0, 15) ++#define AR7240_AT_CTRL_AGE_EN BIT(17) ++#define AR7240_AT_CTRL_LEARN_CHANGE BIT(18) ++#define AR7240_AT_CTRL_ARP_EN BIT(20) + -+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -+}; ++#define AR7240_REG_TAG_PRIORITY 0x70 + -+static int ehci_ar71xx_driver_probe(struct platform_device *pdev) -+{ -+ struct ar71xx_ehci_platform_data *pdata; -+ struct usb_hcd *hcd = NULL; -+ int ret; ++#define AR7240_REG_SERVICE_TAG 0x74 ++#define AR7240_SERVICE_TAG_M BITM(16) + -+ if (usb_disabled()) -+ return -ENODEV; ++#define AR7240_REG_CPU_PORT 0x78 ++#define AR7240_MIRROR_PORT_S 4 ++#define AR7240_CPU_PORT_EN BIT(8) + -+ pdata = pdev->dev.platform_data; -+ if (!pdata) { -+ dev_err(&pdev->dev, "no platform data specified for %s\n", -+ dev_name(&pdev->dev)); -+ return -ENODEV; -+ } ++#define AR7240_REG_MIB_FUNCTION0 0x80 ++#define AR7240_MIB_TIMER_M BITM(16) ++#define AR7240_MIB_AT_HALF_EN BIT(16) ++#define AR7240_MIB_BUSY BIT(17) ++#define AR7240_MIB_FUNC_S 24 ++#define AR7240_MIB_FUNC_NO_OP 0x0 ++#define AR7240_MIB_FUNC_FLUSH 0x1 ++#define AR7240_MIB_FUNC_CAPTURE 0x3 + -+ if (pdata->is_ar91xx) -+ ret = ehci_ar71xx_probe(&ehci_ar91xx_hc_driver, &hcd, pdev); -+ else -+ ret = ehci_ar71xx_probe(&ehci_ar71xx_hc_driver, &hcd, pdev); ++#define AR7240_REG_MDIO_CTRL 0x98 ++#define AR7240_MDIO_CTRL_DATA_M BITM(16) ++#define AR7240_MDIO_CTRL_REG_ADDR_S 16 ++#define AR7240_MDIO_CTRL_PHY_ADDR_S 21 ++#define AR7240_MDIO_CTRL_CMD_WRITE 0 ++#define AR7240_MDIO_CTRL_CMD_READ BIT(27) ++#define AR7240_MDIO_CTRL_MASTER_EN BIT(30) ++#define AR7240_MDIO_CTRL_BUSY BIT(31) + -+ return ret; -+} ++#define AR7240_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100) + -+static int ehci_ar71xx_driver_remove(struct platform_device *pdev) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(pdev); ++#define AR7240_REG_PORT_STATUS(_port) (AR7240_REG_PORT_BASE((_port)) + 0x00) ++#define AR7240_PORT_STATUS_SPEED_M BITM(2) ++#define AR7240_PORT_STATUS_SPEED_10 0 ++#define AR7240_PORT_STATUS_SPEED_100 1 ++#define AR7240_PORT_STATUS_SPEED_1000 2 ++#define AR7240_PORT_STATUS_TXMAC BIT(2) ++#define AR7240_PORT_STATUS_RXMAC BIT(3) ++#define AR7240_PORT_STATUS_TXFLOW BIT(4) ++#define AR7240_PORT_STATUS_RXFLOW BIT(5) ++#define AR7240_PORT_STATUS_DUPLEX BIT(6) ++#define AR7240_PORT_STATUS_LINK_UP BIT(8) ++#define AR7240_PORT_STATUS_LINK_AUTO BIT(9) ++#define AR7240_PORT_STATUS_LINK_PAUSE BIT(10) + -+ ehci_ar71xx_remove(hcd, pdev); -+ return 0; -+} ++#define AR7240_REG_PORT_CTRL(_port) (AR7240_REG_PORT_BASE((_port)) + 0x04) ++#define AR7240_PORT_CTRL_STATE_M BITM(3) ++#define AR7240_PORT_CTRL_STATE_DISABLED 0 ++#define AR7240_PORT_CTRL_STATE_BLOCK 1 ++#define AR7240_PORT_CTRL_STATE_LISTEN 2 ++#define AR7240_PORT_CTRL_STATE_LEARN 3 ++#define AR7240_PORT_CTRL_STATE_FORWARD 4 ++#define AR7240_PORT_CTRL_LEARN_LOCK BIT(7) ++#define AR7240_PORT_CTRL_VLAN_MODE_S 8 ++#define AR7240_PORT_CTRL_VLAN_MODE_KEEP 0 ++#define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1 ++#define AR7240_PORT_CTRL_VLAN_MODE_ADD 2 ++#define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3 ++#define AR7240_PORT_CTRL_IGMP_SNOOP BIT(10) ++#define AR7240_PORT_CTRL_HEADER BIT(11) ++#define AR7240_PORT_CTRL_MAC_LOOP BIT(12) ++#define AR7240_PORT_CTRL_SINGLE_VLAN BIT(13) ++#define AR7240_PORT_CTRL_LEARN BIT(14) ++#define AR7240_PORT_CTRL_DOUBLE_TAG BIT(15) ++#define AR7240_PORT_CTRL_MIRROR_TX BIT(16) ++#define AR7240_PORT_CTRL_MIRROR_RX BIT(17) + -+MODULE_ALIAS("platform:ar71xx-ehci"); ++#define AR7240_REG_PORT_VLAN(_port) (AR7240_REG_PORT_BASE((_port)) + 0x08) + -+static struct platform_driver ehci_ar71xx_driver = { -+ .probe = ehci_ar71xx_driver_probe, -+ .remove = ehci_ar71xx_driver_remove, -+ .driver = { -+ .name = "ar71xx-ehci", -+ } -+}; -diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-hcd.c linux-2.6.39/drivers/usb/host/ehci-hcd.c ---- linux-2.6.39.orig/drivers/usb/host/ehci-hcd.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/usb/host/ehci-hcd.c 2011-05-27 14:36:51.000000000 +0200 -@@ -1265,6 +1265,11 @@ - #define PLATFORM_DRIVER tegra_ehci_driver - #endif - -+#ifdef CONFIG_USB_EHCI_AR71XX -+#include "ehci-ar71xx.c" -+#define PLATFORM_DRIVER ehci_ar71xx_driver -+#endif ++#define AR7240_PORT_VLAN_DEFAULT_ID_S 0 ++#define AR7240_PORT_VLAN_DEST_PORTS_S 16 ++#define AR7240_PORT_VLAN_MODE_S 30 ++#define AR7240_PORT_VLAN_MODE_PORT_ONLY 0 ++#define AR7240_PORT_VLAN_MODE_PORT_FALLBACK 1 ++#define AR7240_PORT_VLAN_MODE_VLAN_ONLY 2 ++#define AR7240_PORT_VLAN_MODE_SECURE 3 + - #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ - !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ - !defined(XILINX_OF_PLATFORM_DRIVER) -diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-ar71xx.c linux-2.6.39/drivers/usb/host/ohci-ar71xx.c ---- linux-2.6.39.orig/drivers/usb/host/ohci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/usb/host/ohci-ar71xx.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,165 @@ -+/* -+ * OHCI HCD (Host Controller Driver) for USB. -+ * -+ * Bus Glue for Atheros AR71xx built-in OHCI controller. -+ * -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * Copyright (C) 2007 Atheros Communications, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ + -+#include -+#include ++#define AR7240_REG_STATS_BASE(_port) (0x20000 + (_port) * 0x100) + -+extern int usb_disabled(void); ++#define AR7240_STATS_RXBROAD 0x00 ++#define AR7240_STATS_RXPAUSE 0x04 ++#define AR7240_STATS_RXMULTI 0x08 ++#define AR7240_STATS_RXFCSERR 0x0c ++#define AR7240_STATS_RXALIGNERR 0x10 ++#define AR7240_STATS_RXRUNT 0x14 ++#define AR7240_STATS_RXFRAGMENT 0x18 ++#define AR7240_STATS_RX64BYTE 0x1c ++#define AR7240_STATS_RX128BYTE 0x20 ++#define AR7240_STATS_RX256BYTE 0x24 ++#define AR7240_STATS_RX512BYTE 0x28 ++#define AR7240_STATS_RX1024BYTE 0x2c ++#define AR7240_STATS_RX1518BYTE 0x30 ++#define AR7240_STATS_RXMAXBYTE 0x34 ++#define AR7240_STATS_RXTOOLONG 0x38 ++#define AR7240_STATS_RXGOODBYTE 0x3c ++#define AR7240_STATS_RXBADBYTE 0x44 ++#define AR7240_STATS_RXOVERFLOW 0x4c ++#define AR7240_STATS_FILTERED 0x50 ++#define AR7240_STATS_TXBROAD 0x54 ++#define AR7240_STATS_TXPAUSE 0x58 ++#define AR7240_STATS_TXMULTI 0x5c ++#define AR7240_STATS_TXUNDERRUN 0x60 ++#define AR7240_STATS_TX64BYTE 0x64 ++#define AR7240_STATS_TX128BYTE 0x68 ++#define AR7240_STATS_TX256BYTE 0x6c ++#define AR7240_STATS_TX512BYTE 0x70 ++#define AR7240_STATS_TX1024BYTE 0x74 ++#define AR7240_STATS_TX1518BYTE 0x78 ++#define AR7240_STATS_TXMAXBYTE 0x7c ++#define AR7240_STATS_TXOVERSIZE 0x80 ++#define AR7240_STATS_TXBYTE 0x84 ++#define AR7240_STATS_TXCOLLISION 0x8c ++#define AR7240_STATS_TXABORTCOL 0x90 ++#define AR7240_STATS_TXMULTICOL 0x94 ++#define AR7240_STATS_TXSINGLECOL 0x98 ++#define AR7240_STATS_TXEXCDEFER 0x9c ++#define AR7240_STATS_TXDEFER 0xa0 ++#define AR7240_STATS_TXLATECOL 0xa4 + -+static int usb_hcd_ar71xx_probe(const struct hc_driver *driver, -+ struct platform_device *pdev) -+{ -+ struct usb_hcd *hcd; -+ struct resource *res; -+ int irq; -+ int ret; ++#define AR7240_PORT_CPU 0 ++#define AR7240_NUM_PORTS 6 ++#define AR7240_NUM_PHYS 5 + -+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (!res) { -+ dev_dbg(&pdev->dev, "no IRQ specified for %s\n", -+ dev_name(&pdev->dev)); -+ return -ENODEV; -+ } -+ irq = res->start; ++#define AR7240_PHY_ID1 0x004d ++#define AR7240_PHY_ID2 0xd041 + -+ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); -+ if (!hcd) -+ return -ENOMEM; ++#define AR7240_PORT_MASK(_port) BIT((_port)) ++#define AR7240_PORT_MASK_ALL BITM(AR7240_NUM_PORTS) ++#define AR7240_PORT_MASK_BUT(_port) (AR7240_PORT_MASK_ALL & ~BIT((_port))) + -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_dbg(&pdev->dev, "no base address specified for %s\n", -+ dev_name(&pdev->dev)); -+ ret = -ENODEV; -+ goto err_put_hcd; -+ } -+ hcd->rsrc_start = res->start; -+ hcd->rsrc_len = res->end - res->start + 1; ++#define AR7240_MAX_VLANS 16 + -+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { -+ dev_dbg(&pdev->dev, "controller already in use\n"); -+ ret = -EBUSY; -+ goto err_put_hcd; -+ } ++#define sw_to_ar7240(_dev) container_of(_dev, struct ar7240sw, swdev) + -+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -+ if (!hcd->regs) { -+ dev_dbg(&pdev->dev, "error mapping memory\n"); -+ ret = -EFAULT; -+ goto err_release_region; -+ } ++struct ar7240sw { ++ struct mii_bus *mii_bus; ++ struct switch_dev swdev; ++ bool vlan; ++ u16 vlan_id[AR7240_MAX_VLANS]; ++ u8 vlan_table[AR7240_MAX_VLANS]; ++ u8 vlan_tagged; ++ u16 pvid[AR7240_NUM_PORTS]; ++}; + -+ ohci_hcd_init(hcd_to_ohci(hcd)); ++struct ar7240sw_hw_stat { ++ char string[ETH_GSTRING_LEN]; ++ int sizeof_stat; ++ int reg; ++}; + -+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); -+ if (ret) -+ goto err_stop_hcd; ++static DEFINE_MUTEX(reg_mutex); + -+ return 0; ++static inline void ar7240sw_init(struct ar7240sw *as, struct mii_bus *mii) ++{ ++ as->mii_bus = mii; ++} + -+ err_stop_hcd: -+ iounmap(hcd->regs); -+ err_release_region: -+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -+ err_put_hcd: -+ usb_put_hcd(hcd); -+ return ret; ++static inline u16 mk_phy_addr(u32 reg) ++{ ++ return 0x17 & ((reg >> 4) | 0x10); +} + -+void usb_hcd_ar71xx_remove(struct usb_hcd *hcd, struct platform_device *pdev) ++static inline u16 mk_phy_reg(u32 reg) +{ -+ usb_remove_hcd(hcd); -+ iounmap(hcd->regs); -+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -+ usb_put_hcd(hcd); ++ return (reg << 1) & 0x1e; +} + -+static int __devinit ohci_ar71xx_start(struct usb_hcd *hcd) ++static inline u16 mk_high_addr(u32 reg) +{ -+ struct ohci_hcd *ohci = hcd_to_ohci(hcd); -+ int ret; ++ return (reg >> 7) & 0x1ff; ++} + -+ ret = ohci_init(ohci); -+ if (ret < 0) -+ return ret; ++static u32 __ar7240sw_reg_read(struct mii_bus *mii, u32 reg) ++{ ++ unsigned long flags; ++ u16 phy_addr; ++ u16 phy_reg; ++ u32 hi, lo; + -+ ret = ohci_run(ohci); -+ if (ret < 0) -+ goto err; ++ reg = (reg & 0xfffffffc) >> 2; ++ phy_addr = mk_phy_addr(reg); ++ phy_reg = mk_phy_reg(reg); + -+ return 0; ++ local_irq_save(flags); ++ ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); ++ lo = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg); ++ hi = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg + 1); ++ local_irq_restore(flags); + -+ err: -+ ohci_stop(hcd); -+ return ret; ++ return (hi << 16) | lo; +} + -+static const struct hc_driver ohci_ar71xx_hc_driver = { -+ .description = hcd_name, -+ .product_desc = "Atheros AR71xx built-in OHCI controller", -+ .hcd_priv_size = sizeof(struct ohci_hcd), ++static void __ar7240sw_reg_write(struct mii_bus *mii, u32 reg, u32 val) ++{ ++ unsigned long flags; ++ u16 phy_addr; ++ u16 phy_reg; + -+ .irq = ohci_irq, -+ .flags = HCD_USB11 | HCD_MEMORY, ++ reg = (reg & 0xfffffffc) >> 2; ++ phy_addr = mk_phy_addr(reg); ++ phy_reg = mk_phy_reg(reg); + -+ .start = ohci_ar71xx_start, -+ .stop = ohci_stop, -+ .shutdown = ohci_shutdown, ++ local_irq_save(flags); ++ ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); ++ ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg + 1, (val >> 16)); ++ ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg, (val & 0xffff)); ++ local_irq_restore(flags); ++} + -+ .urb_enqueue = ohci_urb_enqueue, -+ .urb_dequeue = ohci_urb_dequeue, -+ .endpoint_disable = ohci_endpoint_disable, ++static u32 ar7240sw_reg_read(struct mii_bus *mii, u32 reg_addr) ++{ ++ u32 ret; + -+ /* -+ * scheduling support -+ */ -+ .get_frame_number = ohci_get_frame, ++ mutex_lock(®_mutex); ++ ret = __ar7240sw_reg_read(mii, reg_addr); ++ mutex_unlock(®_mutex); + -+ /* -+ * root hub support -+ */ -+ .hub_status_data = ohci_hub_status_data, -+ .hub_control = ohci_hub_control, -+ .start_port_reset = ohci_start_port_reset, -+}; ++ return ret; ++} + -+static int ohci_hcd_ar71xx_drv_probe(struct platform_device *pdev) ++static void ar7240sw_reg_write(struct mii_bus *mii, u32 reg_addr, u32 reg_val) +{ -+ if (usb_disabled()) -+ return -ENODEV; -+ -+ return usb_hcd_ar71xx_probe(&ohci_ar71xx_hc_driver, pdev); ++ mutex_lock(®_mutex); ++ __ar7240sw_reg_write(mii, reg_addr, reg_val); ++ mutex_unlock(®_mutex); +} + -+static int ohci_hcd_ar71xx_drv_remove(struct platform_device *pdev) ++static u32 ar7240sw_reg_rmw(struct mii_bus *mii, u32 reg, u32 mask, u32 val) +{ -+ struct usb_hcd *hcd = platform_get_drvdata(pdev); ++ u32 t; + -+ usb_hcd_ar71xx_remove(hcd, pdev); -+ return 0; ++ mutex_lock(®_mutex); ++ t = __ar7240sw_reg_read(mii, reg); ++ t &= ~mask; ++ t |= val; ++ __ar7240sw_reg_write(mii, reg, t); ++ mutex_unlock(®_mutex); ++ ++ return t; +} + -+MODULE_ALIAS("platform:ar71xx-ohci"); ++static void ar7240sw_reg_set(struct mii_bus *mii, u32 reg, u32 val) ++{ ++ u32 t; + -+static struct platform_driver ohci_hcd_ar71xx_driver = { -+ .probe = ohci_hcd_ar71xx_drv_probe, -+ .remove = ohci_hcd_ar71xx_drv_remove, -+ .shutdown = usb_hcd_platform_shutdown, -+ .driver = { -+ .name = "ar71xx-ohci", -+ .owner = THIS_MODULE, -+ }, -+}; -diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-hcd.c linux-2.6.39/drivers/usb/host/ohci-hcd.c ---- linux-2.6.39.orig/drivers/usb/host/ohci-hcd.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/usb/host/ohci-hcd.c 2011-05-27 14:36:51.000000000 +0200 -@@ -1105,6 +1105,11 @@ - #define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver - #endif - -+#ifdef CONFIG_USB_OHCI_AR71XX -+#include "ohci-ar71xx.c" -+#define PLATFORM_DRIVER ohci_hcd_ar71xx_driver -+#endif ++ mutex_lock(®_mutex); ++ t = __ar7240sw_reg_read(mii, reg); ++ t |= val; ++ __ar7240sw_reg_write(mii, reg, t); ++ mutex_unlock(®_mutex); ++} + - #if !defined(PCI_DRIVER) && \ - !defined(PLATFORM_DRIVER) && \ - !defined(OMAP1_PLATFORM_DRIVER) && \ -diff -Nur linux-2.6.39.orig/drivers/watchdog/Kconfig linux-2.6.39/drivers/watchdog/Kconfig ---- linux-2.6.39.orig/drivers/watchdog/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/watchdog/Kconfig 2011-05-27 14:36:51.000000000 +0200 -@@ -990,6 +990,13 @@ - To compile this driver as a loadable module, choose M here. - The module will be called bcm63xx_wdt. - -+config AR71XX_WDT -+ tristate "Atheros AR71xx Watchdog Timer" -+ depends on ATHEROS_AR71XX -+ help -+ Hardware driver for the built-in watchdog timer on the Atheros -+ AR71xx SoCs. ++static int __ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, ++ unsigned timeout) ++{ ++ int i; + - # PARISC Architecture - - # POWERPC Architecture -diff -Nur linux-2.6.39.orig/drivers/watchdog/Makefile linux-2.6.39/drivers/watchdog/Makefile ---- linux-2.6.39.orig/drivers/watchdog/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/watchdog/Makefile 2011-05-27 14:36:51.000000000 +0200 -@@ -121,6 +121,7 @@ - obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o - obj-$(CONFIG_AR7_WDT) += ar7_wdt.o - obj-$(CONFIG_TXX9_WDT) += txx9wdt.o -+obj-$(CONFIG_AR71XX_WDT) += ar71xx_wdt.o - obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o - octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o - -diff -Nur linux-2.6.39.orig/drivers/watchdog/ar71xx_wdt.c linux-2.6.39/drivers/watchdog/ar71xx_wdt.c ---- linux-2.6.39.orig/drivers/watchdog/ar71xx_wdt.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/watchdog/ar71xx_wdt.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,270 @@ -+/* -+ * Driver for the Atheros AR71xx SoC's built-in hardware watchdog timer. -+ * -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This driver was based on: drivers/watchdog/ixp4xx_wdt.c -+ * Author: Deepak Saxena -+ * Copyright 2004 (c) MontaVista, Software, Inc. -+ * -+ * which again was based on sa1100 driver, -+ * Copyright (C) 2000 Oleg Drokin -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ ++ for (i = 0; i < timeout; i++) { ++ u32 t; + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ t = __ar7240sw_reg_read(mii, reg); ++ if ((t & mask) == val) ++ return 0; + -+#include ++ msleep(1); ++ } + -+#define DRV_NAME "ar71xx-wdt" -+#define DRV_DESC "Atheros AR71xx hardware watchdog driver" -+#define DRV_VERSION "0.1.0" ++ return -ETIMEDOUT; ++} + -+#define WDT_TIMEOUT 15 /* seconds */ ++static int ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, ++ unsigned timeout) ++{ ++ int ret; + -+static int nowayout = WATCHDOG_NOWAYOUT; ++ mutex_lock(®_mutex); ++ ret = __ar7240sw_reg_wait(mii, reg, mask, val, timeout); ++ mutex_unlock(®_mutex); ++ return ret; ++} + -+#ifdef CONFIG_WATCHDOG_NOWAYOUT -+module_param(nowayout, int, 0); -+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " -+ "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -+#endif ++u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, ++ unsigned reg_addr) ++{ ++ u32 t, val = 0xffff; ++ int err; + -+static unsigned long wdt_flags; ++ if (phy_addr >= AR7240_NUM_PHYS) ++ return 0xffff; + -+#define WDT_FLAGS_BUSY 0 -+#define WDT_FLAGS_EXPECT_CLOSE 1 ++ mutex_lock(®_mutex); ++ t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | ++ (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | ++ AR7240_MDIO_CTRL_MASTER_EN | ++ AR7240_MDIO_CTRL_BUSY | ++ AR7240_MDIO_CTRL_CMD_READ; + -+static int wdt_timeout = WDT_TIMEOUT; -+static int boot_status; -+static int max_timeout; ++ __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); ++ err = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, ++ AR7240_MDIO_CTRL_BUSY, 0, 5); ++ if (!err) ++ val = __ar7240sw_reg_read(mii, AR7240_REG_MDIO_CTRL); ++ mutex_unlock(®_mutex); + -+static void inline ar71xx_wdt_keepalive(void) -+{ -+ ar71xx_reset_wr(AR71XX_RESET_REG_WDOG, ar71xx_ahb_freq * wdt_timeout); ++ return val & AR7240_MDIO_CTRL_DATA_M; +} + -+static void inline ar71xx_wdt_enable(void) ++int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, ++ unsigned reg_addr, u16 reg_val) +{ -+ printk(KERN_DEBUG DRV_NAME ": enabling watchdog timer\n"); -+ ar71xx_wdt_keepalive(); -+ ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR); -+} ++ u32 t; ++ int ret; + -+static void inline ar71xx_wdt_disable(void) -+{ -+ printk(KERN_DEBUG DRV_NAME ": disabling watchdog timer\n"); -+ ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE); -+} -+ -+static int ar71xx_wdt_set_timeout(int val) -+{ -+ if (val < 1 || val > max_timeout) ++ if (phy_addr >= AR7240_NUM_PHYS) + return -EINVAL; + -+ wdt_timeout = val; -+ ar71xx_wdt_keepalive(); ++ mutex_lock(®_mutex); ++ t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | ++ (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | ++ AR7240_MDIO_CTRL_MASTER_EN | ++ AR7240_MDIO_CTRL_BUSY | ++ AR7240_MDIO_CTRL_CMD_WRITE | ++ reg_val; + -+ printk(KERN_DEBUG DRV_NAME ": timeout=%d secs\n", wdt_timeout); ++ __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); ++ ret = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, ++ AR7240_MDIO_CTRL_BUSY, 0, 5); ++ mutex_unlock(®_mutex); + -+ return 0; ++ return ret; +} + -+static int ar71xx_wdt_open(struct inode *inode, struct file *file) ++static int ar7240sw_capture_stats(struct ar7240sw *as) +{ -+ if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags)) -+ return -EBUSY; -+ -+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); ++ struct mii_bus *mii = as->mii_bus; ++ int ret; + -+ ar71xx_wdt_enable(); ++ /* Capture the hardware statistics for all ports */ ++ ar7240sw_reg_write(mii, AR7240_REG_MIB_FUNCTION0, ++ (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S)); + -+ return nonseekable_open(inode, file); ++ /* Wait for the capturing to complete. */ ++ ret = ar7240sw_reg_wait(mii, AR7240_REG_MIB_FUNCTION0, ++ AR7240_MIB_BUSY, 0, 10); ++ return ret; +} + -+static int ar71xx_wdt_release(struct inode *inode, struct file *file) ++static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port) +{ -+ if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags)) { -+ ar71xx_wdt_disable(); -+ } else { -+ printk(KERN_CRIT DRV_NAME ": device closed unexpectedly, " -+ "watchdog timer will not stop!\n"); -+ } -+ -+ clear_bit(WDT_FLAGS_BUSY, &wdt_flags); -+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); -+ -+ return 0; ++ ar7240sw_reg_write(as->mii_bus, AR7240_REG_PORT_CTRL(port), ++ AR7240_PORT_CTRL_STATE_DISABLED); +} + -+static ssize_t ar71xx_wdt_write(struct file *file, const char *data, -+ size_t len, loff_t *ppos) ++static void ar7240sw_setup(struct ar7240sw *as) +{ -+ if (len) { -+ if (!nowayout) { -+ size_t i; ++ struct mii_bus *mii = as->mii_bus; + -+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); ++ /* Enable CPU port, and disable mirror port */ ++ ar7240sw_reg_write(mii, AR7240_REG_CPU_PORT, ++ AR7240_CPU_PORT_EN | ++ (15 << AR7240_MIRROR_PORT_S)); + -+ for (i = 0; i != len; i++) { -+ char c; ++ /* Setup TAG priority mapping */ ++ ar7240sw_reg_write(mii, AR7240_REG_TAG_PRIORITY, 0xfa50); + -+ if (get_user(c, data + i)) -+ return -EFAULT; ++ /* Enable ARP frame acknowledge, aging, MAC replacing */ ++ ar7240sw_reg_write(mii, AR7240_REG_AT_CTRL, ++ 0x2b /* 5 min age time */ | ++ AR7240_AT_CTRL_AGE_EN | ++ AR7240_AT_CTRL_ARP_EN | ++ AR7240_AT_CTRL_LEARN_CHANGE); + -+ if (c == 'V') -+ set_bit(WDT_FLAGS_EXPECT_CLOSE, -+ &wdt_flags); -+ } -+ } ++ /* Enable Broadcast frames transmitted to the CPU */ ++ ar7240sw_reg_set(mii, AR7240_REG_FLOOD_MASK, ++ AR7240_FLOOD_MASK_BROAD_TO_CPU); + -+ ar71xx_wdt_keepalive(); -+ } ++ /* setup MTU */ ++ ar7240sw_reg_rmw(mii, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M, ++ 1536); + -+ return len; ++ /* setup Service TAG */ ++ ar7240sw_reg_rmw(mii, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M, 0); +} + -+static struct watchdog_info ar71xx_wdt_info = { -+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | -+ WDIOF_MAGICCLOSE | WDIOF_CARDRESET, -+ .firmware_version = 0, -+ .identity = "AR71XX watchdog", -+}; -+ -+static int ar71xx_wdt_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) ++static int ar7240sw_reset(struct ar7240sw *as) +{ -+ int t; ++ struct mii_bus *mii = as->mii_bus; + int ret; ++ int i; + -+ switch (cmd) { -+ case WDIOC_GETSUPPORT: -+ ret = copy_to_user((struct watchdog_info *)arg, -+ &ar71xx_wdt_info, -+ sizeof(&ar71xx_wdt_info)) ? -EFAULT : 0; -+ break; ++ /* Set all ports to disabled state. */ ++ for (i = 0; i < AR7240_NUM_PORTS; i++) ++ ar7240sw_disable_port(as, i); + -+ case WDIOC_GETSTATUS: -+ ret = put_user(0, (int *)arg) ? -EFAULT : 0; -+ break; ++ /* Wait for transmit queues to drain. */ ++ msleep(2); + -+ case WDIOC_GETBOOTSTATUS: -+ ret = put_user(boot_status, (int *)arg) ? -EFAULT : 0; -+ break; ++ /* Reset the switch. */ ++ ar7240sw_reg_write(mii, AR7240_REG_MASK_CTRL, ++ AR7240_MASK_CTRL_SOFT_RESET); + -+ case WDIOC_KEEPALIVE: -+ ar71xx_wdt_keepalive(); -+ ret = 0; -+ break; ++ ret = ar7240sw_reg_wait(mii, AR7240_REG_MASK_CTRL, ++ AR7240_MASK_CTRL_SOFT_RESET, 0, 1000); + -+ case WDIOC_SETTIMEOUT: -+ ret = get_user(t, (int *)arg) ? -EFAULT : 0; -+ if (ret) -+ break; ++ ar7240sw_setup(as); ++ return ret; ++} + -+ ret = ar71xx_wdt_set_timeout(t); -+ if (ret) -+ break; ++static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port, u8 portmask) ++{ ++ struct mii_bus *mii = as->mii_bus; ++ u32 ctrl; ++ u32 dest_ports; ++ u32 vlan; + -+ /* fallthrough */ -+ case WDIOC_GETTIMEOUT: -+ ret = put_user(wdt_timeout, (int *)arg) ? -EFAULT : 0; -+ break; ++ ctrl = AR7240_PORT_CTRL_STATE_FORWARD | AR7240_PORT_CTRL_LEARN | ++ AR7240_PORT_CTRL_SINGLE_VLAN; + -+ default: -+ ret = -ENOTTY; -+ break; ++ if (port == AR7240_PORT_CPU) { ++ ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port), ++ AR7240_PORT_STATUS_SPEED_1000 | ++ AR7240_PORT_STATUS_TXFLOW | ++ AR7240_PORT_STATUS_RXFLOW | ++ AR7240_PORT_STATUS_TXMAC | ++ AR7240_PORT_STATUS_RXMAC | ++ AR7240_PORT_STATUS_DUPLEX); ++ } else { ++ ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port), ++ AR7240_PORT_STATUS_LINK_AUTO); + } + -+ return ret; -+} ++ /* Set the default VID for this port */ ++ if (as->vlan) { ++ vlan = as->vlan_id[as->pvid[port]]; ++ vlan |= AR7240_PORT_VLAN_MODE_SECURE << ++ AR7240_PORT_VLAN_MODE_S; ++ } else { ++ vlan = port; ++ vlan |= AR7240_PORT_VLAN_MODE_PORT_ONLY << ++ AR7240_PORT_VLAN_MODE_S; ++ } + -+static const struct file_operations ar71xx_wdt_fops = { -+ .owner = THIS_MODULE, -+ .write = ar71xx_wdt_write, -+ .ioctl = ar71xx_wdt_ioctl, -+ .open = ar71xx_wdt_open, -+ .release = ar71xx_wdt_release, -+}; ++ if (as->vlan && (as->vlan_tagged & BIT(port))) { ++ ctrl |= AR7240_PORT_CTRL_VLAN_MODE_ADD << ++ AR7240_PORT_CTRL_VLAN_MODE_S; ++ } else { ++ ctrl |= AR7240_PORT_CTRL_VLAN_MODE_STRIP << ++ AR7240_PORT_CTRL_VLAN_MODE_S; ++ } + -+static struct miscdevice ar71xx_wdt_miscdev = { -+ .minor = WATCHDOG_MINOR, -+ .name = "watchdog", -+ .fops = &ar71xx_wdt_fops, -+}; ++ if (!portmask) { ++ if (port == AR7240_PORT_CPU) ++ portmask = AR7240_PORT_MASK_BUT(AR7240_PORT_CPU); ++ else ++ portmask = AR7240_PORT_MASK(AR7240_PORT_CPU); ++ } + -+static int __devinit ar71xx_wdt_probe(struct platform_device *pdev) -+{ -+ int ret; ++ /* allow the port to talk to all other ports, but exclude its ++ * own ID to prevent frames from being reflected back to the ++ * port that they came from */ ++ dest_ports = AR7240_PORT_MASK_BUT(port); + -+ max_timeout = (0xfffffffful / ar71xx_ahb_freq); -+ wdt_timeout = (max_timeout < WDT_TIMEOUT) ? max_timeout : WDT_TIMEOUT; ++ /* set default VID and and destination ports for this VLAN */ ++ vlan |= (portmask << AR7240_PORT_VLAN_DEST_PORTS_S); + -+ boot_status = -+ (ar71xx_reset_rr(AR71XX_RESET_REG_WDOG_CTRL) & WDOG_CTRL_LAST_RESET) ? -+ WDIOF_CARDRESET : 0; ++ ar7240sw_reg_write(mii, AR7240_REG_PORT_CTRL(port), ctrl); ++ ar7240sw_reg_write(mii, AR7240_REG_PORT_VLAN(port), vlan); ++} + -+ ret = misc_register(&ar71xx_wdt_miscdev); -+ if (ret) -+ goto err_out; ++static int ar7240_set_addr(struct ar7240sw *as, u8 *addr) ++{ ++ struct mii_bus *mii = as->mii_bus; ++ u32 t; + -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); ++ t = (addr[4] << 8) | addr[5]; ++ ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR0, t); + -+ printk(KERN_DEBUG DRV_NAME ": timeout=%d secs (max=%d)\n", -+ wdt_timeout, max_timeout); ++ t = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3]; ++ ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR1, t); + + return 0; -+ -+err_out: -+ return ret; +} + -+static int __devexit ar71xx_wdt_remove(struct platform_device *pdev) ++static int ++ar7240_set_vid(struct switch_dev *dev, const struct switch_attr *attr, ++ struct switch_val *val) +{ -+ misc_deregister(&ar71xx_wdt_miscdev); ++ struct ar7240sw *as = sw_to_ar7240(dev); ++ as->vlan_id[val->port_vlan] = val->value.i; + return 0; +} + -+static struct platform_driver ar71xx_wdt_driver = { -+ .probe = ar71xx_wdt_probe, -+ .remove = __devexit_p(ar71xx_wdt_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init ar71xx_wdt_init(void) ++static int ++ar7240_get_vid(struct switch_dev *dev, const struct switch_attr *attr, ++ struct switch_val *val) +{ -+ return platform_driver_register(&ar71xx_wdt_driver); ++ struct ar7240sw *as = sw_to_ar7240(dev); ++ val->value.i = as->vlan_id[val->port_vlan]; ++ return 0; +} -+module_init(ar71xx_wdt_init); + -+static void __exit ar71xx_wdt_exit(void) ++static int ++ar7240_set_pvid(struct switch_dev *dev, int port, int vlan) +{ -+ platform_driver_unregister(&ar71xx_wdt_driver); -+} -+module_exit(ar71xx_wdt_exit); ++ struct ar7240sw *as = sw_to_ar7240(dev); + -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos -- * Copyright (c) 2009 Imre Kaloz -+ * ath9k platform data defines - * -- * Permission to use, copy, modify, and/or distribute this software for any -- * purpose with or without fee is hereby granted, provided that the above -- * copyright notice and this permission notice appear in all copies. -+ * Copyright (C) 2008 Gabor Juhos - * -- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. - */ - - #ifndef _LINUX_ATH9K_PLATFORM_H -@@ -23,6 +15,9 @@ - - struct ath9k_platform_data { - u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS]; -+ u8 *macaddr; ++ /* make sure no invalid PVIDs get set */ + -+ unsigned long quirk_wndr3700:1; - }; - - #endif /* _LINUX_ATH9K_PLATFORM_H */ -diff -Nur linux-2.6.39.orig/include/linux/gpio_buttons.h linux-2.6.39/include/linux/gpio_buttons.h ---- linux-2.6.39.orig/include/linux/gpio_buttons.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/include/linux/gpio_buttons.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,33 @@ -+/* -+ * Definitions for the GPIO buttons interface driver -+ * -+ * Copyright (C) 2007-2010 Gabor Juhos -+ * -+ * This file was based on: /include/linux/gpio_keys.h -+ * The original gpio_keys.h seems not to have a license. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ ++ if (vlan >= dev->vlans) ++ return -EINVAL; + -+#ifndef _GPIO_BUTTONS_H_ -+#define _GPIO_BUTTONS_H_ ++ as->pvid[port] = vlan; ++ return 0; ++} + -+struct gpio_button { -+ int gpio; /* GPIO line number */ -+ int active_low; -+ char *desc; /* button description */ -+ int type; /* input event type (EV_KEY, EV_SW) */ -+ int code; /* input event code (KEY_*, SW_*) */ -+ int threshold; /* count threshold */ -+}; ++static int ++ar7240_get_pvid(struct switch_dev *dev, int port, int *vlan) ++{ ++ struct ar7240sw *as = sw_to_ar7240(dev); ++ *vlan = as->pvid[port]; ++ return 0; ++} + -+struct gpio_buttons_platform_data { -+ struct gpio_button *buttons; -+ int nbuttons; /* number of buttons */ -+ int poll_interval; /* polling interval */ -+}; ++static int ++ar7240_get_ports(struct switch_dev *dev, struct switch_val *val) ++{ ++ struct ar7240sw *as = sw_to_ar7240(dev); ++ u8 ports = as->vlan_table[val->port_vlan]; ++ int i; + -+#endif /* _GPIO_BUTTONS_H_ */ -diff -Nur linux-2.6.39.orig/include/linux/gpio_dev.h linux-2.6.39/include/linux/gpio_dev.h ---- linux-2.6.39.orig/include/linux/gpio_dev.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/include/linux/gpio_dev.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,11 @@ -+#ifndef _GPIODEV_H__ -+#define _GPIODEV_H__ ++ val->len = 0; ++ for (i = 0; i < AR7240_NUM_PORTS; i++) { ++ struct switch_port *p; + -+#define IOC_GPIODEV_MAGIC 'B' -+#define GPIO_GET _IO(IOC_GPIODEV_MAGIC, 10) -+#define GPIO_SET _IO(IOC_GPIODEV_MAGIC, 11) -+#define GPIO_CLEAR _IO(IOC_GPIODEV_MAGIC, 12) -+#define GPIO_DIR_IN _IO(IOC_GPIODEV_MAGIC, 13) -+#define GPIO_DIR_OUT _IO(IOC_GPIODEV_MAGIC, 14) ++ if (!(ports & (1 << i))) ++ continue; + -+#endif -diff -Nur linux-2.6.39.orig/include/linux/netdevice.h linux-2.6.39/include/linux/netdevice.h ---- linux-2.6.39.orig/include/linux/netdevice.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/include/linux/netdevice.h 2011-05-27 14:36:51.000000000 +0200 -@@ -1182,6 +1182,7 @@ - void *ax25_ptr; /* AX.25 specific data */ - struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data, - assign before registering */ -+ void *phy_ptr; /* PHY device specific data */ - - /* - * Cache lines mostly used on receive path (including eth_type_trans()) -diff -Nur linux-2.6.39.orig/include/linux/nxp_74hc153.h linux-2.6.39/include/linux/nxp_74hc153.h ---- linux-2.6.39.orig/include/linux/nxp_74hc153.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/include/linux/nxp_74hc153.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,24 @@ -+/* -+ * NXP 74HC153 - Dual 4-input multiplexer defines -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ ++ p = &val->value.ports[val->len++]; ++ p->id = i; ++ if (as->vlan_tagged & (1 << i)) ++ p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); ++ else ++ p->flags = 0; ++ } ++ return 0; ++} + -+#ifndef _NXP_74HC153_H -+#define _NXP_74HC153_H ++static int ++ar7240_set_ports(struct switch_dev *dev, struct switch_val *val) ++{ ++ struct ar7240sw *as = sw_to_ar7240(dev); ++ u8 *vt = &as->vlan_table[val->port_vlan]; ++ int i, j; ++ ++ *vt = 0; ++ for (i = 0; i < val->len; i++) { ++ struct switch_port *p = &val->value.ports[i]; ++ ++ if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) ++ as->vlan_tagged |= (1 << p->id); ++ else { ++ as->vlan_tagged &= ~(1 << p->id); ++ as->pvid[p->id] = val->port_vlan; ++ ++ /* make sure that an untagged port does not ++ * appear in other vlans */ ++ for (j = 0; j < AR7240_MAX_VLANS; j++) { ++ if (j == val->port_vlan) ++ continue; ++ as->vlan_table[j] &= ~(1 << p->id); ++ } ++ } + -+#define NXP_74HC153_DRIVER_NAME "nxp-74hc153" ++ *vt |= 1 << p->id; ++ } ++ return 0; ++} + -+struct nxp_74hc153_platform_data { -+ unsigned gpio_base; -+ unsigned gpio_pin_s0; -+ unsigned gpio_pin_s1; -+ unsigned gpio_pin_1y; -+ unsigned gpio_pin_2y; -+}; ++static int ++ar7240_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct ar7240sw *as = sw_to_ar7240(dev); ++ as->vlan = !!val->value.i; ++ return 0; ++} + -+#endif /* _NXP_74HC153_H */ -diff -Nur linux-2.6.39.orig/include/linux/phy.h linux-2.6.39/include/linux/phy.h ---- linux-2.6.39.orig/include/linux/phy.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/include/linux/phy.h 2011-05-27 14:36:51.000000000 +0200 -@@ -332,6 +332,20 @@ - void (*adjust_link)(struct net_device *dev); - - void (*adjust_state)(struct net_device *dev); ++static int ++ar7240_get_vlan(struct switch_dev *dev, const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct ar7240sw *as = sw_to_ar7240(dev); ++ val->value.i = as->vlan; ++ return 0; ++} + -+ /* -+ * By default these point to the original functions -+ * with the same name. adding them to the phy_device -+ * allows the phy driver to override them for packet -+ * mangling if the ethernet driver supports it -+ * This is required to support some really horrible -+ * switches such as the Marvell 88E6060 -+ */ -+ int (*netif_receive_skb)(struct sk_buff *skb); -+ int (*netif_rx)(struct sk_buff *skb); + -+ /* alignment offset for packets */ -+ int pkt_align; - }; - #define to_phy_device(d) container_of(d, struct phy_device, dev) - -@@ -508,6 +522,7 @@ - void phy_stop_machine(struct phy_device *phydev); - int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd); - int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd); -+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr); - int phy_mii_ioctl(struct phy_device *phydev, - struct ifreq *ifr, int cmd); - int phy_start_interrupts(struct phy_device *phydev); -diff -Nur linux-2.6.39.orig/include/linux/spi/vsc7385.h linux-2.6.39/include/linux/spi/vsc7385.h ---- linux-2.6.39.orig/include/linux/spi/vsc7385.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/include/linux/spi/vsc7385.h 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,19 @@ -+/* -+ * Platform data definition for the Vitesse VSC7385 ethernet switch driver -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++static void ++ar7240_vtu_op(struct ar7240sw *as, u32 op, u32 val) ++{ ++ struct mii_bus *mii = as->mii_bus; + -+struct vsc7385_platform_data { -+ void (* reset)(void); -+ char *ucode_name; -+ struct { -+ u32 tx_ipg:5; -+ u32 bit2:1; -+ u32 clk_sel:3; -+ } mac_cfg; ++ if (ar7240sw_reg_wait(mii, AR7240_REG_VTU, AR7240_VTU_ACTIVE, 0, 5)) ++ return; ++ ++ if ((op & AR7240_VTU_OP) == AR7240_VTU_OP_LOAD) { ++ val &= AR7240_VTUDATA_MEMBER; ++ val |= AR7240_VTUDATA_VALID; ++ ar7240sw_reg_write(mii, AR7240_REG_VTU_DATA, val); ++ } ++ op |= AR7240_VTU_ACTIVE; ++ ar7240sw_reg_write(mii, AR7240_REG_VTU, op); ++} ++ ++static int ++ar7240_hw_apply(struct switch_dev *dev) ++{ ++ struct ar7240sw *as = sw_to_ar7240(dev); ++ u8 portmask[AR7240_NUM_PORTS]; ++ int i, j; ++ ++ /* flush all vlan translation unit entries */ ++ ar7240_vtu_op(as, AR7240_VTU_OP_FLUSH, 0); ++ ++ memset(portmask, 0, sizeof(portmask)); ++ if (as->vlan) { ++ /* calculate the port destination masks and load vlans ++ * into the vlan translation unit */ ++ for (j = 0; j < AR7240_MAX_VLANS; j++) { ++ u8 vp = as->vlan_table[j]; ++ ++ if (!vp) ++ continue; ++ ++ for (i = 0; i < AR7240_NUM_PORTS; i++) { ++ u8 mask = (1 << i); ++ if (vp & mask) ++ portmask[i] |= vp & ~mask; ++ } ++ ++ ar7240_vtu_op(as, ++ AR7240_VTU_OP_LOAD | ++ (as->vlan_id[j] << AR7240_VTU_VID_S), ++ as->vlan_table[j]); ++ } ++ } else { ++ /* vlan disabled: ++ * isolate all ports, but connect them to the cpu port */ ++ for (i = 0; i < AR7240_NUM_PORTS; i++) { ++ if (i == AR7240_PORT_CPU) ++ continue; ++ ++ portmask[i] = 1 << AR7240_PORT_CPU; ++ portmask[AR7240_PORT_CPU] |= (1 << i); ++ } ++ } ++ ++ /* update the port destination mask registers and tag settings */ ++ for (i = 0; i < AR7240_NUM_PORTS; i++) ++ ar7240sw_setup_port(as, i, portmask[i]); ++ ++ return 0; ++} ++ ++static int ++ar7240_reset_switch(struct switch_dev *dev) ++{ ++ struct ar7240sw *as = sw_to_ar7240(dev); ++ ar7240sw_reset(as); ++ return 0; ++} ++ ++static struct switch_attr ar7240_globals[] = { ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "enable_vlan", ++ .description = "Enable VLAN mode", ++ .set = ar7240_set_vlan, ++ .get = ar7240_get_vlan, ++ .max = 1 ++ }, +}; -diff -Nur linux-2.6.39.orig/net/dsa/ar7240.c linux-2.6.39/net/dsa/ar7240.c ---- linux-2.6.39.orig/net/dsa/ar7240.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/net/dsa/ar7240.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,736 @@ -+/* -+ * DSA driver for the built-in ethernet switch of the Atheros AR7240 SoC -+ * Copyright (c) 2010 Gabor Juhos -+ * -+ * This file was based on: -+ * net/dsa/mv88e6060.c - Driver for Marvell 88e6060 switch chips -+ * Copyright (c) 2008 Marvell Semiconductor -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ + -+#include -+#include -+#include -+#include -+#include -+#include ++static struct switch_attr ar7240_port[] = { ++}; + -+#include "dsa_priv.h" ++static struct switch_attr ar7240_vlan[] = { ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "vid", ++ .description = "VLAN ID", ++ .set = ar7240_set_vid, ++ .get = ar7240_get_vid, ++ .max = 4094, ++ }, ++}; + -+#define BITM(_count) (BIT(_count) - 1) ++static const struct switch_dev_ops ar7240_ops = { ++ .attr_global = { ++ .attr = ar7240_globals, ++ .n_attr = ARRAY_SIZE(ar7240_globals), ++ }, ++ .attr_port = { ++ .attr = ar7240_port, ++ .n_attr = ARRAY_SIZE(ar7240_port), ++ }, ++ .attr_vlan = { ++ .attr = ar7240_vlan, ++ .n_attr = ARRAY_SIZE(ar7240_vlan), ++ }, ++ .get_port_pvid = ar7240_get_pvid, ++ .set_port_pvid = ar7240_set_pvid, ++ .get_vlan_ports = ar7240_get_ports, ++ .set_vlan_ports = ar7240_set_ports, ++ .apply_config = ar7240_hw_apply, ++ .reset_switch = ar7240_reset_switch, ++}; + -+#define AR7240_REG_MASK_CTRL 0x00 -+#define AR7240_MASK_CTRL_REVISION_M BITM(8) -+#define AR7240_MASK_CTRL_VERSION_M BITM(8) -+#define AR7240_MASK_CTRL_VERSION_S 8 -+#define AR7240_MASK_CTRL_SOFT_RESET BIT(31) ++static struct ar7240sw *ar7240_probe(struct ag71xx *ag) ++{ ++ struct mii_bus *mii = ag->mii_bus; ++ struct ar7240sw *as; ++ struct switch_dev *swdev; ++ u32 ctrl; ++ u16 phy_id1; ++ u16 phy_id2; ++ u8 ver; ++ int i; + -+#define AR7240_REG_MAC_ADDR0 0x20 -+#define AR7240_REG_MAC_ADDR1 0x24 ++ as = kzalloc(sizeof(*as), GFP_KERNEL); ++ if (!as) ++ return NULL; + -+#define AR7240_REG_FLOOD_MASK 0x2c -+#define AR7240_FLOOD_MASK_BROAD_TO_CPU BIT(26) ++ ar7240sw_init(as, mii); + -+#define AR7240_REG_GLOBAL_CTRL 0x30 -+#define AR7240_GLOBAL_CTRL_MTU_M BITM(12) ++ ctrl = ar7240sw_reg_read(mii, AR7240_REG_MASK_CTRL); + -+#define AR7240_REG_AT_CTRL 0x5c -+#define AR7240_AT_CTRL_ARP_EN BIT(20) ++ ver = (ctrl >> AR7240_MASK_CTRL_VERSION_S) & AR7240_MASK_CTRL_VERSION_M; ++ if (ver != 1) { ++ pr_err("%s: unsupported chip, ctrl=%08x\n", ++ ag->dev->name, ctrl); ++ return NULL; ++ } + -+#define AR7240_REG_TAG_PRIORITY 0x70 ++ phy_id1 = ar7240sw_phy_read(mii, 0, MII_PHYSID1); ++ phy_id2 = ar7240sw_phy_read(mii, 0, MII_PHYSID2); ++ if (phy_id1 != AR7240_PHY_ID1 || phy_id2 != AR7240_PHY_ID2) { ++ pr_err("%s: unknown phy id '%04x:%04x'\n", ++ ag->dev->name, phy_id1, phy_id2); ++ return NULL; ++ } + -+#define AR7240_REG_SERVICE_TAG 0x74 -+#define AR7240_SERVICE_TAG_M BITM(16) ++ swdev = &as->swdev; ++ swdev->name = "AR7240 built-in switch"; ++ swdev->ports = AR7240_NUM_PORTS; ++ swdev->cpu_port = AR7240_PORT_CPU; ++ swdev->vlans = AR7240_MAX_VLANS; ++ swdev->ops = &ar7240_ops; + -+#define AR7240_REG_CPU_PORT 0x78 -+#define AR7240_MIRROR_PORT_S 4 -+#define AR7240_CPU_PORT_EN BIT(8) ++ if (register_switch(&as->swdev, ag->dev) < 0) { ++ kfree(as); ++ return NULL; ++ } + -+#define AR7240_REG_MIB_FUNCTION0 0x80 -+#define AR7240_MIB_TIMER_M BITM(16) -+#define AR7240_MIB_AT_HALF_EN BIT(16) -+#define AR7240_MIB_BUSY BIT(17) -+#define AR7240_MIB_FUNC_S 24 -+#define AR7240_MIB_FUNC_NO_OP 0x0 -+#define AR7240_MIB_FUNC_FLUSH 0x1 -+#define AR7240_MIB_FUNC_CAPTURE 0x3 ++ pr_info("%s: Found an AR7240 built-in switch\n", ag->dev->name); + -+#define AR7240_REG_MDIO_CTRL 0x98 -+#define AR7240_MDIO_CTRL_DATA_M BITM(16) -+#define AR7240_MDIO_CTRL_REG_ADDR_S 16 -+#define AR7240_MDIO_CTRL_PHY_ADDR_S 21 -+#define AR7240_MDIO_CTRL_CMD_WRITE 0 -+#define AR7240_MDIO_CTRL_CMD_READ BIT(27) -+#define AR7240_MDIO_CTRL_MASTER_EN BIT(30) -+#define AR7240_MDIO_CTRL_BUSY BIT(31) ++ /* initialize defaults */ ++ for (i = 0; i < AR7240_MAX_VLANS; i++) ++ as->vlan_id[i] = i; + -+#define AR7240_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100) ++ as->vlan_table[0] = AR7240_PORT_MASK_ALL; + -+#define AR7240_REG_PORT_STATUS(_port) (AR7240_REG_PORT_BASE((_port)) + 0x00) -+#define AR7240_PORT_STATUS_SPEED_M BITM(2) -+#define AR7240_PORT_STATUS_SPEED_10 0 -+#define AR7240_PORT_STATUS_SPEED_100 1 -+#define AR7240_PORT_STATUS_SPEED_1000 2 -+#define AR7240_PORT_STATUS_TXMAC BIT(2) -+#define AR7240_PORT_STATUS_RXMAC BIT(3) -+#define AR7240_PORT_STATUS_TXFLOW BIT(4) -+#define AR7240_PORT_STATUS_RXFLOW BIT(5) -+#define AR7240_PORT_STATUS_DUPLEX BIT(6) -+#define AR7240_PORT_STATUS_LINK_UP BIT(8) -+#define AR7240_PORT_STATUS_LINK_AUTO BIT(9) -+#define AR7240_PORT_STATUS_LINK_PAUSE BIT(10) ++ return as; ++} + -+#define AR7240_REG_PORT_CTRL(_port) (AR7240_REG_PORT_BASE((_port)) + 0x04) -+#define AR7240_PORT_CTRL_STATE_M BITM(3) -+#define AR7240_PORT_CTRL_STATE_DISABLED 0 -+#define AR7240_PORT_CTRL_STATE_BLOCK 1 -+#define AR7240_PORT_CTRL_STATE_LISTEN 2 -+#define AR7240_PORT_CTRL_STATE_LEARN 3 -+#define AR7240_PORT_CTRL_STATE_FORWARD 4 -+#define AR7240_PORT_CTRL_LEARN_LOCK BIT(7) -+#define AR7240_PORT_CTRL_VLAN_MODE_S 8 -+#define AR7240_PORT_CTRL_VLAN_MODE_KEEP 0 -+#define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1 -+#define AR7240_PORT_CTRL_VLAN_MODE_ADD 2 -+#define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3 -+#define AR7240_PORT_CTRL_IGMP_SNOOP BIT(10) -+#define AR7240_PORT_CTRL_HEADER BIT(11) -+#define AR7240_PORT_CTRL_MAC_LOOP BIT(12) -+#define AR7240_PORT_CTRL_SINGLE_VLAN BIT(13) -+#define AR7240_PORT_CTRL_LEARN BIT(14) -+#define AR7240_PORT_CTRL_DOUBLE_TAG BIT(15) -+#define AR7240_PORT_CTRL_MIRROR_TX BIT(16) -+#define AR7240_PORT_CTRL_MIRROR_RX BIT(17) ++static void link_function(struct work_struct *work) { ++ struct ag71xx *ag = container_of(work, struct ag71xx, link_work.work); ++ unsigned long flags; ++ int i; ++ int status = 0; + -+#define AR7240_REG_PORT_VLAN(_port) (AR7240_REG_PORT_BASE((_port)) + 0x08) ++ for (i = 0; i < 4; i++) { ++ int link = ar7240sw_phy_read(ag->mii_bus, i, MII_BMSR); ++ if(link & BMSR_LSTATUS) { ++ status = 1; ++ break; ++ } ++ } + -+#define AR7240_PORT_VLAN_DEFAULT_ID_S 0 -+#define AR7240_PORT_VLAN_DEST_PORTS_S 16 ++ spin_lock_irqsave(&ag->lock, flags); ++ if(status != ag->link) { ++ ag->link = status; ++ ag71xx_link_adjust(ag); ++ } ++ spin_unlock_irqrestore(&ag->lock, flags); + -+#define AR7240_REG_STATS_BASE(_port) (0x20000 + (_port) * 0x100) ++ schedule_delayed_work(&ag->link_work, HZ / 2); ++} + -+#define AR7240_STATS_RXBROAD 0x00 -+#define AR7240_STATS_RXPAUSE 0x04 -+#define AR7240_STATS_RXMULTI 0x08 -+#define AR7240_STATS_RXFCSERR 0x0c -+#define AR7240_STATS_RXALIGNERR 0x10 -+#define AR7240_STATS_RXRUNT 0x14 -+#define AR7240_STATS_RXFRAGMENT 0x18 -+#define AR7240_STATS_RX64BYTE 0x1c -+#define AR7240_STATS_RX128BYTE 0x20 -+#define AR7240_STATS_RX256BYTE 0x24 -+#define AR7240_STATS_RX512BYTE 0x28 -+#define AR7240_STATS_RX1024BYTE 0x2c -+#define AR7240_STATS_RX1518BYTE 0x30 -+#define AR7240_STATS_RXMAXBYTE 0x34 -+#define AR7240_STATS_RXTOOLONG 0x38 -+#define AR7240_STATS_RXGOODBYTE 0x3c -+#define AR7240_STATS_RXBADBYTE 0x44 -+#define AR7240_STATS_RXOVERFLOW 0x4c -+#define AR7240_STATS_FILTERED 0x50 -+#define AR7240_STATS_TXBROAD 0x54 -+#define AR7240_STATS_TXPAUSE 0x58 -+#define AR7240_STATS_TXMULTI 0x5c -+#define AR7240_STATS_TXUNDERRUN 0x60 -+#define AR7240_STATS_TX64BYTE 0x64 -+#define AR7240_STATS_TX128BYTE 0x68 -+#define AR7240_STATS_TX256BYTE 0x6c -+#define AR7240_STATS_TX512BYTE 0x70 -+#define AR7240_STATS_TX1024BYTE 0x74 -+#define AR7240_STATS_TX1518BYTE 0x78 -+#define AR7240_STATS_TXMAXBYTE 0x7c -+#define AR7240_STATS_TXOVERSIZE 0x80 -+#define AR7240_STATS_TXBYTE 0x84 -+#define AR7240_STATS_TXCOLLISION 0x8c -+#define AR7240_STATS_TXABORTCOL 0x90 -+#define AR7240_STATS_TXMULTICOL 0x94 -+#define AR7240_STATS_TXSINGLECOL 0x98 -+#define AR7240_STATS_TXEXCDEFER 0x9c -+#define AR7240_STATS_TXDEFER 0xa0 -+#define AR7240_STATS_TXLATECOL 0xa4 ++void ag71xx_ar7240_start(struct ag71xx *ag) ++{ ++ struct ar7240sw *as = ag->phy_priv; ++ ++ ar7240sw_reset(as); ++ ++ ag->speed = SPEED_1000; ++ ag->duplex = 1; ++ ++ ar7240_set_addr(as, ag->dev->dev_addr); ++ ar7240_hw_apply(&as->swdev); ++ ++ schedule_delayed_work(&ag->link_work, HZ / 10); ++} ++ ++void ag71xx_ar7240_stop(struct ag71xx *ag) ++{ ++ cancel_delayed_work_sync(&ag->link_work); ++} ++ ++int __devinit ag71xx_ar7240_init(struct ag71xx *ag) ++{ ++ struct ar7240sw *as; ++ ++ as = ar7240_probe(ag); ++ if (!as) ++ return -ENODEV; ++ ++ ag->phy_priv = as; ++ ar7240sw_reset(as); ++ ++ INIT_DELAYED_WORK(&ag->link_work, link_function); ++ ++ return 0; ++} ++ ++void ag71xx_ar7240_cleanup(struct ag71xx *ag) ++{ ++ struct ar7240sw *as = ag->phy_priv; ++ ++ if (!as) ++ return; ++ ++ unregister_switch(&as->swdev); ++ kfree(as); ++ ag->phy_priv = NULL; ++} +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar8216.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ar8216.c +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar8216.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ar8216.c 2011-04-27 12:19:22.257663952 +0200 +@@ -0,0 +1,44 @@ ++/* ++ * Atheros AR71xx built-in ethernet mac driver ++ * Special support for the Atheros ar8216 switch chip ++ * ++ * Copyright (C) 2009-2010 Gabor Juhos ++ * ++ * Based on Atheros' AG7100 driver ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include "ag71xx.h" ++ ++#define AR8216_PACKET_TYPE_MASK 0xf ++#define AR8216_PACKET_TYPE_NORMAL 0 ++ ++#define AR8216_HEADER_LEN 2 ++ ++void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb) ++{ ++ skb_push(skb, AR8216_HEADER_LEN); ++ skb->data[0] = 0x10; ++ skb->data[1] = 0x80; ++} ++ ++int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, ++ int pktlen) ++{ ++ u8 type; ++ ++ type = skb->data[1] & AR8216_PACKET_TYPE_MASK; ++ switch (type) { ++ case AR8216_PACKET_TYPE_NORMAL: ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ skb_pull(skb, AR8216_HEADER_LEN); ++ return 0; ++} +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_debugfs.c linux-2.6.39/drivers/net/ag71xx/ag71xx_debugfs.c +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_debugfs.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_debugfs.c 2011-08-06 09:32:37.298018216 +0200 +@@ -0,0 +1,280 @@ ++/* ++ * Atheros AR71xx built-in ethernet mac driver ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Based on Atheros' AG7100 driver ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++ ++#include "ag71xx.h" ++ ++static struct dentry *ag71xx_debugfs_root; ++ ++static int ag71xx_debugfs_generic_open(struct inode *inode, struct file *file) ++{ ++ file->private_data = inode->i_private; ++ return 0; ++} ++ ++void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status) ++{ ++ if (status) ++ ag->debug.int_stats.total++; ++ if (status & AG71XX_INT_TX_PS) ++ ag->debug.int_stats.tx_ps++; ++ if (status & AG71XX_INT_TX_UR) ++ ag->debug.int_stats.tx_ur++; ++ if (status & AG71XX_INT_TX_BE) ++ ag->debug.int_stats.tx_be++; ++ if (status & AG71XX_INT_RX_PR) ++ ag->debug.int_stats.rx_pr++; ++ if (status & AG71XX_INT_RX_OF) ++ ag->debug.int_stats.rx_of++; ++ if (status & AG71XX_INT_RX_BE) ++ ag->debug.int_stats.rx_be++; ++} ++ ++static ssize_t read_file_int_stats(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++#define PR_INT_STAT(_label, _field) \ ++ len += snprintf(buf + len, sizeof(buf) - len, \ ++ "%20s: %10lu\n", _label, ag->debug.int_stats._field); ++ ++ struct ag71xx *ag = file->private_data; ++ char buf[256]; ++ unsigned int len = 0; ++ ++ PR_INT_STAT("TX Packet Sent", tx_ps); ++ PR_INT_STAT("TX Underrun", tx_ur); ++ PR_INT_STAT("TX Bus Error", tx_be); ++ PR_INT_STAT("RX Packet Received", rx_pr); ++ PR_INT_STAT("RX Overflow", rx_of); ++ PR_INT_STAT("RX Bus Error", rx_be); ++ len += snprintf(buf + len, sizeof(buf) - len, "\n"); ++ PR_INT_STAT("Total", total); ++ ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++#undef PR_INT_STAT ++} ++ ++static const struct file_operations ag71xx_fops_int_stats = { ++ .open = ag71xx_debugfs_generic_open, ++ .read = read_file_int_stats, ++ .owner = THIS_MODULE ++}; ++ ++void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx) ++{ ++ struct ag71xx_napi_stats *stats = &ag->debug.napi_stats; ++ ++ if (rx) { ++ stats->rx_count++; ++ stats->rx_packets += rx; ++ if (rx <= AG71XX_NAPI_WEIGHT) ++ stats->rx[rx]++; ++ if (rx > stats->rx_packets_max) ++ stats->rx_packets_max = rx; ++ } ++ ++ if (tx) { ++ stats->tx_count++; ++ stats->tx_packets += tx; ++ if (tx <= AG71XX_NAPI_WEIGHT) ++ stats->tx[tx]++; ++ if (tx > stats->tx_packets_max) ++ stats->tx_packets_max = tx; ++ } ++} ++ ++static ssize_t read_file_napi_stats(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ag71xx *ag = file->private_data; ++ struct ag71xx_napi_stats *stats = &ag->debug.napi_stats; ++ char *buf; ++ unsigned int buflen; ++ unsigned int len = 0; ++ unsigned long rx_avg = 0; ++ unsigned long tx_avg = 0; ++ int ret; ++ int i; ++ ++ buflen = 2048; ++ buf = kmalloc(buflen, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ if (stats->rx_count) ++ rx_avg = stats->rx_packets / stats->rx_count; ++ ++ if (stats->tx_count) ++ tx_avg = stats->tx_packets / stats->tx_count; ++ ++ len += snprintf(buf + len, buflen - len, "%3s %10s %10s\n", ++ "len", "rx", "tx"); ++ ++ for (i = 1; i <= AG71XX_NAPI_WEIGHT; i++) ++ len += snprintf(buf + len, buflen - len, ++ "%3d: %10lu %10lu\n", ++ i, stats->rx[i], stats->tx[i]); ++ ++ len += snprintf(buf + len, buflen - len, "\n"); ++ ++ len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", ++ "sum", stats->rx_count, stats->tx_count); ++ len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", ++ "avg", rx_avg, tx_avg); ++ len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", ++ "max", stats->rx_packets_max, stats->tx_packets_max); ++ len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", ++ "pkt", stats->rx_packets, stats->tx_packets); ++ ++ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); ++ kfree(buf); ++ ++ return ret; ++} ++ ++static const struct file_operations ag71xx_fops_napi_stats = { ++ .open = ag71xx_debugfs_generic_open, ++ .read = read_file_napi_stats, ++ .owner = THIS_MODULE ++}; ++ ++#define DESC_PRINT_LEN 64 ++ ++static ssize_t read_file_ring(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos, ++ struct ag71xx *ag, ++ struct ag71xx_ring *ring, ++ unsigned desc_reg) ++{ ++ char *buf; ++ unsigned int buflen; ++ unsigned int len = 0; ++ unsigned long flags; ++ ssize_t ret; ++ int curr; ++ int dirty; ++ u32 desc_hw; ++ int i; ++ ++ buflen = (ring->size * DESC_PRINT_LEN); ++ buf = kmalloc(buflen, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ len += snprintf(buf + len, buflen - len, ++ "Idx ... %-8s %-8s %-8s %-8s . %-10s\n", ++ "desc", "next", "data", "ctrl", "timestamp"); ++ ++ spin_lock_irqsave(&ag->lock, flags); ++ ++ curr = (ring->curr % ring->size); ++ dirty = (ring->dirty % ring->size); ++ desc_hw = ag71xx_rr(ag, desc_reg); ++ for (i = 0; i < ring->size; i++) { ++ struct ag71xx_buf *ab = &ring->buf[i]; ++ u32 desc_dma = ((u32) ring->descs_dma) + i * ring->desc_size; ++ ++ len += snprintf(buf + len, buflen - len, ++ "%3d %c%c%c %08x %08x %08x %08x %c %10lu\n", ++ i, ++ (i == curr) ? 'C' : ' ', ++ (i == dirty) ? 'D' : ' ', ++ (desc_hw == desc_dma) ? 'H' : ' ', ++ desc_dma, ++ ab->desc->next, ++ ab->desc->data, ++ ab->desc->ctrl, ++ (ab->desc->ctrl & DESC_EMPTY) ? 'E' : '*', ++ ab->timestamp); ++ } ++ ++ spin_unlock_irqrestore(&ag->lock, flags); ++ ++ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); ++ kfree(buf); ++ ++ return ret; ++} ++ ++static ssize_t read_file_tx_ring(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ag71xx *ag = file->private_data; ++ ++ return read_file_ring(file, user_buf, count, ppos, ag, &ag->tx_ring, ++ AG71XX_REG_TX_DESC); ++} ++ ++static const struct file_operations ag71xx_fops_tx_ring = { ++ .open = ag71xx_debugfs_generic_open, ++ .read = read_file_tx_ring, ++ .owner = THIS_MODULE ++}; ++ ++static ssize_t read_file_rx_ring(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ag71xx *ag = file->private_data; ++ ++ return read_file_ring(file, user_buf, count, ppos, ag, &ag->rx_ring, ++ AG71XX_REG_RX_DESC); ++} ++ ++static const struct file_operations ag71xx_fops_rx_ring = { ++ .open = ag71xx_debugfs_generic_open, ++ .read = read_file_rx_ring, ++ .owner = THIS_MODULE ++}; ++ ++void ag71xx_debugfs_exit(struct ag71xx *ag) ++{ ++ debugfs_remove_recursive(ag->debug.debugfs_dir); ++} ++ ++int ag71xx_debugfs_init(struct ag71xx *ag) ++{ ++ ag->debug.debugfs_dir = debugfs_create_dir(ag->dev->name, ++ ag71xx_debugfs_root); ++ if (!ag->debug.debugfs_dir) ++ return -ENOMEM; ++ ++ debugfs_create_file("int_stats", S_IRUGO, ag->debug.debugfs_dir, ++ ag, &ag71xx_fops_int_stats); ++ debugfs_create_file("napi_stats", S_IRUGO, ag->debug.debugfs_dir, ++ ag, &ag71xx_fops_napi_stats); ++ debugfs_create_file("tx_ring", S_IRUGO, ag->debug.debugfs_dir, ++ ag, &ag71xx_fops_tx_ring); ++ debugfs_create_file("rx_ring", S_IRUGO, ag->debug.debugfs_dir, ++ ag, &ag71xx_fops_rx_ring); ++ ++ return 0; ++} ++ ++int ag71xx_debugfs_root_init(void) ++{ ++ if (ag71xx_debugfs_root) ++ return -EBUSY; ++ ++ ag71xx_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); ++ if (!ag71xx_debugfs_root) ++ return -ENOENT; ++ ++ return 0; ++} ++ ++void ag71xx_debugfs_root_exit(void) ++{ ++ debugfs_remove(ag71xx_debugfs_root); ++ ag71xx_debugfs_root = NULL; ++} +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ethtool.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ethtool.c +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ethtool.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ethtool.c 2011-08-06 09:32:37.308017908 +0200 +@@ -0,0 +1,124 @@ ++/* ++ * Atheros AR71xx built-in ethernet mac driver ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Based on Atheros' AG7100 driver ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include "ag71xx.h" ++ ++static int ag71xx_ethtool_get_settings(struct net_device *dev, ++ struct ethtool_cmd *cmd) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ struct phy_device *phydev = ag->phy_dev; ++ ++ if (!phydev) ++ return -ENODEV; ++ ++ return phy_ethtool_gset(phydev, cmd); ++} ++ ++static int ag71xx_ethtool_set_settings(struct net_device *dev, ++ struct ethtool_cmd *cmd) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ struct phy_device *phydev = ag->phy_dev; ++ ++ if (!phydev) ++ return -ENODEV; ++ ++ return phy_ethtool_sset(phydev, cmd); ++} ++ ++static void ag71xx_ethtool_get_drvinfo(struct net_device *dev, ++ struct ethtool_drvinfo *info) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ ++ strcpy(info->driver, ag->pdev->dev.driver->name); ++ strcpy(info->version, AG71XX_DRV_VERSION); ++ strcpy(info->bus_info, dev_name(&ag->pdev->dev)); ++} ++ ++static u32 ag71xx_ethtool_get_msglevel(struct net_device *dev) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ ++ return ag->msg_enable; ++} ++ ++static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ ++ ag->msg_enable = msg_level; ++} ++ ++static void ag71xx_ethtool_get_ringparam(struct net_device *dev, ++ struct ethtool_ringparam *er) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ ++ er->tx_max_pending = AG71XX_TX_RING_SIZE_MAX; ++ er->rx_max_pending = AG71XX_RX_RING_SIZE_MAX; ++ er->rx_mini_max_pending = 0; ++ er->rx_jumbo_max_pending = 0; ++ ++ er->tx_pending = ag->tx_ring.size; ++ er->rx_pending = ag->rx_ring.size; ++ er->rx_mini_pending = 0; ++ er->rx_jumbo_pending = 0; ++} ++ ++static int ag71xx_ethtool_set_ringparam(struct net_device *dev, ++ struct ethtool_ringparam *er) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ unsigned tx_size; ++ unsigned rx_size; ++ int err; ++ ++ if (er->rx_mini_pending != 0|| ++ er->rx_jumbo_pending != 0 || ++ er->rx_pending == 0 || ++ er->tx_pending == 0) ++ return -EINVAL; ++ ++ tx_size = er->tx_pending < AG71XX_TX_RING_SIZE_MAX ? ++ er->tx_pending : AG71XX_TX_RING_SIZE_MAX; ++ ++ rx_size = er->rx_pending < AG71XX_RX_RING_SIZE_MAX ? ++ er->rx_pending : AG71XX_RX_RING_SIZE_MAX; ++ ++ if (netif_running(dev)) { ++ err = dev->netdev_ops->ndo_stop(dev); ++ if (err) ++ return err; ++ } ++ ++ ag->tx_ring.size = tx_size; ++ ag->rx_ring.size = rx_size; ++ ++ if (netif_running(dev)) ++ err = dev->netdev_ops->ndo_open(dev); ++ ++ return err; ++} ++ ++struct ethtool_ops ag71xx_ethtool_ops = { ++ .set_settings = ag71xx_ethtool_set_settings, ++ .get_settings = ag71xx_ethtool_get_settings, ++ .get_drvinfo = ag71xx_ethtool_get_drvinfo, ++ .get_msglevel = ag71xx_ethtool_get_msglevel, ++ .set_msglevel = ag71xx_ethtool_set_msglevel, ++ .get_ringparam = ag71xx_ethtool_get_ringparam, ++ .set_ringparam = ag71xx_ethtool_set_ringparam, ++ .get_link = ethtool_op_get_link, ++}; +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h linux-2.6.39/drivers/net/ag71xx/ag71xx.h +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx.h 2011-08-22 07:40:12.160480642 +0200 +@@ -0,0 +1,518 @@ ++/* ++ * Atheros AR71xx built-in ethernet mac driver ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Based on Atheros' AG7100 driver ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#ifndef __AG71XX_H ++#define __AG71XX_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#define AG71XX_DRV_NAME "ag71xx" ++#define AG71XX_DRV_VERSION "0.5.35" ++ ++#define AG71XX_NAPI_WEIGHT 64 ++#define AG71XX_OOM_REFILL (1 + HZ/10) ++ ++#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE) ++#define AG71XX_INT_TX (AG71XX_INT_TX_PS) ++#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF) ++ ++#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX) ++#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL) ++ ++#define AG71XX_TX_MTU_LEN 1540 ++#define AG71XX_RX_PKT_RESERVE 64 ++#define AG71XX_RX_PKT_SIZE \ ++ (AG71XX_RX_PKT_RESERVE + ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) ++ ++#define AG71XX_TX_RING_SIZE_DEFAULT 64 ++#define AG71XX_RX_RING_SIZE_DEFAULT 128 ++ ++#define AG71XX_TX_RING_SIZE_MAX 256 ++#define AG71XX_RX_RING_SIZE_MAX 256 ++ ++#ifdef CONFIG_AG71XX_DEBUG ++#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args) ++#else ++#define DBG(fmt, args...) do {} while (0) ++#endif ++ ++#define ag71xx_assert(_cond) \ ++do { \ ++ if (_cond) \ ++ break; \ ++ printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \ ++ BUG(); \ ++} while (0) ++ ++struct ag71xx_desc { ++ u32 data; ++ u32 ctrl; ++#define DESC_EMPTY BIT(31) ++#define DESC_MORE BIT(24) ++#define DESC_PKTLEN_M 0xfff ++ u32 next; ++ u32 pad; ++} __attribute__((aligned(4))); ++ ++struct ag71xx_buf { ++ struct sk_buff *skb; ++ struct ag71xx_desc *desc; ++ dma_addr_t dma_addr; ++ unsigned long timestamp; ++}; ++ ++struct ag71xx_ring { ++ struct ag71xx_buf *buf; ++ u8 *descs_cpu; ++ dma_addr_t descs_dma; ++ unsigned int desc_size; ++ unsigned int curr; ++ unsigned int dirty; ++ unsigned int size; ++}; ++ ++struct ag71xx_mdio { ++ struct mii_bus *mii_bus; ++ int mii_irq[PHY_MAX_ADDR]; ++ void __iomem *mdio_base; ++ struct ag71xx_mdio_platform_data *pdata; ++}; ++ ++struct ag71xx_int_stats { ++ unsigned long rx_pr; ++ unsigned long rx_be; ++ unsigned long rx_of; ++ unsigned long tx_ps; ++ unsigned long tx_be; ++ unsigned long tx_ur; ++ unsigned long total; ++}; ++ ++struct ag71xx_napi_stats { ++ unsigned long napi_calls; ++ unsigned long rx_count; ++ unsigned long rx_packets; ++ unsigned long rx_packets_max; ++ unsigned long tx_count; ++ unsigned long tx_packets; ++ unsigned long tx_packets_max; ++ ++ unsigned long rx[AG71XX_NAPI_WEIGHT + 1]; ++ unsigned long tx[AG71XX_NAPI_WEIGHT + 1]; ++}; ++ ++struct ag71xx_debug { ++ struct dentry *debugfs_dir; ++ ++ struct ag71xx_int_stats int_stats; ++ struct ag71xx_napi_stats napi_stats; ++}; ++ ++struct ag71xx { ++ void __iomem *mac_base; ++ void __iomem *mii_ctrl; ++ ++ spinlock_t lock; ++ struct platform_device *pdev; ++ struct net_device *dev; ++ struct napi_struct napi; ++ u32 msg_enable; ++ ++ struct ag71xx_desc *stop_desc; ++ dma_addr_t stop_desc_dma; ++ ++ struct ag71xx_ring rx_ring; ++ struct ag71xx_ring tx_ring; ++ ++ struct mii_bus *mii_bus; ++ struct phy_device *phy_dev; ++ void *phy_priv; ++ ++ unsigned int link; ++ unsigned int speed; ++ int duplex; ++ ++ struct work_struct restart_work; ++ struct delayed_work link_work; ++ struct timer_list oom_timer; ++ ++#ifdef CONFIG_AG71XX_DEBUG_FS ++ struct ag71xx_debug debug; ++#endif ++}; ++ ++extern struct ethtool_ops ag71xx_ethtool_ops; ++void ag71xx_link_adjust(struct ag71xx *ag); ++ ++int ag71xx_mdio_driver_init(void) __init; ++void ag71xx_mdio_driver_exit(void); ++ ++int ag71xx_phy_connect(struct ag71xx *ag); ++void ag71xx_phy_disconnect(struct ag71xx *ag); ++void ag71xx_phy_start(struct ag71xx *ag); ++void ag71xx_phy_stop(struct ag71xx *ag); ++ ++static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag) ++{ ++ return ag->pdev->dev.platform_data; ++} ++ ++static inline int ag71xx_desc_empty(struct ag71xx_desc *desc) ++{ ++ return (desc->ctrl & DESC_EMPTY) != 0; ++} ++ ++static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc) ++{ ++ return desc->ctrl & DESC_PKTLEN_M; ++} ++ ++/* Register offsets */ ++#define AG71XX_REG_MAC_CFG1 0x0000 ++#define AG71XX_REG_MAC_CFG2 0x0004 ++#define AG71XX_REG_MAC_IPG 0x0008 ++#define AG71XX_REG_MAC_HDX 0x000c ++#define AG71XX_REG_MAC_MFL 0x0010 ++#define AG71XX_REG_MII_CFG 0x0020 ++#define AG71XX_REG_MII_CMD 0x0024 ++#define AG71XX_REG_MII_ADDR 0x0028 ++#define AG71XX_REG_MII_CTRL 0x002c ++#define AG71XX_REG_MII_STATUS 0x0030 ++#define AG71XX_REG_MII_IND 0x0034 ++#define AG71XX_REG_MAC_IFCTL 0x0038 ++#define AG71XX_REG_MAC_ADDR1 0x0040 ++#define AG71XX_REG_MAC_ADDR2 0x0044 ++#define AG71XX_REG_FIFO_CFG0 0x0048 ++#define AG71XX_REG_FIFO_CFG1 0x004c ++#define AG71XX_REG_FIFO_CFG2 0x0050 ++#define AG71XX_REG_FIFO_CFG3 0x0054 ++#define AG71XX_REG_FIFO_CFG4 0x0058 ++#define AG71XX_REG_FIFO_CFG5 0x005c ++#define AG71XX_REG_FIFO_RAM0 0x0060 ++#define AG71XX_REG_FIFO_RAM1 0x0064 ++#define AG71XX_REG_FIFO_RAM2 0x0068 ++#define AG71XX_REG_FIFO_RAM3 0x006c ++#define AG71XX_REG_FIFO_RAM4 0x0070 ++#define AG71XX_REG_FIFO_RAM5 0x0074 ++#define AG71XX_REG_FIFO_RAM6 0x0078 ++#define AG71XX_REG_FIFO_RAM7 0x007c ++ ++#define AG71XX_REG_TX_CTRL 0x0180 ++#define AG71XX_REG_TX_DESC 0x0184 ++#define AG71XX_REG_TX_STATUS 0x0188 ++#define AG71XX_REG_RX_CTRL 0x018c ++#define AG71XX_REG_RX_DESC 0x0190 ++#define AG71XX_REG_RX_STATUS 0x0194 ++#define AG71XX_REG_INT_ENABLE 0x0198 ++#define AG71XX_REG_INT_STATUS 0x019c ++ ++#define AG71XX_REG_FIFO_DEPTH 0x01a8 ++#define AG71XX_REG_RX_SM 0x01b0 ++#define AG71XX_REG_TX_SM 0x01b4 ++ ++#define MAC_CFG1_TXE BIT(0) /* Tx Enable */ ++#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */ ++#define MAC_CFG1_RXE BIT(2) /* Rx Enable */ ++#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */ ++#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */ ++#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */ ++#define MAC_CFG1_LB BIT(8) /* Loopback mode */ ++#define MAC_CFG1_SR BIT(31) /* Soft Reset */ ++ ++#define MAC_CFG2_FDX BIT(0) ++#define MAC_CFG2_CRC_EN BIT(1) ++#define MAC_CFG2_PAD_CRC_EN BIT(2) ++#define MAC_CFG2_LEN_CHECK BIT(4) ++#define MAC_CFG2_HUGE_FRAME_EN BIT(5) ++#define MAC_CFG2_IF_1000 BIT(9) ++#define MAC_CFG2_IF_10_100 BIT(8) ++ ++#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */ ++#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */ ++#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */ ++#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */ ++#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */ ++#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \ ++ | FIFO_CFG0_TXS | FIFO_CFG0_TXF) ++ ++#define FIFO_CFG0_ENABLE_SHIFT 8 ++ ++#define FIFO_CFG4_DE BIT(0) /* Drop Event */ ++#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */ ++#define FIFO_CFG4_FC BIT(2) /* False Carrier */ ++#define FIFO_CFG4_CE BIT(3) /* Code Error */ ++#define FIFO_CFG4_CR BIT(4) /* CRC error */ ++#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */ ++#define FIFO_CFG4_LO BIT(6) /* Length out of range */ ++#define FIFO_CFG4_OK BIT(7) /* Packet is OK */ ++#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */ ++#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */ ++#define FIFO_CFG4_DR BIT(10) /* Dribble */ ++#define FIFO_CFG4_LE BIT(11) /* Long Event */ ++#define FIFO_CFG4_CF BIT(12) /* Control Frame */ ++#define FIFO_CFG4_PF BIT(13) /* Pause Frame */ ++#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */ ++#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */ ++#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */ ++#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */ ++ ++#define FIFO_CFG5_DE BIT(0) /* Drop Event */ ++#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */ ++#define FIFO_CFG5_FC BIT(2) /* False Carrier */ ++#define FIFO_CFG5_CE BIT(3) /* Code Error */ ++#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */ ++#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */ ++#define FIFO_CFG5_OK BIT(6) /* Packet is OK */ ++#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */ ++#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */ ++#define FIFO_CFG5_DR BIT(9) /* Dribble */ ++#define FIFO_CFG5_CF BIT(10) /* Control Frame */ ++#define FIFO_CFG5_PF BIT(11) /* Pause Frame */ ++#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */ ++#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */ ++#define FIFO_CFG5_LE BIT(14) /* Long Event */ ++#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */ ++#define FIFO_CFG5_16 BIT(16) /* unknown */ ++#define FIFO_CFG5_17 BIT(17) /* unknown */ ++#define FIFO_CFG5_SF BIT(18) /* Short Frame */ ++#define FIFO_CFG5_BM BIT(19) /* Byte Mode */ ++ ++#define AG71XX_INT_TX_PS BIT(0) ++#define AG71XX_INT_TX_UR BIT(1) ++#define AG71XX_INT_TX_BE BIT(3) ++#define AG71XX_INT_RX_PR BIT(4) ++#define AG71XX_INT_RX_OF BIT(6) ++#define AG71XX_INT_RX_BE BIT(7) ++ ++#define MAC_IFCTL_SPEED BIT(16) ++ ++#define MII_CFG_CLK_DIV_4 0 ++#define MII_CFG_CLK_DIV_6 2 ++#define MII_CFG_CLK_DIV_8 3 ++#define MII_CFG_CLK_DIV_10 4 ++#define MII_CFG_CLK_DIV_14 5 ++#define MII_CFG_CLK_DIV_20 6 ++#define MII_CFG_CLK_DIV_28 7 ++#define MII_CFG_RESET BIT(31) ++ ++#define MII_CMD_WRITE 0x0 ++#define MII_CMD_READ 0x1 ++#define MII_ADDR_SHIFT 8 ++#define MII_IND_BUSY BIT(0) ++#define MII_IND_INVALID BIT(2) ++ ++#define TX_CTRL_TXE BIT(0) /* Tx Enable */ ++ ++#define TX_STATUS_PS BIT(0) /* Packet Sent */ ++#define TX_STATUS_UR BIT(1) /* Tx Underrun */ ++#define TX_STATUS_BE BIT(3) /* Bus Error */ ++ ++#define RX_CTRL_RXE BIT(0) /* Rx Enable */ ++ ++#define RX_STATUS_PR BIT(0) /* Packet Received */ ++#define RX_STATUS_OF BIT(2) /* Rx Overflow */ ++#define RX_STATUS_BE BIT(3) /* Bus Error */ ++ ++#define MII_CTRL_IF_MASK 3 ++#define MII_CTRL_SPEED_SHIFT 4 ++#define MII_CTRL_SPEED_MASK 3 ++#define MII_CTRL_SPEED_10 0 ++#define MII_CTRL_SPEED_100 1 ++#define MII_CTRL_SPEED_1000 2 ++ ++static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg) ++{ ++ switch (reg) { ++ case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: ++ case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: ++ case AG71XX_REG_MII_CFG: ++ break; ++ ++ default: ++ BUG(); ++ } ++} ++ ++static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) ++{ ++ ag71xx_check_reg_offset(ag, reg); ++ ++ __raw_writel(value, ag->mac_base + reg); ++ /* flush write */ ++ (void) __raw_readl(ag->mac_base + reg); ++} ++ ++static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) ++{ ++ ag71xx_check_reg_offset(ag, reg); ++ ++ return __raw_readl(ag->mac_base + reg); ++} ++ ++static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) ++{ ++ void __iomem *r; ++ ++ ag71xx_check_reg_offset(ag, reg); ++ ++ r = ag->mac_base + reg; ++ __raw_writel(__raw_readl(r) | mask, r); ++ /* flush write */ ++ (void)__raw_readl(r); ++} ++ ++static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) ++{ ++ void __iomem *r; ++ ++ ag71xx_check_reg_offset(ag, reg); ++ ++ r = ag->mac_base + reg; ++ __raw_writel(__raw_readl(r) & ~mask, r); ++ /* flush write */ ++ (void) __raw_readl(r); ++} ++ ++static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) ++{ ++ ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints); ++} ++ ++static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints) ++{ ++ ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints); ++} ++ ++static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ ++ if (pdata->is_ar724x) ++ return; ++ ++ __raw_writel(value, ag->mii_ctrl); ++ ++ /* flush write */ ++ __raw_readl(ag->mii_ctrl); ++} ++ ++static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ ++ if (pdata->is_ar724x) ++ return 0xffffffff; ++ ++ return __raw_readl(ag->mii_ctrl); ++} ++ ++static inline void ag71xx_mii_ctrl_set_if(struct ag71xx *ag, ++ unsigned int mii_if) ++{ ++ u32 t; ++ ++ t = ag71xx_mii_ctrl_rr(ag); ++ t &= ~(MII_CTRL_IF_MASK); ++ t |= (mii_if & MII_CTRL_IF_MASK); ++ ag71xx_mii_ctrl_wr(ag, t); ++} ++ ++static inline void ag71xx_mii_ctrl_set_speed(struct ag71xx *ag, ++ unsigned int speed) ++{ ++ u32 t; ++ ++ t = ag71xx_mii_ctrl_rr(ag); ++ t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT); ++ t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT; ++ ag71xx_mii_ctrl_wr(ag, t); ++} ++ ++#ifdef CONFIG_AG71XX_AR8216_SUPPORT ++void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); ++int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, ++ int pktlen); ++static inline int ag71xx_has_ar8216(struct ag71xx *ag) ++{ ++ return ag71xx_get_pdata(ag)->has_ar8216; ++} ++#else ++static inline void ag71xx_add_ar8216_header(struct ag71xx *ag, ++ struct sk_buff *skb) ++{ ++} ++ ++static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag, ++ struct sk_buff *skb, ++ int pktlen) ++{ ++ return 0; ++} ++static inline int ag71xx_has_ar8216(struct ag71xx *ag) ++{ ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_AG71XX_DEBUG_FS ++int ag71xx_debugfs_root_init(void); ++void ag71xx_debugfs_root_exit(void); ++int ag71xx_debugfs_init(struct ag71xx *ag); ++void ag71xx_debugfs_exit(struct ag71xx *ag); ++void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status); ++void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx); ++#else ++static inline int ag71xx_debugfs_root_init(void) { return 0; } ++static inline void ag71xx_debugfs_root_exit(void) {} ++static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; } ++static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {} ++static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, ++ u32 status) {} ++static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, ++ int rx, int tx) {} ++#endif /* CONFIG_AG71XX_DEBUG_FS */ ++ ++void ag71xx_ar7240_start(struct ag71xx *ag); ++void ag71xx_ar7240_stop(struct ag71xx *ag); ++int ag71xx_ar7240_init(struct ag71xx *ag); ++void ag71xx_ar7240_cleanup(struct ag71xx *ag); ++ ++int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg); ++void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val); ++ ++u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, ++ unsigned reg_addr); ++int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, ++ unsigned reg_addr, u16 reg_val); ++ ++#endif /* _AG71XX_H */ +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c 2011-08-22 07:40:12.160480642 +0200 +@@ -0,0 +1,1291 @@ ++/* ++ * Atheros AR71xx built-in ethernet mac driver ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Based on Atheros' AG7100 driver ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include "ag71xx.h" ++ ++#define AG71XX_DEFAULT_MSG_ENABLE \ ++ (NETIF_MSG_DRV \ ++ | NETIF_MSG_PROBE \ ++ | NETIF_MSG_LINK \ ++ | NETIF_MSG_TIMER \ ++ | NETIF_MSG_IFDOWN \ ++ | NETIF_MSG_IFUP \ ++ | NETIF_MSG_RX_ERR \ ++ | NETIF_MSG_TX_ERR) ++ ++static int ag71xx_msg_level = -1; ++ ++module_param_named(msg_level, ag71xx_msg_level, int, 0); ++MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)"); ++ ++static void ag71xx_dump_dma_regs(struct ag71xx *ag) ++{ ++ DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_TX_CTRL), ++ ag71xx_rr(ag, AG71XX_REG_TX_DESC), ++ ag71xx_rr(ag, AG71XX_REG_TX_STATUS)); ++ ++ DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_RX_CTRL), ++ ag71xx_rr(ag, AG71XX_REG_RX_DESC), ++ ag71xx_rr(ag, AG71XX_REG_RX_STATUS)); ++} ++ ++static void ag71xx_dump_regs(struct ag71xx *ag) ++{ ++ DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_MAC_CFG1), ++ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), ++ ag71xx_rr(ag, AG71XX_REG_MAC_IPG), ++ ag71xx_rr(ag, AG71XX_REG_MAC_HDX), ++ ag71xx_rr(ag, AG71XX_REG_MAC_MFL)); ++ DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), ++ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1), ++ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2)); ++ DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); ++ DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); ++} ++ ++static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr) ++{ ++ DBG("%s: %s intr=%08x %s%s%s%s%s%s\n", ++ ag->dev->name, label, intr, ++ (intr & AG71XX_INT_TX_PS) ? "TXPS " : "", ++ (intr & AG71XX_INT_TX_UR) ? "TXUR " : "", ++ (intr & AG71XX_INT_TX_BE) ? "TXBE " : "", ++ (intr & AG71XX_INT_RX_PR) ? "RXPR " : "", ++ (intr & AG71XX_INT_RX_OF) ? "RXOF " : "", ++ (intr & AG71XX_INT_RX_BE) ? "RXBE " : ""); ++} ++ ++static void ag71xx_ring_free(struct ag71xx_ring *ring) ++{ ++ kfree(ring->buf); ++ ++ if (ring->descs_cpu) ++ dma_free_coherent(NULL, ring->size * ring->desc_size, ++ ring->descs_cpu, ring->descs_dma); ++} ++ ++static int ag71xx_ring_alloc(struct ag71xx_ring *ring) ++{ ++ int err; ++ int i; ++ ++ ring->desc_size = sizeof(struct ag71xx_desc); ++ if (ring->desc_size % cache_line_size()) { ++ DBG("ag71xx: ring %p, desc size %u rounded to %u\n", ++ ring, ring->desc_size, ++ roundup(ring->desc_size, cache_line_size())); ++ ring->desc_size = roundup(ring->desc_size, cache_line_size()); ++ } ++ ++ ring->descs_cpu = dma_alloc_coherent(NULL, ring->size * ring->desc_size, ++ &ring->descs_dma, GFP_ATOMIC); ++ if (!ring->descs_cpu) { ++ err = -ENOMEM; ++ goto err; ++ } ++ ++ ++ ring->buf = kzalloc(ring->size * sizeof(*ring->buf), GFP_KERNEL); ++ if (!ring->buf) { ++ err = -ENOMEM; ++ goto err; ++ } ++ ++ for (i = 0; i < ring->size; i++) { ++ int idx = i * ring->desc_size; ++ ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[idx]; ++ DBG("ag71xx: ring %p, desc %d at %p\n", ++ ring, i, ring->buf[i].desc); ++ } ++ ++ return 0; ++ ++err: ++ return err; ++} ++ ++static void ag71xx_ring_tx_clean(struct ag71xx *ag) ++{ ++ struct ag71xx_ring *ring = &ag->tx_ring; ++ struct net_device *dev = ag->dev; ++ ++ while (ring->curr != ring->dirty) { ++ u32 i = ring->dirty % ring->size; ++ ++ if (!ag71xx_desc_empty(ring->buf[i].desc)) { ++ ring->buf[i].desc->ctrl = 0; ++ dev->stats.tx_errors++; ++ } ++ ++ if (ring->buf[i].skb) ++ dev_kfree_skb_any(ring->buf[i].skb); ++ ++ ring->buf[i].skb = NULL; ++ ++ ring->dirty++; ++ } ++ ++ /* flush descriptors */ ++ wmb(); ++ ++} ++ ++static void ag71xx_ring_tx_init(struct ag71xx *ag) ++{ ++ struct ag71xx_ring *ring = &ag->tx_ring; ++ int i; ++ ++ for (i = 0; i < ring->size; i++) { ++ ring->buf[i].desc->next = (u32) (ring->descs_dma + ++ ring->desc_size * ((i + 1) % ring->size)); ++ ++ ring->buf[i].desc->ctrl = DESC_EMPTY; ++ ring->buf[i].skb = NULL; ++ } ++ ++ /* flush descriptors */ ++ wmb(); ++ ++ ring->curr = 0; ++ ring->dirty = 0; ++} ++ ++static void ag71xx_ring_rx_clean(struct ag71xx *ag) ++{ ++ struct ag71xx_ring *ring = &ag->rx_ring; ++ int i; ++ ++ if (!ring->buf) ++ return; ++ ++ for (i = 0; i < ring->size; i++) ++ if (ring->buf[i].skb) { ++ dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, ++ AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); ++ kfree_skb(ring->buf[i].skb); ++ } ++} ++ ++static int ag71xx_rx_reserve(struct ag71xx *ag) ++{ ++ int reserve = 0; ++ ++ if (ag71xx_get_pdata(ag)->is_ar724x) { ++ if (!ag71xx_has_ar8216(ag)) ++ reserve = 2; ++ ++ if (ag->phy_dev) ++ reserve += 4 - (ag->phy_dev->pkt_align % 4); ++ ++ reserve %= 4; ++ } ++ ++ return reserve + AG71XX_RX_PKT_RESERVE; ++} ++ ++ ++static int ag71xx_ring_rx_init(struct ag71xx *ag) ++{ ++ struct ag71xx_ring *ring = &ag->rx_ring; ++ unsigned int reserve = ag71xx_rx_reserve(ag); ++ unsigned int i; ++ int ret; ++ ++ ret = 0; ++ for (i = 0; i < ring->size; i++) { ++ ring->buf[i].desc->next = (u32) (ring->descs_dma + ++ ring->desc_size * ((i + 1) % ring->size)); ++ ++ DBG("ag71xx: RX desc at %p, next is %08x\n", ++ ring->buf[i].desc, ++ ring->buf[i].desc->next); ++ } ++ ++ for (i = 0; i < ring->size; i++) { ++ struct sk_buff *skb; ++ dma_addr_t dma_addr; ++ ++ skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); ++ if (!skb) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ skb->dev = ag->dev; ++ skb_reserve(skb, reserve); ++ ++ dma_addr = dma_map_single(&ag->dev->dev, skb->data, ++ AG71XX_RX_PKT_SIZE, ++ DMA_FROM_DEVICE); ++ ring->buf[i].skb = skb; ++ ring->buf[i].dma_addr = dma_addr; ++ ring->buf[i].desc->data = (u32) dma_addr; ++ ring->buf[i].desc->ctrl = DESC_EMPTY; ++ } ++ ++ /* flush descriptors */ ++ wmb(); ++ ++ ring->curr = 0; ++ ring->dirty = 0; ++ ++ return ret; ++} ++ ++static int ag71xx_ring_rx_refill(struct ag71xx *ag) ++{ ++ struct ag71xx_ring *ring = &ag->rx_ring; ++ unsigned int reserve = ag71xx_rx_reserve(ag); ++ unsigned int count; ++ ++ count = 0; ++ for (; ring->curr - ring->dirty > 0; ring->dirty++) { ++ unsigned int i; ++ ++ i = ring->dirty % ring->size; ++ ++ if (ring->buf[i].skb == NULL) { ++ dma_addr_t dma_addr; ++ struct sk_buff *skb; ++ ++ skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); ++ if (skb == NULL) ++ break; ++ ++ skb_reserve(skb, reserve); ++ skb->dev = ag->dev; ++ ++ dma_addr = dma_map_single(&ag->dev->dev, skb->data, ++ AG71XX_RX_PKT_SIZE, ++ DMA_FROM_DEVICE); ++ ++ ring->buf[i].skb = skb; ++ ring->buf[i].dma_addr = dma_addr; ++ ring->buf[i].desc->data = (u32) dma_addr; ++ } ++ ++ ring->buf[i].desc->ctrl = DESC_EMPTY; ++ count++; ++ } ++ ++ /* flush descriptors */ ++ wmb(); ++ ++ DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count); ++ ++ return count; ++} ++ ++static int ag71xx_rings_init(struct ag71xx *ag) ++{ ++ int ret; ++ ++ ret = ag71xx_ring_alloc(&ag->tx_ring); ++ if (ret) ++ return ret; ++ ++ ag71xx_ring_tx_init(ag); ++ ++ ret = ag71xx_ring_alloc(&ag->rx_ring); ++ if (ret) ++ return ret; ++ ++ ret = ag71xx_ring_rx_init(ag); ++ return ret; ++} ++ ++static void ag71xx_rings_cleanup(struct ag71xx *ag) ++{ ++ ag71xx_ring_rx_clean(ag); ++ ag71xx_ring_free(&ag->rx_ring); ++ ++ ag71xx_ring_tx_clean(ag); ++ ag71xx_ring_free(&ag->tx_ring); ++} ++ ++static unsigned char *ag71xx_speed_str(struct ag71xx *ag) ++{ ++ switch (ag->speed) { ++ case SPEED_1000: ++ return "1000"; ++ case SPEED_100: ++ return "100"; ++ case SPEED_10: ++ return "10"; ++ } ++ ++ return "?"; ++} ++ ++static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) ++{ ++ u32 t; ++ ++ t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16) ++ | (((u32) mac[3]) << 8) | ((u32) mac[2]); ++ ++ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t); ++ ++ t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16); ++ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); ++} ++ ++static void ag71xx_dma_reset(struct ag71xx *ag) ++{ ++ u32 val; ++ int i; ++ ++ ag71xx_dump_dma_regs(ag); ++ ++ /* stop RX and TX */ ++ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); ++ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); ++ ++ /* ++ * give the hardware some time to really stop all rx/tx activity ++ * clearing the descriptors too early causes random memory corruption ++ */ ++ mdelay(1); ++ ++ /* clear descriptor addresses */ ++ ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->stop_desc_dma); ++ ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->stop_desc_dma); ++ ++ /* clear pending RX/TX interrupts */ ++ for (i = 0; i < 256; i++) { ++ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); ++ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); ++ } ++ ++ /* clear pending errors */ ++ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); ++ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); ++ ++ val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); ++ if (val) ++ printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n", ++ ag->dev->name, val); ++ ++ val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); ++ ++ /* mask out reserved bits */ ++ val &= ~0xff000000; ++ ++ if (val) ++ printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n", ++ ag->dev->name, val); ++ ++ ag71xx_dump_dma_regs(ag); ++} ++ ++#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \ ++ MAC_CFG1_SRX | MAC_CFG1_STX) ++ ++#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT) ++ ++#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \ ++ FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \ ++ FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \ ++ FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \ ++ FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \ ++ FIFO_CFG4_VT) ++ ++#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \ ++ FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \ ++ FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \ ++ FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \ ++ FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \ ++ FIFO_CFG5_17 | FIFO_CFG5_SF) ++ ++static void ag71xx_hw_stop(struct ag71xx *ag) ++{ ++ /* disable all interrupts and stop the rx/tx engine */ ++ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0); ++ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); ++ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); ++} ++ ++static void ag71xx_hw_setup(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ ++ /* setup MAC configuration registers */ ++ ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT); ++ ++ ag71xx_sb(ag, AG71XX_REG_MAC_CFG2, ++ MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK); ++ ++ /* setup max frame length */ ++ ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN); ++ ++ /* setup MII interface type */ ++ ag71xx_mii_ctrl_set_if(ag, pdata->mii_if); ++ ++ /* setup FIFO configuration registers */ ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT); ++ if (pdata->is_ar724x) { ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, pdata->fifo_cfg1); ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, pdata->fifo_cfg2); ++ } else { ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); ++ } ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT); ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT); ++} ++ ++static void ag71xx_hw_init(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ u32 reset_mask = pdata->reset_bit; ++ ++ ag71xx_hw_stop(ag); ++ ++ if (pdata->is_ar724x) { ++ u32 reset_phy = reset_mask; ++ ++ reset_phy &= RESET_MODULE_GE0_PHY | RESET_MODULE_GE1_PHY; ++ reset_mask &= ~(RESET_MODULE_GE0_PHY | RESET_MODULE_GE1_PHY); ++ ++ ar71xx_device_stop(reset_phy); ++ mdelay(50); ++ ar71xx_device_start(reset_phy); ++ mdelay(200); ++ } ++ ++ ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); ++ udelay(20); ++ ++ ar71xx_device_stop(reset_mask); ++ mdelay(100); ++ ar71xx_device_start(reset_mask); ++ mdelay(200); ++ ++ ag71xx_hw_setup(ag); ++ ++ ag71xx_dma_reset(ag); ++} ++ ++static void ag71xx_fast_reset(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ struct net_device *dev = ag->dev; ++ u32 reset_mask = pdata->reset_bit; ++ u32 rx_ds, tx_ds; ++ u32 mii_reg; ++ ++ reset_mask &= RESET_MODULE_GE0_MAC | RESET_MODULE_GE1_MAC; ++ ++ mii_reg = ag71xx_rr(ag, AG71XX_REG_MII_CFG); ++ rx_ds = ag71xx_rr(ag, AG71XX_REG_RX_DESC); ++ tx_ds = ag71xx_rr(ag, AG71XX_REG_TX_DESC); ++ ++ ar71xx_device_stop(reset_mask); ++ udelay(10); ++ ar71xx_device_start(reset_mask); ++ udelay(10); ++ ++ ag71xx_dma_reset(ag); ++ ag71xx_hw_setup(ag); ++ ++ ag71xx_wr(ag, AG71XX_REG_RX_DESC, rx_ds); ++ ag71xx_wr(ag, AG71XX_REG_TX_DESC, tx_ds); ++ ag71xx_wr(ag, AG71XX_REG_MII_CFG, mii_reg); ++ ++ ag71xx_hw_set_macaddr(ag, dev->dev_addr); ++} ++ ++static void ag71xx_hw_start(struct ag71xx *ag) ++{ ++ /* start RX engine */ ++ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); ++ ++ /* enable interrupts */ ++ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT); ++} ++ ++void ag71xx_link_adjust(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ u32 cfg2; ++ u32 ifctl; ++ u32 fifo5; ++ u32 mii_speed; ++ ++ if (!ag->link) { ++ ag71xx_hw_stop(ag); ++ netif_carrier_off(ag->dev); ++ if (netif_msg_link(ag)) ++ printk(KERN_INFO "%s: link down\n", ag->dev->name); ++ return; ++ } ++ ++ if (pdata->is_ar724x) ++ ag71xx_fast_reset(ag); ++ ++ cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); ++ cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); ++ cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; ++ ++ ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); ++ ifctl &= ~(MAC_IFCTL_SPEED); ++ ++ fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); ++ fifo5 &= ~FIFO_CFG5_BM; ++ ++ switch (ag->speed) { ++ case SPEED_1000: ++ mii_speed = MII_CTRL_SPEED_1000; ++ cfg2 |= MAC_CFG2_IF_1000; ++ fifo5 |= FIFO_CFG5_BM; ++ break; ++ case SPEED_100: ++ mii_speed = MII_CTRL_SPEED_100; ++ cfg2 |= MAC_CFG2_IF_10_100; ++ ifctl |= MAC_IFCTL_SPEED; ++ break; ++ case SPEED_10: ++ mii_speed = MII_CTRL_SPEED_10; ++ cfg2 |= MAC_CFG2_IF_10_100; ++ break; ++ default: ++ BUG(); ++ return; ++ } ++ ++ if (pdata->is_ar91xx) ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); ++ else if (pdata->is_ar724x) ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3); ++ else ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff); ++ ++ if (pdata->set_pll) ++ pdata->set_pll(ag->speed); ++ ++ ag71xx_mii_ctrl_set_speed(ag, mii_speed); ++ ++ ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); ++ ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); ++ ag71xx_hw_start(ag); ++ ++ netif_carrier_on(ag->dev); ++ if (netif_msg_link(ag)) ++ printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n", ++ ag->dev->name, ++ ag71xx_speed_str(ag), ++ (DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); ++ ++ DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); ++ ++ DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); ++ ++ DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), ++ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), ++ ag71xx_mii_ctrl_rr(ag)); ++} ++ ++static int ag71xx_open(struct net_device *dev) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ int ret; ++ ++ ret = ag71xx_rings_init(ag); ++ if (ret) ++ goto err; ++ ++ napi_enable(&ag->napi); ++ ++ netif_carrier_off(dev); ++ ag71xx_phy_start(ag); ++ ++ ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma); ++ ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma); ++ ++ ag71xx_hw_set_macaddr(ag, dev->dev_addr); ++ ++ netif_start_queue(dev); ++ ++ return 0; ++ ++err: ++ ag71xx_rings_cleanup(ag); ++ return ret; ++} ++ ++static int ag71xx_stop(struct net_device *dev) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ unsigned long flags; ++ ++ netif_carrier_off(dev); ++ ag71xx_phy_stop(ag); ++ ++ spin_lock_irqsave(&ag->lock, flags); ++ ++ netif_stop_queue(dev); ++ ++ ag71xx_hw_stop(ag); ++ ag71xx_dma_reset(ag); ++ ++ napi_disable(&ag->napi); ++ del_timer_sync(&ag->oom_timer); ++ ++ spin_unlock_irqrestore(&ag->lock, flags); ++ ++ ag71xx_rings_cleanup(ag); ++ ++ return 0; ++} ++ ++static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ struct ag71xx_ring *ring = &ag->tx_ring; ++ struct ag71xx_desc *desc; ++ dma_addr_t dma_addr; ++ int i; ++ ++ i = ring->curr % ring->size; ++ desc = ring->buf[i].desc; ++ ++ if (!ag71xx_desc_empty(desc)) ++ goto err_drop; ++ ++ if (ag71xx_has_ar8216(ag)) ++ ag71xx_add_ar8216_header(ag, skb); ++ ++ if (skb->len <= 0) { ++ DBG("%s: packet len is too small\n", ag->dev->name); ++ goto err_drop; ++ } ++ ++ dma_addr = dma_map_single(&dev->dev, skb->data, skb->len, ++ DMA_TO_DEVICE); ++ ++ ring->buf[i].skb = skb; ++ ring->buf[i].timestamp = jiffies; ++ ++ /* setup descriptor fields */ ++ desc->data = (u32) dma_addr; ++ desc->ctrl = (skb->len & DESC_PKTLEN_M); ++ ++ /* flush descriptor */ ++ wmb(); ++ ++ ring->curr++; ++ if (ring->curr == (ring->dirty + ring->size)) { ++ DBG("%s: tx queue full\n", ag->dev->name); ++ netif_stop_queue(dev); ++ } ++ ++ DBG("%s: packet injected into TX queue\n", ag->dev->name); ++ ++ /* enable TX engine */ ++ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); ++ ++ return NETDEV_TX_OK; ++ ++err_drop: ++ dev->stats.tx_dropped++; ++ ++ dev_kfree_skb(skb); ++ return NETDEV_TX_OK; ++} ++ ++static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ int ret; ++ ++ switch (cmd) { ++ case SIOCETHTOOL: ++ if (ag->phy_dev == NULL) ++ break; ++ ++ spin_lock_irq(&ag->lock); ++ ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data); ++ spin_unlock_irq(&ag->lock); ++ return ret; ++ ++ case SIOCSIFHWADDR: ++ if (copy_from_user ++ (dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr))) ++ return -EFAULT; ++ return 0; ++ ++ case SIOCGIFHWADDR: ++ if (copy_to_user ++ (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr))) ++ return -EFAULT; ++ return 0; ++ ++ case SIOCGMIIPHY: ++ case SIOCGMIIREG: ++ case SIOCSMIIREG: ++ if (ag->phy_dev == NULL) ++ break; ++ ++ return phy_mii_ioctl(ag->phy_dev, ifr, cmd); ++ ++ default: ++ break; ++ } ++ ++ return -EOPNOTSUPP; ++} ++ ++static void ag71xx_oom_timer_handler(unsigned long data) ++{ ++ struct net_device *dev = (struct net_device *) data; ++ struct ag71xx *ag = netdev_priv(dev); ++ ++ napi_schedule(&ag->napi); ++} ++ ++static void ag71xx_tx_timeout(struct net_device *dev) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ ++ if (netif_msg_tx_err(ag)) ++ printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name); ++ ++ schedule_work(&ag->restart_work); ++} ++ ++static void ag71xx_restart_work_func(struct work_struct *work) ++{ ++ struct ag71xx *ag = container_of(work, struct ag71xx, restart_work); ++ ++ if (ag71xx_get_pdata(ag)->is_ar724x) { ++ ag->link = 0; ++ ag71xx_link_adjust(ag); ++ return; ++ } ++ ++ ag71xx_stop(ag->dev); ++ ag71xx_open(ag->dev); ++} ++ ++static bool ag71xx_check_dma_stuck(struct ag71xx *ag, unsigned long timestamp) ++{ ++ u32 rx_sm, tx_sm, rx_fd; ++ ++ if (likely(time_before(jiffies, timestamp + HZ/10))) ++ return false; ++ ++ if (!netif_carrier_ok(ag->dev)) ++ return false; ++ ++ rx_sm = ag71xx_rr(ag, AG71XX_REG_RX_SM); ++ if ((rx_sm & 0x7) == 0x3 && ((rx_sm >> 4) & 0x7) == 0x6) ++ return true; ++ ++ tx_sm = ag71xx_rr(ag, AG71XX_REG_TX_SM); ++ rx_fd = ag71xx_rr(ag, AG71XX_REG_FIFO_DEPTH); ++ if (((tx_sm >> 4) & 0x7) == 0 && ((rx_sm & 0x7) == 0) && ++ ((rx_sm >> 4) & 0x7) == 0 && rx_fd == 0) ++ return true; ++ ++ return false; ++} ++ ++static int ag71xx_tx_packets(struct ag71xx *ag) ++{ ++ struct ag71xx_ring *ring = &ag->tx_ring; ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ int sent; ++ ++ DBG("%s: processing TX ring\n", ag->dev->name); ++ ++ sent = 0; ++ while (ring->dirty != ring->curr) { ++ unsigned int i = ring->dirty % ring->size; ++ struct ag71xx_desc *desc = ring->buf[i].desc; ++ struct sk_buff *skb = ring->buf[i].skb; ++ ++ if (!ag71xx_desc_empty(desc)) { ++ if (pdata->is_ar7240 && ++ ag71xx_check_dma_stuck(ag, ring->buf[i].timestamp)) ++ schedule_work(&ag->restart_work); ++ break; ++ } ++ ++ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); ++ ++ ag->dev->stats.tx_bytes += skb->len; ++ ag->dev->stats.tx_packets++; ++ ++ dev_kfree_skb_any(skb); ++ ring->buf[i].skb = NULL; ++ ++ ring->dirty++; ++ sent++; ++ } ++ ++ DBG("%s: %d packets sent out\n", ag->dev->name, sent); ++ ++ if ((ring->curr - ring->dirty) < (ring->size * 3) / 4) ++ netif_wake_queue(ag->dev); ++ ++ return sent; ++} ++ ++static int ag71xx_rx_packets(struct ag71xx *ag, int limit) ++{ ++ struct net_device *dev = ag->dev; ++ struct ag71xx_ring *ring = &ag->rx_ring; ++ int done = 0; ++ ++ DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n", ++ dev->name, limit, ring->curr, ring->dirty); ++ ++ while (done < limit) { ++ unsigned int i = ring->curr % ring->size; ++ struct ag71xx_desc *desc = ring->buf[i].desc; ++ struct sk_buff *skb; ++ int pktlen; ++ int err = 0; ++ ++ if (ag71xx_desc_empty(desc)) ++ break; ++ ++ if ((ring->dirty + ring->size) == ring->curr) { ++ ag71xx_assert(0); ++ break; ++ } ++ ++ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); ++ ++ skb = ring->buf[i].skb; ++ pktlen = ag71xx_desc_pktlen(desc); ++ pktlen -= ETH_FCS_LEN; ++ ++ dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, ++ AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); ++ ++ dev->last_rx = jiffies; ++ dev->stats.rx_packets++; ++ dev->stats.rx_bytes += pktlen; ++ ++ skb_put(skb, pktlen); ++ if (ag71xx_has_ar8216(ag)) ++ err = ag71xx_remove_ar8216_header(ag, skb, pktlen); ++ ++ if (err) { ++ dev->stats.rx_dropped++; ++ kfree_skb(skb); ++ } else { ++ skb->dev = dev; ++ skb->ip_summed = CHECKSUM_NONE; ++ if (ag->phy_dev) { ++ ag->phy_dev->netif_receive_skb(skb); ++ } else { ++ skb->protocol = eth_type_trans(skb, dev); ++ netif_receive_skb(skb); ++ } ++ } ++ ++ ring->buf[i].skb = NULL; ++ done++; ++ ++ ring->curr++; ++ } ++ ++ ag71xx_ring_rx_refill(ag); ++ ++ DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n", ++ dev->name, ring->curr, ring->dirty, done); ++ ++ return done; ++} ++ ++static int ag71xx_poll(struct napi_struct *napi, int limit) ++{ ++ struct ag71xx *ag = container_of(napi, struct ag71xx, napi); ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ struct net_device *dev = ag->dev; ++ struct ag71xx_ring *rx_ring; ++ unsigned long flags; ++ u32 status; ++ int tx_done; ++ int rx_done; ++ ++ pdata->ddr_flush(); ++ tx_done = ag71xx_tx_packets(ag); ++ ++ DBG("%s: processing RX ring\n", dev->name); ++ rx_done = ag71xx_rx_packets(ag, limit); ++ ++ ag71xx_debugfs_update_napi_stats(ag, rx_done, tx_done); ++ ++ rx_ring = &ag->rx_ring; ++ if (rx_ring->buf[rx_ring->dirty % rx_ring->size].skb == NULL) ++ goto oom; ++ ++ status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); ++ if (unlikely(status & RX_STATUS_OF)) { ++ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF); ++ dev->stats.rx_fifo_errors++; ++ ++ /* restart RX */ ++ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); ++ } ++ ++ if (rx_done < limit) { ++ if (status & RX_STATUS_PR) ++ goto more; ++ ++ status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); ++ if (status & TX_STATUS_PS) ++ goto more; ++ ++ DBG("%s: disable polling mode, rx=%d, tx=%d,limit=%d\n", ++ dev->name, rx_done, tx_done, limit); ++ ++ napi_complete(napi); ++ ++ /* enable interrupts */ ++ spin_lock_irqsave(&ag->lock, flags); ++ ag71xx_int_enable(ag, AG71XX_INT_POLL); ++ spin_unlock_irqrestore(&ag->lock, flags); ++ return rx_done; ++ } ++ ++more: ++ DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n", ++ dev->name, rx_done, tx_done, limit); ++ return rx_done; ++ ++oom: ++ if (netif_msg_rx_err(ag)) ++ printk(KERN_DEBUG "%s: out of memory\n", dev->name); ++ ++ mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL); ++ napi_complete(napi); ++ return 0; ++} ++ ++static irqreturn_t ag71xx_interrupt(int irq, void *dev_id) ++{ ++ struct net_device *dev = dev_id; ++ struct ag71xx *ag = netdev_priv(dev); ++ u32 status; ++ ++ status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS); ++ ag71xx_dump_intr(ag, "raw", status); ++ ++ if (unlikely(!status)) ++ return IRQ_NONE; ++ ++ if (unlikely(status & AG71XX_INT_ERR)) { ++ if (status & AG71XX_INT_TX_BE) { ++ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE); ++ dev_err(&dev->dev, "TX BUS error\n"); ++ } ++ if (status & AG71XX_INT_RX_BE) { ++ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE); ++ dev_err(&dev->dev, "RX BUS error\n"); ++ } ++ } ++ ++ if (likely(status & AG71XX_INT_POLL)) { ++ ag71xx_int_disable(ag, AG71XX_INT_POLL); ++ DBG("%s: enable polling mode\n", dev->name); ++ napi_schedule(&ag->napi); ++ } ++ ++ ag71xx_debugfs_update_int_stats(ag, status); ++ ++ return IRQ_HANDLED; ++} ++ ++static void ag71xx_set_multicast_list(struct net_device *dev) ++{ ++ /* TODO */ ++} ++ ++#ifdef CONFIG_NET_POLL_CONTROLLER ++/* ++ * Polling 'interrupt' - used by things like netconsole to send skbs ++ * without having to re-enable interrupts. It's not called while ++ * the interrupt routine is executing. ++ */ ++static void ag71xx_netpoll(struct net_device *dev) ++{ ++ disable_irq(dev->irq); ++ ag71xx_interrupt(dev->irq, dev); ++ enable_irq(dev->irq); ++} ++#endif ++ ++static const struct net_device_ops ag71xx_netdev_ops = { ++ .ndo_open = ag71xx_open, ++ .ndo_stop = ag71xx_stop, ++ .ndo_start_xmit = ag71xx_hard_start_xmit, ++ .ndo_set_multicast_list = ag71xx_set_multicast_list, ++ .ndo_do_ioctl = ag71xx_do_ioctl, ++ .ndo_tx_timeout = ag71xx_tx_timeout, ++ .ndo_change_mtu = eth_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++#ifdef CONFIG_NET_POLL_CONTROLLER ++ .ndo_poll_controller = ag71xx_netpoll, ++#endif ++}; ++ ++static int __devinit ag71xx_probe(struct platform_device *pdev) ++{ ++ struct net_device *dev; ++ struct resource *res; ++ struct ag71xx *ag; ++ struct ag71xx_platform_data *pdata; ++ int err; ++ ++ pdata = pdev->dev.platform_data; ++ if (!pdata) { ++ dev_err(&pdev->dev, "no platform data specified\n"); ++ err = -ENXIO; ++ goto err_out; ++ } ++ ++ if (pdata->mii_bus_dev == NULL) { ++ dev_err(&pdev->dev, "no MII bus device specified\n"); ++ err = -EINVAL; ++ goto err_out; ++ } ++ ++ dev = alloc_etherdev(sizeof(*ag)); ++ if (!dev) { ++ dev_err(&pdev->dev, "alloc_etherdev failed\n"); ++ err = -ENOMEM; ++ goto err_out; ++ } ++ ++ SET_NETDEV_DEV(dev, &pdev->dev); ++ ++ ag = netdev_priv(dev); ++ ag->pdev = pdev; ++ ag->dev = dev; ++ ag->msg_enable = netif_msg_init(ag71xx_msg_level, ++ AG71XX_DEFAULT_MSG_ENABLE); ++ spin_lock_init(&ag->lock); ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base"); ++ if (!res) { ++ dev_err(&pdev->dev, "no mac_base resource found\n"); ++ err = -ENXIO; ++ goto err_out; ++ } ++ ++ ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1); ++ if (!ag->mac_base) { ++ dev_err(&pdev->dev, "unable to ioremap mac_base\n"); ++ err = -ENOMEM; ++ goto err_free_dev; ++ } ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mii_ctrl"); ++ if (!res) { ++ dev_err(&pdev->dev, "no mii_ctrl resource found\n"); ++ err = -ENXIO; ++ goto err_unmap_base; ++ } ++ ++ ag->mii_ctrl = ioremap_nocache(res->start, res->end - res->start + 1); ++ if (!ag->mii_ctrl) { ++ dev_err(&pdev->dev, "unable to ioremap mii_ctrl\n"); ++ err = -ENOMEM; ++ goto err_unmap_base; ++ } ++ ++ dev->irq = platform_get_irq(pdev, 0); ++ err = request_irq(dev->irq, ag71xx_interrupt, ++ IRQF_DISABLED, ++ dev->name, dev); ++ if (err) { ++ dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq); ++ goto err_unmap_mii_ctrl; ++ } ++ ++ dev->base_addr = (unsigned long)ag->mac_base; ++ dev->netdev_ops = &ag71xx_netdev_ops; ++ dev->ethtool_ops = &ag71xx_ethtool_ops; ++ ++ INIT_WORK(&ag->restart_work, ag71xx_restart_work_func); ++ ++ init_timer(&ag->oom_timer); ++ ag->oom_timer.data = (unsigned long) dev; ++ ag->oom_timer.function = ag71xx_oom_timer_handler; ++ ++ ag->tx_ring.size = AG71XX_TX_RING_SIZE_DEFAULT; ++ ag->rx_ring.size = AG71XX_RX_RING_SIZE_DEFAULT; ++ ++ ag->stop_desc = dma_alloc_coherent(NULL, ++ sizeof(struct ag71xx_desc), &ag->stop_desc_dma, GFP_KERNEL); ++ ++ if (!ag->stop_desc) ++ goto err_free_irq; ++ ++ ag->stop_desc->data = 0; ++ ag->stop_desc->ctrl = 0; ++ ag->stop_desc->next = (u32) ag->stop_desc_dma; ++ ++ memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN); ++ ++ netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT); ++ ++ err = register_netdev(dev); ++ if (err) { ++ dev_err(&pdev->dev, "unable to register net device\n"); ++ goto err_free_desc; ++ } ++ ++ printk(KERN_INFO "%s: Atheros AG71xx at 0x%08lx, irq %d\n", ++ dev->name, dev->base_addr, dev->irq); ++ ++ ag71xx_dump_regs(ag); ++ ++ ag71xx_hw_init(ag); ++ ++ ag71xx_dump_regs(ag); ++ ++ err = ag71xx_phy_connect(ag); ++ if (err) ++ goto err_unregister_netdev; ++ ++ err = ag71xx_debugfs_init(ag); ++ if (err) ++ goto err_phy_disconnect; ++ ++ platform_set_drvdata(pdev, dev); ++ ++ return 0; ++ ++err_phy_disconnect: ++ ag71xx_phy_disconnect(ag); ++err_unregister_netdev: ++ unregister_netdev(dev); ++err_free_desc: ++ dma_free_coherent(NULL, sizeof(struct ag71xx_desc), ag->stop_desc, ++ ag->stop_desc_dma); ++err_free_irq: ++ free_irq(dev->irq, dev); ++err_unmap_mii_ctrl: ++ iounmap(ag->mii_ctrl); ++err_unmap_base: ++ iounmap(ag->mac_base); ++err_free_dev: ++ kfree(dev); ++err_out: ++ platform_set_drvdata(pdev, NULL); ++ return err; ++} ++ ++static int __devexit ag71xx_remove(struct platform_device *pdev) ++{ ++ struct net_device *dev = platform_get_drvdata(pdev); ++ ++ if (dev) { ++ struct ag71xx *ag = netdev_priv(dev); ++ ++ ag71xx_debugfs_exit(ag); ++ ag71xx_phy_disconnect(ag); ++ unregister_netdev(dev); ++ free_irq(dev->irq, dev); ++ iounmap(ag->mii_ctrl); ++ iounmap(ag->mac_base); ++ kfree(dev); ++ platform_set_drvdata(pdev, NULL); ++ } ++ ++ return 0; ++} ++ ++static struct platform_driver ag71xx_driver = { ++ .probe = ag71xx_probe, ++ .remove = __exit_p(ag71xx_remove), ++ .driver = { ++ .name = AG71XX_DRV_NAME, ++ } ++}; ++ ++static int __init ag71xx_module_init(void) ++{ ++ int ret; ++ ++ ret = ag71xx_debugfs_root_init(); ++ if (ret) ++ goto err_out; ++ ++ ret = ag71xx_mdio_driver_init(); ++ if (ret) ++ goto err_debugfs_exit; ++ ++ ret = platform_driver_register(&ag71xx_driver); ++ if (ret) ++ goto err_mdio_exit; ++ ++ return 0; ++ ++err_mdio_exit: ++ ag71xx_mdio_driver_exit(); ++err_debugfs_exit: ++ ag71xx_debugfs_root_exit(); ++err_out: ++ return ret; ++} ++ ++static void __exit ag71xx_module_exit(void) ++{ ++ platform_driver_unregister(&ag71xx_driver); ++ ag71xx_mdio_driver_exit(); ++ ag71xx_debugfs_root_exit(); ++} ++ ++module_init(ag71xx_module_init); ++module_exit(ag71xx_module_exit); ++ ++MODULE_VERSION(AG71XX_DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_AUTHOR("Imre Kaloz "); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" AG71XX_DRV_NAME); +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c 2011-04-27 12:19:22.257663952 +0200 +@@ -0,0 +1,248 @@ ++/* ++ * Atheros AR71xx built-in ethernet mac driver ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Based on Atheros' AG7100 driver ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include "ag71xx.h" ++ ++#define AG71XX_MDIO_RETRY 1000 ++#define AG71XX_MDIO_DELAY 5 ++ ++static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg, ++ u32 value) ++{ ++ void __iomem *r; ++ ++ r = am->mdio_base + reg; ++ __raw_writel(value, r); ++ ++ /* flush write */ ++ (void) __raw_readl(r); ++} ++ ++static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg) ++{ ++ return __raw_readl(am->mdio_base + reg); ++} ++ ++static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am) ++{ ++ DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n", ++ am->mii_bus->name, ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG), ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD), ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR)); ++ DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n", ++ am->mii_bus->name, ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL), ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS), ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_IND)); ++} ++ ++int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg) ++{ ++ int ret; ++ int i; ++ ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, ++ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ); ++ ++ i = AG71XX_MDIO_RETRY; ++ while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { ++ if (i-- == 0) { ++ printk(KERN_ERR "%s: mii_read timed out\n", ++ am->mii_bus->name); ++ ret = 0xffff; ++ goto out; ++ } ++ udelay(AG71XX_MDIO_DELAY); ++ } ++ ++ ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff; ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); ++ ++ DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret); ++ ++out: ++ return ret; ++} ++ ++void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val) ++{ ++ int i; ++ ++ DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val); ++ ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, ++ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val); ++ ++ i = AG71XX_MDIO_RETRY; ++ while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { ++ if (i-- == 0) { ++ printk(KERN_ERR "%s: mii_write timed out\n", ++ am->mii_bus->name); ++ break; ++ } ++ udelay(AG71XX_MDIO_DELAY); ++ } ++} ++ ++static int ag71xx_mdio_reset(struct mii_bus *bus) ++{ ++ struct ag71xx_mdio *am = bus->priv; ++ u32 t; ++ ++ if (am->pdata->is_ar7240) ++ t = MII_CFG_CLK_DIV_6; ++ else ++ t = MII_CFG_CLK_DIV_28; ++ ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET); ++ udelay(100); ++ ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t); ++ udelay(100); ++ ++ return 0; ++} ++ ++static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg) ++{ ++ struct ag71xx_mdio *am = bus->priv; ++ ++ if (am->pdata->is_ar7240) ++ return ar7240sw_phy_read(bus, addr, reg); ++ else ++ return ag71xx_mdio_mii_read(am, addr, reg); ++} ++ ++static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) ++{ ++ struct ag71xx_mdio *am = bus->priv; ++ ++ if (am->pdata->is_ar7240) ++ ar7240sw_phy_write(bus, addr, reg, val); ++ else ++ ag71xx_mdio_mii_write(am, addr, reg, val); ++ return 0; ++} ++ ++static int __devinit ag71xx_mdio_probe(struct platform_device *pdev) ++{ ++ struct ag71xx_mdio_platform_data *pdata; ++ struct ag71xx_mdio *am; ++ struct resource *res; ++ int i; ++ int err; ++ ++ pdata = pdev->dev.platform_data; ++ if (!pdata) { ++ dev_err(&pdev->dev, "no platform data specified\n"); ++ return -EINVAL; ++ } ++ ++ am = kzalloc(sizeof(*am), GFP_KERNEL); ++ if (!am) { ++ err = -ENOMEM; ++ goto err_out; ++ } ++ ++ am->pdata = pdata; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "no iomem resource found\n"); ++ err = -ENXIO; ++ goto err_out; ++ } ++ ++ am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1); ++ if (!am->mdio_base) { ++ dev_err(&pdev->dev, "unable to ioremap registers\n"); ++ err = -ENOMEM; ++ goto err_free_mdio; ++ } ++ ++ am->mii_bus = mdiobus_alloc(); ++ if (am->mii_bus == NULL) { ++ err = -ENOMEM; ++ goto err_iounmap; ++ } ++ ++ am->mii_bus->name = "ag71xx_mdio"; ++ am->mii_bus->read = ag71xx_mdio_read; ++ am->mii_bus->write = ag71xx_mdio_write; ++ am->mii_bus->reset = ag71xx_mdio_reset; ++ am->mii_bus->irq = am->mii_irq; ++ am->mii_bus->priv = am; ++ am->mii_bus->parent = &pdev->dev; ++ snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev)); ++ am->mii_bus->phy_mask = pdata->phy_mask; ++ ++ for (i = 0; i < PHY_MAX_ADDR; i++) ++ am->mii_irq[i] = PHY_POLL; ++ ++ ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0); ++ ++ err = mdiobus_register(am->mii_bus); ++ if (err) ++ goto err_free_bus; ++ ++ ag71xx_mdio_dump_regs(am); ++ ++ platform_set_drvdata(pdev, am); ++ return 0; ++ ++err_free_bus: ++ mdiobus_free(am->mii_bus); ++err_iounmap: ++ iounmap(am->mdio_base); ++err_free_mdio: ++ kfree(am); ++err_out: ++ return err; ++} ++ ++static int __devexit ag71xx_mdio_remove(struct platform_device *pdev) ++{ ++ struct ag71xx_mdio *am = platform_get_drvdata(pdev); ++ ++ if (am) { ++ mdiobus_unregister(am->mii_bus); ++ mdiobus_free(am->mii_bus); ++ iounmap(am->mdio_base); ++ kfree(am); ++ platform_set_drvdata(pdev, NULL); ++ } ++ ++ return 0; ++} ++ ++static struct platform_driver ag71xx_mdio_driver = { ++ .probe = ag71xx_mdio_probe, ++ .remove = __exit_p(ag71xx_mdio_remove), ++ .driver = { ++ .name = "ag71xx-mdio", ++ } ++}; ++ ++int __init ag71xx_mdio_driver_init(void) ++{ ++ return platform_driver_register(&ag71xx_mdio_driver); ++} ++ ++void ag71xx_mdio_driver_exit(void) ++{ ++ platform_driver_unregister(&ag71xx_mdio_driver); ++} +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c 2011-08-06 09:32:37.298018216 +0200 +@@ -0,0 +1,228 @@ ++/* ++ * Atheros AR71xx built-in ethernet mac driver ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Based on Atheros' AG7100 driver ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include "ag71xx.h" ++ ++static void ag71xx_phy_link_adjust(struct net_device *dev) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ struct phy_device *phydev = ag->phy_dev; ++ unsigned long flags; ++ int status_change = 0; ++ ++ spin_lock_irqsave(&ag->lock, flags); ++ ++ if (phydev->link) { ++ if (ag->duplex != phydev->duplex ++ || ag->speed != phydev->speed) { ++ status_change = 1; ++ } ++ } ++ ++ if (phydev->link != ag->link) ++ status_change = 1; ++ ++ ag->link = phydev->link; ++ ag->duplex = phydev->duplex; ++ ag->speed = phydev->speed; ++ ++ if (status_change) ++ ag71xx_link_adjust(ag); ++ ++ spin_unlock_irqrestore(&ag->lock, flags); ++} ++ ++void ag71xx_phy_start(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ ++ if (ag->phy_dev) { ++ phy_start(ag->phy_dev); ++ } else if (pdata->has_ar7240_switch) { ++ ag71xx_ar7240_start(ag); ++ } else { ++ ag->link = 1; ++ ag71xx_link_adjust(ag); ++ } ++} ++ ++void ag71xx_phy_stop(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ ++ if (ag->phy_dev) { ++ phy_stop(ag->phy_dev); ++ } else { ++ if (pdata->has_ar7240_switch) ++ ag71xx_ar7240_stop(ag); ++ ag->link = 0; ++ ag71xx_link_adjust(ag); ++ } ++} ++ ++static int ag71xx_phy_connect_fixed(struct ag71xx *ag) ++{ ++ struct net_device *dev = ag->dev; ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ int ret = 0; ++ ++ /* use fixed settings */ ++ switch (pdata->speed) { ++ case SPEED_10: ++ case SPEED_100: ++ case SPEED_1000: ++ break; ++ default: ++ printk(KERN_ERR "%s: invalid speed specified\n", dev->name); ++ ret = -EINVAL; ++ break; ++ } ++ ++ printk(KERN_DEBUG "%s: using fixed link parameters\n", dev->name); ++ ++ ag->duplex = pdata->duplex; ++ ag->speed = pdata->speed; ++ ++ return ret; ++} ++ ++static int ag71xx_phy_connect_multi(struct ag71xx *ag) ++{ ++ struct net_device *dev = ag->dev; ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ struct phy_device *phydev = NULL; ++ int phy_addr; ++ int ret = 0; ++ ++ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { ++ if (!(pdata->phy_mask & (1 << phy_addr))) ++ continue; ++ ++ if (ag->mii_bus->phy_map[phy_addr] == NULL) ++ continue; ++ ++ DBG("%s: PHY found at %s, uid=%08x\n", ++ dev->name, ++ dev_name(&ag->mii_bus->phy_map[phy_addr]->dev), ++ ag->mii_bus->phy_map[phy_addr]->phy_id); ++ ++ if (phydev == NULL) ++ phydev = ag->mii_bus->phy_map[phy_addr]; ++ } ++ ++ if (!phydev) { ++ printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n", ++ dev->name, pdata->phy_mask); ++ return -ENODEV; ++ } ++ ++ ag->phy_dev = phy_connect(dev, dev_name(&phydev->dev), ++ &ag71xx_phy_link_adjust, 0, ++ pdata->phy_if_mode); ++ ++ if (IS_ERR(ag->phy_dev)) { ++ printk(KERN_ERR "%s: could not connect to PHY at %s\n", ++ dev->name, dev_name(&phydev->dev)); ++ return PTR_ERR(ag->phy_dev); ++ } ++ ++ /* mask with MAC supported features */ ++ if (pdata->has_gbit) ++ phydev->supported &= PHY_GBIT_FEATURES; ++ else ++ phydev->supported &= PHY_BASIC_FEATURES; ++ ++ phydev->advertising = phydev->supported; ++ ++ printk(KERN_DEBUG "%s: connected to PHY at %s [uid=%08x, driver=%s]\n", ++ dev->name, dev_name(&phydev->dev), ++ phydev->phy_id, phydev->drv->name); ++ ++ ag->link = 0; ++ ag->speed = 0; ++ ag->duplex = -1; ++ ++ return ret; ++} ++ ++static int dev_is_class(struct device *dev, void *class) ++{ ++ if (dev->class != NULL && !strcmp(dev->class->name, class)) ++ return 1; ++ ++ return 0; ++} ++ ++static struct device *dev_find_class(struct device *parent, char *class) ++{ ++ if (dev_is_class(parent, class)) { ++ get_device(parent); ++ return parent; ++ } ++ ++ return device_find_child(parent, class, dev_is_class); ++} ++ ++static struct mii_bus *dev_to_mii_bus(struct device *dev) ++{ ++ struct device *d; ++ ++ d = dev_find_class(dev, "mdio_bus"); ++ if (d != NULL) { ++ struct mii_bus *bus; ++ ++ bus = to_mii_bus(d); ++ put_device(d); ++ ++ return bus; ++ } ++ ++ return NULL; ++} ++ ++int __devinit ag71xx_phy_connect(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ ++ ag->mii_bus = dev_to_mii_bus(pdata->mii_bus_dev); ++ if (ag->mii_bus == NULL) { ++ printk(KERN_ERR "%s: unable to find MII bus on device '%s'\n", ++ ag->dev->name, dev_name(pdata->mii_bus_dev)); ++ return -ENODEV; ++ } ++ ++ /* Reset the mdio bus explicitly */ ++ if (ag->mii_bus->reset) { ++ mutex_lock(&ag->mii_bus->mdio_lock); ++ ag->mii_bus->reset(ag->mii_bus); ++ mutex_unlock(&ag->mii_bus->mdio_lock); ++ } ++ ++ if (pdata->has_ar7240_switch) ++ return ag71xx_ar7240_init(ag); ++ ++ if (pdata->phy_mask) ++ return ag71xx_phy_connect_multi(ag); ++ ++ return ag71xx_phy_connect_fixed(ag); ++} ++ ++void ag71xx_phy_disconnect(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ ++ if (pdata->has_ar7240_switch) ++ ag71xx_ar7240_cleanup(ag); ++ else if (ag->phy_dev) ++ phy_disconnect(ag->phy_dev); ++} +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Kconfig linux-2.6.39/drivers/net/ag71xx/Kconfig +--- linux-2.6.39.orig/drivers/net/ag71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/Kconfig 2011-04-27 12:19:22.247664026 +0200 +@@ -0,0 +1,33 @@ ++config AG71XX ++ tristate "Atheros AR71xx built-in ethernet mac support" ++ depends on ATHEROS_AR71XX ++ select PHYLIB ++ help ++ If you wish to compile a kernel for AR71xx/91xx and enable ++ ethernet support, then you should always answer Y to this. ++ ++if AG71XX ++ ++config AG71XX_DEBUG ++ bool "Atheros AR71xx built-in ethernet driver debugging" ++ default n ++ help ++ Atheros AR71xx built-in ethernet driver debugging messages. ++ ++config AG71XX_DEBUG_FS ++ bool "Atheros AR71xx built-in ethernet driver debugfs support" ++ depends on DEBUG_FS ++ default n ++ help ++ Say Y, if you need access to various statistics provided by ++ the ag71xx driver. ++ ++config AG71XX_AR8216_SUPPORT ++ bool "special support for the Atheros AR8216 switch" ++ default n ++ default y if AR71XX_MACH_WNR2000 || AR71XX_MACH_MZK_W04NU ++ help ++ Say 'y' here if you want to enable special support for the ++ Atheros AR8216 switch found on some boards. ++ ++endif +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Makefile linux-2.6.39/drivers/net/ag71xx/Makefile +--- linux-2.6.39.orig/drivers/net/ag71xx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/Makefile 2011-04-27 12:19:22.257663952 +0200 +@@ -0,0 +1,15 @@ ++# ++# Makefile for the Atheros AR71xx built-in ethernet macs ++# ++ ++ag71xx-y += ag71xx_main.o ++ag71xx-y += ag71xx_ethtool.o ++ag71xx-y += ag71xx_phy.o ++ag71xx-y += ag71xx_mdio.o ++ag71xx-y += ag71xx_ar7240.o ++ ++ag71xx-$(CONFIG_AG71XX_DEBUG_FS) += ag71xx_debugfs.o ++ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o ++ ++obj-$(CONFIG_AG71XX) += ag71xx.o ++ +diff -Nur linux-2.6.39.orig/drivers/net/Kconfig linux-2.6.39/drivers/net/Kconfig +--- linux-2.6.39.orig/drivers/net/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/Kconfig 2011-08-22 16:21:54.787979739 +0200 +@@ -2071,6 +2071,8 @@ + + The safe and default value for this is N. + ++source drivers/net/ag71xx/Kconfig ++ + config DL2K + tristate "DL2000/TC902x-based Gigabit Ethernet support" + depends on PCI +diff -Nur linux-2.6.39.orig/drivers/net/Makefile linux-2.6.39/drivers/net/Makefile +--- linux-2.6.39.orig/drivers/net/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/Makefile 2011-08-22 16:21:54.797980120 +0200 +@@ -112,6 +112,7 @@ + # end link order section + # + ++obj-$(CONFIG_AG71XX) += ag71xx/ + obj-$(CONFIG_SUNDANCE) += sundance.o + obj-$(CONFIG_HAMACHI) += hamachi.o + obj-$(CONFIG_NET) += Space.o loopback.o +diff -Nur linux-2.6.39.orig/drivers/net/phy/Kconfig linux-2.6.39/drivers/net/phy/Kconfig +--- linux-2.6.39.orig/drivers/net/phy/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/phy/Kconfig 2011-08-22 22:19:34.339230055 +0200 +@@ -13,6 +13,12 @@ + + if PHYLIB + ++config SWCONFIG ++ tristate "Switch configuration API" ++ ---help--- ++ Switch configuration API using netlink. This allows ++ you to configure the VLAN features of certain switches. ++ + comment "MII PHY device drivers" + + config MARVELL_PHY +diff -Nur linux-2.6.39.orig/drivers/net/phy/Makefile linux-2.6.39/drivers/net/phy/Makefile +--- linux-2.6.39.orig/drivers/net/phy/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/phy/Makefile 2011-08-22 22:19:34.339230055 +0200 +@@ -3,6 +3,7 @@ + libphy-objs := phy.o phy_device.o mdio_bus.o + + obj-$(CONFIG_PHYLIB) += libphy.o ++obj-$(CONFIG_SWCONFIG) += swconfig.o + obj-$(CONFIG_MARVELL_PHY) += marvell.o + obj-$(CONFIG_DAVICOM_PHY) += davicom.o + obj-$(CONFIG_CICADA_PHY) += cicada.o +diff -Nur linux-2.6.39.orig/drivers/net/phy/micrel.c linux-2.6.39/drivers/net/phy/micrel.c +--- linux-2.6.39.orig/drivers/net/phy/micrel.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/phy/micrel.c 2011-04-27 12:19:22.257663952 +0200 +@@ -1,251 +1,82 @@ + /* +- * drivers/net/phy/micrel.c ++ * Driver for Micrel/Kendin PHYs + * +- * Driver for Micrel PHYs ++ * Copyright (c) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * +- * Author: David J. Choi ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + * +- * Copyright (c) 2010 Micrel, 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. +- * +- * Support : ksz9021 1000/100/10 phy from Micrel +- * ks8001, ks8737, ks8721, ks8041, ks8051 100/10 phy + */ + +-#include +-#include ++#include ++#include + #include +-#include + +-/* general Interrupt control/status reg in vendor specific block. */ +-#define MII_KSZPHY_INTCS 0x1B +-#define KSZPHY_INTCS_JABBER (1 << 15) +-#define KSZPHY_INTCS_RECEIVE_ERR (1 << 14) +-#define KSZPHY_INTCS_PAGE_RECEIVE (1 << 13) +-#define KSZPHY_INTCS_PARELLEL (1 << 12) +-#define KSZPHY_INTCS_LINK_PARTNER_ACK (1 << 11) +-#define KSZPHY_INTCS_LINK_DOWN (1 << 10) +-#define KSZPHY_INTCS_REMOTE_FAULT (1 << 9) +-#define KSZPHY_INTCS_LINK_UP (1 << 8) +-#define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\ +- KSZPHY_INTCS_LINK_DOWN) +- +-/* general PHY control reg in vendor specific block. */ +-#define MII_KSZPHY_CTRL 0x1F +-/* bitmap of PHY register to set interrupt mode */ +-#define KSZPHY_CTRL_INT_ACTIVE_HIGH (1 << 9) +-#define KSZ9021_CTRL_INT_ACTIVE_HIGH (1 << 14) +-#define KS8737_CTRL_INT_ACTIVE_HIGH (1 << 14) +-#define KSZ8051_RMII_50MHZ_CLK (1 << 7) ++#define KSZ_REG_INT_CTRL 0x1b + +-static int kszphy_ack_interrupt(struct phy_device *phydev) +-{ +- /* bit[7..0] int status, which is a read and clear register. */ +- int rc; ++#define KSZ_INT_LU_EN (1 << 8) /* enable Link Up interrupt */ ++#define KSZ_INT_RF_EN (1 << 9) /* enable Remote Fault interrupt */ ++#define KSZ_INT_LD_EN (1 << 10) /* enable Link Down interrupt */ + +- rc = phy_read(phydev, MII_KSZPHY_INTCS); +- +- return (rc < 0) ? rc : 0; +-} ++#define KSZ_INT_INIT (KSZ_INT_LU_EN | KSZ_INT_LD_EN) + +-static int kszphy_set_interrupt(struct phy_device *phydev) ++static int ksz8041_ack_interrupt(struct phy_device *phydev) + { +- int temp; +- temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ? +- KSZPHY_INTCS_ALL : 0; +- return phy_write(phydev, MII_KSZPHY_INTCS, temp); +-} ++ int err; + +-static int kszphy_config_intr(struct phy_device *phydev) +-{ +- int temp, rc; ++ err = phy_read(phydev, KSZ_REG_INT_CTRL); + +- /* set the interrupt pin active low */ +- temp = phy_read(phydev, MII_KSZPHY_CTRL); +- temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH; +- phy_write(phydev, MII_KSZPHY_CTRL, temp); +- rc = kszphy_set_interrupt(phydev); +- return rc < 0 ? rc : 0; ++ return (err < 0) ? err : 0; + } + +-static int ksz9021_config_intr(struct phy_device *phydev) ++static int ksz8041_config_intr(struct phy_device *phydev) + { +- int temp, rc; ++ int err; + +- /* set the interrupt pin active low */ +- temp = phy_read(phydev, MII_KSZPHY_CTRL); +- temp &= ~KSZ9021_CTRL_INT_ACTIVE_HIGH; +- phy_write(phydev, MII_KSZPHY_CTRL, temp); +- rc = kszphy_set_interrupt(phydev); +- return rc < 0 ? rc : 0; +-} +- +-static int ks8737_config_intr(struct phy_device *phydev) +-{ +- int temp, rc; ++ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) ++ err = phy_write(phydev, KSZ_REG_INT_CTRL, ++ KSZ_INT_INIT); ++ else ++ err = phy_write(phydev, KSZ_REG_INT_CTRL, 0); + +- /* set the interrupt pin active low */ +- temp = phy_read(phydev, MII_KSZPHY_CTRL); +- temp &= ~KS8737_CTRL_INT_ACTIVE_HIGH; +- phy_write(phydev, MII_KSZPHY_CTRL, temp); +- rc = kszphy_set_interrupt(phydev); +- return rc < 0 ? rc : 0; ++ return err; + } + +-static int kszphy_config_init(struct phy_device *phydev) +-{ +- return 0; +-} +- +-static int ks8051_config_init(struct phy_device *phydev) +-{ +- int regval; +- +- if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { +- regval = phy_read(phydev, MII_KSZPHY_CTRL); +- regval |= KSZ8051_RMII_50MHZ_CLK; +- phy_write(phydev, MII_KSZPHY_CTRL, regval); +- } +- +- return 0; +-} +- +-static struct phy_driver ks8737_driver = { +- .phy_id = PHY_ID_KS8737, +- .phy_id_mask = 0x00fffff0, +- .name = "Micrel KS8737", +- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), +- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, +- .config_init = kszphy_config_init, ++static struct phy_driver ksz8041_phy_driver = { ++ .phy_id = 0x00221512, ++ .name = "Micrel KSZ8041", ++ .phy_id_mask = 0x001fffff, ++ .features = PHY_BASIC_FEATURES, ++ .flags = PHY_HAS_INTERRUPT, + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, +- .ack_interrupt = kszphy_ack_interrupt, +- .config_intr = ks8737_config_intr, +- .driver = { .owner = THIS_MODULE,}, ++ .ack_interrupt = ksz8041_ack_interrupt, ++ .config_intr = ksz8041_config_intr, ++ .driver = { ++ .owner = THIS_MODULE, ++ }, + }; + +-static struct phy_driver ks8041_driver = { +- .phy_id = PHY_ID_KS8041, +- .phy_id_mask = 0x00fffff0, +- .name = "Micrel KS8041", +- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause +- | SUPPORTED_Asym_Pause), +- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, +- .config_init = kszphy_config_init, +- .config_aneg = genphy_config_aneg, +- .read_status = genphy_read_status, +- .ack_interrupt = kszphy_ack_interrupt, +- .config_intr = kszphy_config_intr, +- .driver = { .owner = THIS_MODULE,}, +-}; +- +-static struct phy_driver ks8051_driver = { +- .phy_id = PHY_ID_KS8051, +- .phy_id_mask = 0x00fffff0, +- .name = "Micrel KS8051", +- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause +- | SUPPORTED_Asym_Pause), +- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, +- .config_init = ks8051_config_init, +- .config_aneg = genphy_config_aneg, +- .read_status = genphy_read_status, +- .ack_interrupt = kszphy_ack_interrupt, +- .config_intr = kszphy_config_intr, +- .driver = { .owner = THIS_MODULE,}, +-}; +- +-static struct phy_driver ks8001_driver = { +- .phy_id = PHY_ID_KS8001, +- .name = "Micrel KS8001 or KS8721", +- .phy_id_mask = 0x00fffff0, +- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), +- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, +- .config_init = kszphy_config_init, +- .config_aneg = genphy_config_aneg, +- .read_status = genphy_read_status, +- .ack_interrupt = kszphy_ack_interrupt, +- .config_intr = kszphy_config_intr, +- .driver = { .owner = THIS_MODULE,}, +-}; +- +-static struct phy_driver ksz9021_driver = { +- .phy_id = PHY_ID_KSZ9021, +- .phy_id_mask = 0x000fff10, +- .name = "Micrel KSZ9021 Gigabit PHY", +- .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause +- | SUPPORTED_Asym_Pause), +- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, +- .config_init = kszphy_config_init, +- .config_aneg = genphy_config_aneg, +- .read_status = genphy_read_status, +- .ack_interrupt = kszphy_ack_interrupt, +- .config_intr = ksz9021_config_intr, +- .driver = { .owner = THIS_MODULE, }, +-}; +- +-static int __init ksphy_init(void) ++static int __init micrel_phy_init(void) + { +- int ret; +- +- ret = phy_driver_register(&ks8001_driver); +- if (ret) +- goto err1; +- +- ret = phy_driver_register(&ksz9021_driver); +- if (ret) +- goto err2; +- +- ret = phy_driver_register(&ks8737_driver); +- if (ret) +- goto err3; +- ret = phy_driver_register(&ks8041_driver); +- if (ret) +- goto err4; +- ret = phy_driver_register(&ks8051_driver); +- if (ret) +- goto err5; +- +- return 0; +- +-err5: +- phy_driver_unregister(&ks8041_driver); +-err4: +- phy_driver_unregister(&ks8737_driver); +-err3: +- phy_driver_unregister(&ksz9021_driver); +-err2: +- phy_driver_unregister(&ks8001_driver); +-err1: +- return ret; ++ return phy_driver_register(&ksz8041_phy_driver); + } + +-static void __exit ksphy_exit(void) ++static void __exit micrel_phy_exit(void) + { +- phy_driver_unregister(&ks8001_driver); +- phy_driver_unregister(&ks8737_driver); +- phy_driver_unregister(&ksz9021_driver); +- phy_driver_unregister(&ks8041_driver); +- phy_driver_unregister(&ks8051_driver); ++ phy_driver_unregister(&ksz8041_phy_driver); + } + +-module_init(ksphy_init); +-module_exit(ksphy_exit); +- +-MODULE_DESCRIPTION("Micrel PHY driver"); +-MODULE_AUTHOR("David J. Choi"); +-MODULE_LICENSE("GPL"); +- +-static struct mdio_device_id __maybe_unused micrel_tbl[] = { +- { PHY_ID_KSZ9021, 0x000fff10 }, +- { PHY_ID_KS8001, 0x00fffff0 }, +- { PHY_ID_KS8737, 0x00fffff0 }, +- { PHY_ID_KS8041, 0x00fffff0 }, +- { PHY_ID_KS8051, 0x00fffff0 }, +- { } +-}; ++#ifdef MODULE ++module_init(micrel_phy_init); ++module_exit(micrel_phy_exit); ++#else ++subsys_initcall(micrel_phy_init); ++#endif + +-MODULE_DEVICE_TABLE(mdio, micrel_tbl); ++MODULE_DESCRIPTION("Micrel/Kendin PHY driver"); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_AUTHOR("Imre Kaloz "); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-2.6.39.orig/drivers/net/phy/phy.c linux-2.6.39/drivers/net/phy/phy.c +--- linux-2.6.39.orig/drivers/net/phy/phy.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/phy/phy.c 2011-08-22 22:00:02.067980292 +0200 +@@ -297,6 +297,50 @@ + } + EXPORT_SYMBOL(phy_ethtool_gset); + ++int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr) ++{ ++ u32 cmd; ++ int tmp; ++ struct ethtool_cmd ecmd = { ETHTOOL_GSET }; ++ struct ethtool_value edata = { ETHTOOL_GLINK }; ++ ++ if (get_user(cmd, (u32 *) useraddr)) ++ return -EFAULT; ++ ++ switch (cmd) { ++ case ETHTOOL_GSET: ++ phy_ethtool_gset(phydev, &ecmd); ++ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) ++ return -EFAULT; ++ return 0; ++ ++ case ETHTOOL_SSET: ++ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) ++ return -EFAULT; ++ return phy_ethtool_sset(phydev, &ecmd); ++ ++ case ETHTOOL_NWAY_RST: ++ /* if autoneg is off, it's an error */ ++ tmp = phy_read(phydev, MII_BMCR); ++ if (tmp & BMCR_ANENABLE) { ++ tmp |= (BMCR_ANRESTART); ++ phy_write(phydev, MII_BMCR, tmp); ++ return 0; ++ } ++ return -EINVAL; ++ ++ case ETHTOOL_GLINK: ++ edata.data = (phy_read(phydev, ++ MII_BMSR) & BMSR_LSTATUS) ? 1 : 0; ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; ++ } ++ ++ return -EOPNOTSUPP; ++} ++EXPORT_SYMBOL(phy_ethtool_ioctl); ++ + /** + * phy_mii_ioctl - generic PHY MII ioctl interface + * @phydev: the phy_device struct +@@ -472,7 +516,7 @@ + int idx; + + idx = phy_find_setting(phydev->speed, phydev->duplex); +- ++ + idx++; + + idx = phy_find_valid(idx, phydev->supported); +diff -Nur linux-2.6.39.orig/drivers/net/phy/phy_device.c linux-2.6.39/drivers/net/phy/phy_device.c +--- linux-2.6.39.orig/drivers/net/phy/phy_device.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/phy/phy_device.c 2011-08-22 22:00:06.817981347 +0200 +@@ -149,6 +149,18 @@ + } + EXPORT_SYMBOL(phy_scan_fixups); + ++static int generic_receive_skb(struct sk_buff *skb) ++{ ++ skb->protocol = eth_type_trans(skb, skb->dev); ++ return netif_receive_skb(skb); ++} ++ ++static int generic_rx(struct sk_buff *skb) ++{ ++ skb->protocol = eth_type_trans(skb, skb->dev); ++ return netif_rx(skb); ++} ++ + static struct phy_device* phy_device_create(struct mii_bus *bus, + int addr, int phy_id) + { +@@ -180,6 +192,8 @@ + dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr); + + dev->state = PHY_DOWN; ++ dev->netif_receive_skb = &generic_receive_skb; ++ dev->netif_rx = &generic_rx; + + mutex_init(&dev->lock); + INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); +diff -Nur linux-2.6.39.orig/drivers/net/phy/swconfig.c linux-2.6.39/drivers/net/phy/swconfig.c +--- linux-2.6.39.orig/drivers/net/phy/swconfig.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/phy/swconfig.c 2011-08-22 22:18:58.887990974 +0200 +@@ -0,0 +1,954 @@ ++/* ++ * swconfig.c: Switch configuration API ++ * ++ * Copyright (C) 2008 Felix Fietkau ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++//#define DEBUG 1 ++#ifdef DEBUG ++#define DPRINTF(format, ...) printk("%s: " format, __func__, ##__VA_ARGS__) ++#else ++#define DPRINTF(...) do {} while(0) ++#endif ++ ++#define SWCONFIG_DEVNAME "switch%d" ++ ++MODULE_AUTHOR("Felix Fietkau "); ++MODULE_LICENSE("GPL"); ++ ++static int swdev_id = 0; ++static struct list_head swdevs; ++static DEFINE_SPINLOCK(swdevs_lock); ++struct swconfig_callback; ++ ++struct swconfig_callback ++{ ++ struct sk_buff *msg; ++ struct genlmsghdr *hdr; ++ struct genl_info *info; ++ int cmd; ++ ++ /* callback for filling in the message data */ ++ int (*fill)(struct swconfig_callback *cb, void *arg); ++ ++ /* callback for closing the message before sending it */ ++ int (*close)(struct swconfig_callback *cb, void *arg); ++ ++ struct nlattr *nest[4]; ++ int args[4]; ++}; ++ ++/* defaults */ ++ ++static int ++swconfig_get_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) ++{ ++ int ret; ++ if (val->port_vlan >= dev->vlans) ++ return -EINVAL; ++ ++ if (!dev->ops->get_vlan_ports) ++ return -EOPNOTSUPP; ++ ++ ret = dev->ops->get_vlan_ports(dev, val); ++ return ret; ++} ++ ++static int ++swconfig_set_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) ++{ ++ struct switch_port *ports = val->value.ports; ++ const struct switch_dev_ops *ops = dev->ops; ++ int i; ++ ++ if (val->port_vlan >= dev->vlans) ++ return -EINVAL; ++ ++ /* validate ports */ ++ if (val->len > dev->ports) ++ return -EINVAL; ++ ++ if (!ops->set_vlan_ports) ++ return -EOPNOTSUPP; ++ ++ for (i = 0; i < val->len; i++) { ++ if (ports[i].id >= dev->ports) ++ return -EINVAL; ++ ++ if (ops->set_port_pvid && ++ !(ports[i].flags & (1 << SWITCH_PORT_FLAG_TAGGED))) ++ ops->set_port_pvid(dev, ports[i].id, val->port_vlan); ++ } ++ ++ return ops->set_vlan_ports(dev, val); ++} ++ ++static int ++swconfig_set_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) ++{ ++ if (val->port_vlan >= dev->ports) ++ return -EINVAL; ++ ++ if (!dev->ops->set_port_pvid) ++ return -EOPNOTSUPP; ++ ++ return dev->ops->set_port_pvid(dev, val->port_vlan, val->value.i); ++} ++ ++static int ++swconfig_get_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) ++{ ++ if (val->port_vlan >= dev->ports) ++ return -EINVAL; ++ ++ if (!dev->ops->get_port_pvid) ++ return -EOPNOTSUPP; ++ ++ return dev->ops->get_port_pvid(dev, val->port_vlan, &val->value.i); ++} ++ ++static int ++swconfig_apply_config(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) ++{ ++ /* don't complain if not supported by the switch driver */ ++ if (!dev->ops->apply_config) ++ return 0; ++ ++ return dev->ops->apply_config(dev); ++} ++ ++static int ++swconfig_reset_switch(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) ++{ ++ /* don't complain if not supported by the switch driver */ ++ if (!dev->ops->reset_switch) ++ return 0; ++ ++ return dev->ops->reset_switch(dev); ++} ++ ++enum global_defaults { ++ GLOBAL_APPLY, ++ GLOBAL_RESET, ++}; ++ ++enum vlan_defaults { ++ VLAN_PORTS, ++}; ++ ++enum port_defaults { ++ PORT_PVID, ++}; ++ ++static struct switch_attr default_global[] = { ++ [GLOBAL_APPLY] = { ++ .type = SWITCH_TYPE_NOVAL, ++ .name = "apply", ++ .description = "Activate changes in the hardware", ++ .set = swconfig_apply_config, ++ }, ++ [GLOBAL_RESET] = { ++ .type = SWITCH_TYPE_NOVAL, ++ .name = "reset", ++ .description = "Reset the switch", ++ .set = swconfig_reset_switch, ++ } ++}; ++ ++static struct switch_attr default_port[] = { ++ [PORT_PVID] = { ++ .type = SWITCH_TYPE_INT, ++ .name = "pvid", ++ .description = "Primary VLAN ID", ++ .set = swconfig_set_pvid, ++ .get = swconfig_get_pvid, ++ } ++}; ++ ++static struct switch_attr default_vlan[] = { ++ [VLAN_PORTS] = { ++ .type = SWITCH_TYPE_PORTS, ++ .name = "ports", ++ .description = "VLAN port mapping", ++ .set = swconfig_set_vlan_ports, ++ .get = swconfig_get_vlan_ports, ++ }, ++}; ++ ++ ++static void swconfig_defaults_init(struct switch_dev *dev) ++{ ++ const struct switch_dev_ops *ops = dev->ops; ++ ++ dev->def_global = 0; ++ dev->def_vlan = 0; ++ dev->def_port = 0; ++ ++ if (ops->get_vlan_ports || ops->set_vlan_ports) ++ set_bit(VLAN_PORTS, &dev->def_vlan); ++ ++ if (ops->get_port_pvid || ops->set_port_pvid) ++ set_bit(PORT_PVID, &dev->def_port); ++ ++ /* always present, can be no-op */ ++ set_bit(GLOBAL_APPLY, &dev->def_global); ++ set_bit(GLOBAL_RESET, &dev->def_global); ++} ++ ++ ++static struct genl_family switch_fam = { ++ .id = GENL_ID_GENERATE, ++ .name = "switch", ++ .hdrsize = 0, ++ .version = 1, ++ .maxattr = SWITCH_ATTR_MAX, ++}; ++ ++static const struct nla_policy switch_policy[SWITCH_ATTR_MAX+1] = { ++ [SWITCH_ATTR_ID] = { .type = NLA_U32 }, ++ [SWITCH_ATTR_OP_ID] = { .type = NLA_U32 }, ++ [SWITCH_ATTR_OP_PORT] = { .type = NLA_U32 }, ++ [SWITCH_ATTR_OP_VLAN] = { .type = NLA_U32 }, ++ [SWITCH_ATTR_OP_VALUE_INT] = { .type = NLA_U32 }, ++ [SWITCH_ATTR_OP_VALUE_STR] = { .type = NLA_NUL_STRING }, ++ [SWITCH_ATTR_OP_VALUE_PORTS] = { .type = NLA_NESTED }, ++ [SWITCH_ATTR_TYPE] = { .type = NLA_U32 }, ++}; ++ ++static const struct nla_policy port_policy[SWITCH_PORT_ATTR_MAX+1] = { ++ [SWITCH_PORT_ID] = { .type = NLA_U32 }, ++ [SWITCH_PORT_FLAG_TAGGED] = { .type = NLA_FLAG }, ++}; ++ ++static inline void ++swconfig_lock(void) ++{ ++ spin_lock(&swdevs_lock); ++} ++ ++static inline void ++swconfig_unlock(void) ++{ ++ spin_unlock(&swdevs_lock); ++} ++ ++static struct switch_dev * ++swconfig_get_dev(struct genl_info *info) ++{ ++ struct switch_dev *dev = NULL; ++ struct switch_dev *p; ++ int id; ++ ++ if (!info->attrs[SWITCH_ATTR_ID]) ++ goto done; ++ ++ id = nla_get_u32(info->attrs[SWITCH_ATTR_ID]); ++ swconfig_lock(); ++ list_for_each_entry(p, &swdevs, dev_list) { ++ if (id != p->id) ++ continue; ++ ++ dev = p; ++ break; ++ } ++ if (dev) ++ spin_lock(&dev->lock); ++ else ++ DPRINTF("device %d not found\n", id); ++ swconfig_unlock(); ++done: ++ return dev; ++} ++ ++static inline void ++swconfig_put_dev(struct switch_dev *dev) ++{ ++ spin_unlock(&dev->lock); ++} ++ ++static int ++swconfig_dump_attr(struct swconfig_callback *cb, void *arg) ++{ ++ struct switch_attr *op = arg; ++ struct genl_info *info = cb->info; ++ struct sk_buff *msg = cb->msg; ++ int id = cb->args[0]; ++ void *hdr; ++ ++ hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, &switch_fam, ++ NLM_F_MULTI, SWITCH_CMD_NEW_ATTR); ++ if (IS_ERR(hdr)) ++ return -1; ++ ++ NLA_PUT_U32(msg, SWITCH_ATTR_OP_ID, id); ++ NLA_PUT_U32(msg, SWITCH_ATTR_OP_TYPE, op->type); ++ NLA_PUT_STRING(msg, SWITCH_ATTR_OP_NAME, op->name); ++ if (op->description) ++ NLA_PUT_STRING(msg, SWITCH_ATTR_OP_DESCRIPTION, ++ op->description); ++ ++ return genlmsg_end(msg, hdr); ++nla_put_failure: ++ genlmsg_cancel(msg, hdr); ++ return -EMSGSIZE; ++} ++ ++/* spread multipart messages across multiple message buffers */ ++static int ++swconfig_send_multipart(struct swconfig_callback *cb, void *arg) ++{ ++ struct genl_info *info = cb->info; ++ int restart = 0; ++ int err; ++ ++ do { ++ if (!cb->msg) { ++ cb->msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); ++ if (cb->msg == NULL) ++ goto error; ++ } ++ ++ if (!(cb->fill(cb, arg) < 0)) ++ break; ++ ++ /* fill failed, check if this was already the second attempt */ ++ if (restart) ++ goto error; ++ ++ /* try again in a new message, send the current one */ ++ restart = 1; ++ if (cb->close) { ++ if (cb->close(cb, arg) < 0) ++ goto error; ++ } ++ err = genlmsg_reply(cb->msg, info); ++ cb->msg = NULL; ++ if (err < 0) ++ goto error; ++ ++ } while (restart); ++ ++ return 0; ++ ++error: ++ if (cb->msg) ++ nlmsg_free(cb->msg); ++ return -1; ++} ++ ++static int ++swconfig_list_attrs(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); ++ const struct switch_attrlist *alist; ++ struct switch_dev *dev; ++ struct swconfig_callback cb; ++ int err = -EINVAL; ++ int i; ++ ++ /* defaults */ ++ struct switch_attr *def_list; ++ unsigned long *def_active; ++ int n_def; ++ ++ dev = swconfig_get_dev(info); ++ if (!dev) ++ return -EINVAL; ++ ++ switch(hdr->cmd) { ++ case SWITCH_CMD_LIST_GLOBAL: ++ alist = &dev->ops->attr_global; ++ def_list = default_global; ++ def_active = &dev->def_global; ++ n_def = ARRAY_SIZE(default_global); ++ break; ++ case SWITCH_CMD_LIST_VLAN: ++ alist = &dev->ops->attr_vlan; ++ def_list = default_vlan; ++ def_active = &dev->def_vlan; ++ n_def = ARRAY_SIZE(default_vlan); ++ break; ++ case SWITCH_CMD_LIST_PORT: ++ alist = &dev->ops->attr_port; ++ def_list = default_port; ++ def_active = &dev->def_port; ++ n_def = ARRAY_SIZE(default_port); ++ break; ++ default: ++ WARN_ON(1); ++ goto out; ++ } ++ ++ memset(&cb, 0, sizeof(cb)); ++ cb.info = info; ++ cb.fill = swconfig_dump_attr; ++ for (i = 0; i < alist->n_attr; i++) { ++ if (alist->attr[i].disabled) ++ continue; ++ cb.args[0] = i; ++ err = swconfig_send_multipart(&cb, (void *) &alist->attr[i]); ++ if (err < 0) ++ goto error; ++ } ++ ++ /* defaults */ ++ for (i = 0; i < n_def; i++) { ++ if (!test_bit(i, def_active)) ++ continue; ++ cb.args[0] = SWITCH_ATTR_DEFAULTS_OFFSET + i; ++ err = swconfig_send_multipart(&cb, (void *) &def_list[i]); ++ if (err < 0) ++ goto error; ++ } ++ swconfig_put_dev(dev); ++ ++ if (!cb.msg) ++ return 0; ++ ++ return genlmsg_reply(cb.msg, info); ++ ++error: ++ if (cb.msg) ++ nlmsg_free(cb.msg); ++out: ++ swconfig_put_dev(dev); ++ return err; ++} ++ ++static const struct switch_attr * ++swconfig_lookup_attr(struct switch_dev *dev, struct genl_info *info, ++ struct switch_val *val) ++{ ++ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); ++ const struct switch_attrlist *alist; ++ const struct switch_attr *attr = NULL; ++ int attr_id; ++ ++ /* defaults */ ++ struct switch_attr *def_list; ++ unsigned long *def_active; ++ int n_def; ++ ++ if (!info->attrs[SWITCH_ATTR_OP_ID]) ++ goto done; ++ ++ switch(hdr->cmd) { ++ case SWITCH_CMD_SET_GLOBAL: ++ case SWITCH_CMD_GET_GLOBAL: ++ alist = &dev->ops->attr_global; ++ def_list = default_global; ++ def_active = &dev->def_global; ++ n_def = ARRAY_SIZE(default_global); ++ break; ++ case SWITCH_CMD_SET_VLAN: ++ case SWITCH_CMD_GET_VLAN: ++ alist = &dev->ops->attr_vlan; ++ def_list = default_vlan; ++ def_active = &dev->def_vlan; ++ n_def = ARRAY_SIZE(default_vlan); ++ if (!info->attrs[SWITCH_ATTR_OP_VLAN]) ++ goto done; ++ val->port_vlan = nla_get_u32(info->attrs[SWITCH_ATTR_OP_VLAN]); ++ if (val->port_vlan >= dev->vlans) ++ goto done; ++ break; ++ case SWITCH_CMD_SET_PORT: ++ case SWITCH_CMD_GET_PORT: ++ alist = &dev->ops->attr_port; ++ def_list = default_port; ++ def_active = &dev->def_port; ++ n_def = ARRAY_SIZE(default_port); ++ if (!info->attrs[SWITCH_ATTR_OP_PORT]) ++ goto done; ++ val->port_vlan = nla_get_u32(info->attrs[SWITCH_ATTR_OP_PORT]); ++ if (val->port_vlan >= dev->ports) ++ goto done; ++ break; ++ default: ++ WARN_ON(1); ++ goto done; ++ } ++ ++ if (!alist) ++ goto done; ++ ++ attr_id = nla_get_u32(info->attrs[SWITCH_ATTR_OP_ID]); ++ if (attr_id >= SWITCH_ATTR_DEFAULTS_OFFSET) { ++ attr_id -= SWITCH_ATTR_DEFAULTS_OFFSET; ++ if (attr_id >= n_def) ++ goto done; ++ if (!test_bit(attr_id, def_active)) ++ goto done; ++ attr = &def_list[attr_id]; ++ } else { ++ if (attr_id >= alist->n_attr) ++ goto done; ++ attr = &alist->attr[attr_id]; ++ } ++ ++ if (attr->disabled) ++ attr = NULL; ++ ++done: ++ if (!attr) ++ DPRINTF("attribute lookup failed\n"); ++ val->attr = attr; ++ return attr; ++} ++ ++static int ++swconfig_parse_ports(struct sk_buff *msg, struct nlattr *head, ++ struct switch_val *val, int max) ++{ ++ struct nlattr *nla; ++ int rem; ++ ++ val->len = 0; ++ nla_for_each_nested(nla, head, rem) { ++ struct nlattr *tb[SWITCH_PORT_ATTR_MAX+1]; ++ struct switch_port *port = &val->value.ports[val->len]; ++ ++ if (val->len >= max) ++ return -EINVAL; ++ ++ if (nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, nla, ++ port_policy)) ++ return -EINVAL; ++ ++ if (!tb[SWITCH_PORT_ID]) ++ return -EINVAL; ++ ++ port->id = nla_get_u32(tb[SWITCH_PORT_ID]); ++ if (tb[SWITCH_PORT_FLAG_TAGGED]) ++ port->flags |= (1 << SWITCH_PORT_FLAG_TAGGED); ++ val->len++; ++ } ++ ++ return 0; ++} ++ ++static int ++swconfig_set_attr(struct sk_buff *skb, struct genl_info *info) ++{ ++ const struct switch_attr *attr; ++ struct switch_dev *dev; ++ struct switch_val val; ++ int err = -EINVAL; ++ ++ dev = swconfig_get_dev(info); ++ if (!dev) ++ return -EINVAL; ++ ++ memset(&val, 0, sizeof(val)); ++ attr = swconfig_lookup_attr(dev, info, &val); ++ if (!attr || !attr->set) ++ goto error; ++ ++ val.attr = attr; ++ switch(attr->type) { ++ case SWITCH_TYPE_NOVAL: ++ break; ++ case SWITCH_TYPE_INT: ++ if (!info->attrs[SWITCH_ATTR_OP_VALUE_INT]) ++ goto error; ++ val.value.i = ++ nla_get_u32(info->attrs[SWITCH_ATTR_OP_VALUE_INT]); ++ break; ++ case SWITCH_TYPE_STRING: ++ if (!info->attrs[SWITCH_ATTR_OP_VALUE_STR]) ++ goto error; ++ val.value.s = ++ nla_data(info->attrs[SWITCH_ATTR_OP_VALUE_STR]); ++ break; ++ case SWITCH_TYPE_PORTS: ++ val.value.ports = dev->portbuf; ++ memset(dev->portbuf, 0, ++ sizeof(struct switch_port) * dev->ports); ++ ++ /* TODO: implement multipart? */ ++ if (info->attrs[SWITCH_ATTR_OP_VALUE_PORTS]) { ++ err = swconfig_parse_ports(skb, ++ info->attrs[SWITCH_ATTR_OP_VALUE_PORTS], &val, dev->ports); ++ if (err < 0) ++ goto error; ++ } else { ++ val.len = 0; ++ err = 0; ++ } ++ break; ++ default: ++ goto error; ++ } ++ ++ err = attr->set(dev, attr, &val); ++error: ++ swconfig_put_dev(dev); ++ return err; ++} ++ ++static int ++swconfig_close_portlist(struct swconfig_callback *cb, void *arg) ++{ ++ if (cb->nest[0]) ++ nla_nest_end(cb->msg, cb->nest[0]); ++ return 0; ++} ++ ++static int ++swconfig_send_port(struct swconfig_callback *cb, void *arg) ++{ ++ const struct switch_port *port = arg; ++ struct nlattr *p = NULL; ++ ++ if (!cb->nest[0]) { ++ cb->nest[0] = nla_nest_start(cb->msg, cb->cmd); ++ if (!cb->nest[0]) ++ return -1; ++ } ++ ++ p = nla_nest_start(cb->msg, SWITCH_ATTR_PORT); ++ if (!p) ++ goto error; ++ ++ NLA_PUT_U32(cb->msg, SWITCH_PORT_ID, port->id); ++ if (port->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) ++ NLA_PUT_FLAG(cb->msg, SWITCH_PORT_FLAG_TAGGED); ++ ++ nla_nest_end(cb->msg, p); ++ return 0; ++ ++nla_put_failure: ++ nla_nest_cancel(cb->msg, p); ++error: ++ nla_nest_cancel(cb->msg, cb->nest[0]); ++ return -1; ++} ++ ++static int ++swconfig_send_ports(struct sk_buff **msg, struct genl_info *info, int attr, ++ const struct switch_val *val) ++{ ++ struct swconfig_callback cb; ++ int err = 0; ++ int i; ++ ++ if (!val->value.ports) ++ return -EINVAL; ++ ++ memset(&cb, 0, sizeof(cb)); ++ cb.cmd = attr; ++ cb.msg = *msg; ++ cb.info = info; ++ cb.fill = swconfig_send_port; ++ cb.close = swconfig_close_portlist; ++ ++ cb.nest[0] = nla_nest_start(cb.msg, cb.cmd); ++ for (i = 0; i < val->len; i++) { ++ err = swconfig_send_multipart(&cb, &val->value.ports[i]); ++ if (err) ++ goto done; ++ } ++ err = val->len; ++ swconfig_close_portlist(&cb, NULL); ++ *msg = cb.msg; ++ ++done: ++ return err; ++} ++ ++static int ++swconfig_get_attr(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); ++ const struct switch_attr *attr; ++ struct switch_dev *dev; ++ struct sk_buff *msg = NULL; ++ struct switch_val val; ++ int err = -EINVAL; ++ int cmd = hdr->cmd; ++ ++ dev = swconfig_get_dev(info); ++ if (!dev) ++ return -EINVAL; ++ ++ memset(&val, 0, sizeof(val)); ++ attr = swconfig_lookup_attr(dev, info, &val); ++ if (!attr || !attr->get) ++ goto error; ++ ++ if (attr->type == SWITCH_TYPE_PORTS) { ++ val.value.ports = dev->portbuf; ++ memset(dev->portbuf, 0, ++ sizeof(struct switch_port) * dev->ports); ++ } ++ ++ err = attr->get(dev, attr, &val); ++ if (err) ++ goto error; ++ ++ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); ++ if (!msg) ++ goto error; ++ ++ hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, &switch_fam, ++ 0, cmd); ++ if (IS_ERR(hdr)) ++ goto nla_put_failure; ++ ++ switch(attr->type) { ++ case SWITCH_TYPE_INT: ++ NLA_PUT_U32(msg, SWITCH_ATTR_OP_VALUE_INT, val.value.i); ++ break; ++ case SWITCH_TYPE_STRING: ++ NLA_PUT_STRING(msg, SWITCH_ATTR_OP_VALUE_STR, val.value.s); ++ break; ++ case SWITCH_TYPE_PORTS: ++ err = swconfig_send_ports(&msg, info, ++ SWITCH_ATTR_OP_VALUE_PORTS, &val); ++ if (err < 0) ++ goto nla_put_failure; ++ break; ++ default: ++ DPRINTF("invalid type in attribute\n"); ++ err = -EINVAL; ++ goto error; ++ } ++ err = genlmsg_end(msg, hdr); ++ if (err < 0) ++ goto nla_put_failure; ++ ++ swconfig_put_dev(dev); ++ return genlmsg_reply(msg, info); ++ ++nla_put_failure: ++ if (msg) ++ nlmsg_free(msg); ++error: ++ swconfig_put_dev(dev); ++ if (!err) ++ err = -ENOMEM; ++ return err; ++} ++ ++static int ++swconfig_send_switch(struct sk_buff *msg, u32 pid, u32 seq, int flags, ++ const struct switch_dev *dev) ++{ ++ void *hdr; ++ ++ hdr = genlmsg_put(msg, pid, seq, &switch_fam, flags, ++ SWITCH_CMD_NEW_ATTR); ++ if (IS_ERR(hdr)) ++ return -1; ++ ++ NLA_PUT_U32(msg, SWITCH_ATTR_ID, dev->id); ++ NLA_PUT_STRING(msg, SWITCH_ATTR_DEV_NAME, dev->devname); ++ NLA_PUT_STRING(msg, SWITCH_ATTR_ALIAS, dev->alias); ++ NLA_PUT_STRING(msg, SWITCH_ATTR_NAME, dev->name); ++ NLA_PUT_U32(msg, SWITCH_ATTR_VLANS, dev->vlans); ++ NLA_PUT_U32(msg, SWITCH_ATTR_PORTS, dev->ports); ++ NLA_PUT_U32(msg, SWITCH_ATTR_CPU_PORT, dev->cpu_port); ++ ++ return genlmsg_end(msg, hdr); ++nla_put_failure: ++ genlmsg_cancel(msg, hdr); ++ return -EMSGSIZE; ++} ++ ++static int swconfig_dump_switches(struct sk_buff *skb, ++ struct netlink_callback *cb) ++{ ++ struct switch_dev *dev; ++ int start = cb->args[0]; ++ int idx = 0; ++ ++ swconfig_lock(); ++ list_for_each_entry(dev, &swdevs, dev_list) { ++ if (++idx <= start) ++ continue; ++ if (swconfig_send_switch(skb, NETLINK_CB(cb->skb).pid, ++ cb->nlh->nlmsg_seq, NLM_F_MULTI, ++ dev) < 0) ++ break; ++ } ++ swconfig_unlock(); ++ cb->args[0] = idx; ++ ++ return skb->len; ++} ++ ++static int ++swconfig_done(struct netlink_callback *cb) ++{ ++ return 0; ++} ++ ++static struct genl_ops swconfig_ops[] = { ++ { ++ .cmd = SWITCH_CMD_LIST_GLOBAL, ++ .doit = swconfig_list_attrs, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_LIST_VLAN, ++ .doit = swconfig_list_attrs, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_LIST_PORT, ++ .doit = swconfig_list_attrs, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_GET_GLOBAL, ++ .doit = swconfig_get_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_GET_VLAN, ++ .doit = swconfig_get_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_GET_PORT, ++ .doit = swconfig_get_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_SET_GLOBAL, ++ .doit = swconfig_set_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_SET_VLAN, ++ .doit = swconfig_set_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_SET_PORT, ++ .doit = swconfig_set_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_GET_SWITCH, ++ .dumpit = swconfig_dump_switches, ++ .policy = switch_policy, ++ .done = swconfig_done, ++ } ++}; ++ ++int ++register_switch(struct switch_dev *dev, struct net_device *netdev) ++{ ++ struct switch_dev *sdev; ++ const int max_switches = 8 * sizeof(unsigned long); ++ unsigned long in_use = 0; ++ int i; ++ ++ INIT_LIST_HEAD(&dev->dev_list); ++ if (netdev) { ++ dev->netdev = netdev; ++ if (!dev->alias) ++ dev->alias = netdev->name; ++ } ++ BUG_ON(!dev->alias); ++ ++ if (dev->ports > 0) { ++ dev->portbuf = kzalloc(sizeof(struct switch_port) * dev->ports, ++ GFP_KERNEL); ++ if (!dev->portbuf) ++ return -ENOMEM; ++ } ++ swconfig_defaults_init(dev); ++ spin_lock_init(&dev->lock); ++ swconfig_lock(); ++ dev->id = ++swdev_id; ++ ++ list_for_each_entry(sdev, &swdevs, dev_list) { ++ if (!sscanf(sdev->devname, SWCONFIG_DEVNAME, &i)) ++ continue; ++ if (i < 0 || i > max_switches) ++ continue; ++ ++ set_bit(i, &in_use); ++ } ++ i = find_first_zero_bit(&in_use, max_switches); ++ ++ if (i == max_switches) ++ return -ENFILE; ++ ++ /* fill device name */ ++ snprintf(dev->devname, IFNAMSIZ, SWCONFIG_DEVNAME, i); ++ ++ list_add(&dev->dev_list, &swdevs); ++ swconfig_unlock(); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(register_switch); ++ ++void ++unregister_switch(struct switch_dev *dev) ++{ ++ kfree(dev->portbuf); ++ spin_lock(&dev->lock); ++ swconfig_lock(); ++ list_del(&dev->dev_list); ++ swconfig_unlock(); ++ spin_unlock(&dev->lock); ++} ++EXPORT_SYMBOL_GPL(unregister_switch); ++ ++ ++static int __init ++swconfig_init(void) ++{ ++ int i, err; ++ ++ INIT_LIST_HEAD(&swdevs); ++ err = genl_register_family(&switch_fam); ++ if (err) ++ return err; ++ ++ for (i = 0; i < ARRAY_SIZE(swconfig_ops); i++) { ++ err = genl_register_ops(&switch_fam, &swconfig_ops[i]); ++ if (err) ++ goto unregister; ++ } ++ ++ return 0; ++ ++unregister: ++ genl_unregister_family(&switch_fam); ++ return err; ++} ++ ++static void __exit ++swconfig_exit(void) ++{ ++ genl_unregister_family(&switch_fam); ++} ++ ++module_init(swconfig_init); ++module_exit(swconfig_exit); ++ +diff -Nur linux-2.6.39.orig/drivers/spi/ap83_spi.c linux-2.6.39/drivers/spi/ap83_spi.c +--- linux-2.6.39.orig/drivers/spi/ap83_spi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/spi/ap83_spi.c 2011-04-27 12:19:22.317665385 +0200 +@@ -0,0 +1,283 @@ ++/* ++ * Atheros AP83 board specific SPI Controller driver ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define DRV_DESC "Atheros AP83 board SPI Controller driver" ++#define DRV_VERSION "0.1.0" ++#define DRV_NAME "ap83-spi" ++ ++#define AP83_SPI_CLK_HIGH (1 << 23) ++#define AP83_SPI_CLK_LOW 0 ++#define AP83_SPI_MOSI_HIGH (1 << 22) ++#define AP83_SPI_MOSI_LOW 0 ++ ++#define AP83_SPI_GPIO_CS 1 ++#define AP83_SPI_GPIO_MISO 3 ++ ++struct ap83_spi { ++ struct spi_bitbang bitbang; ++ void __iomem *base; ++ u32 addr; ++ ++ struct platform_device *pdev; ++}; ++ ++static inline u32 ap83_spi_rr(struct ap83_spi *sp, u32 reg) ++{ ++ return __raw_readl(sp->base + reg); ++} ++ ++static inline struct ap83_spi *spidev_to_sp(struct spi_device *spi) ++{ ++ return spi_master_get_devdata(spi->master); ++} ++ ++static inline void setsck(struct spi_device *spi, int val) ++{ ++ struct ap83_spi *sp = spidev_to_sp(spi); ++ ++ if (val) ++ sp->addr |= AP83_SPI_CLK_HIGH; ++ else ++ sp->addr &= ~AP83_SPI_CLK_HIGH; ++ ++ dev_dbg(&spi->dev, "addr=%08x, SCK set to %s\n", ++ sp->addr, (val) ? "HIGH" : "LOW"); ++ ++ ap83_spi_rr(sp, sp->addr); ++} ++ ++static inline void setmosi(struct spi_device *spi, int val) ++{ ++ struct ap83_spi *sp = spidev_to_sp(spi); ++ ++ if (val) ++ sp->addr |= AP83_SPI_MOSI_HIGH; ++ else ++ sp->addr &= ~AP83_SPI_MOSI_HIGH; ++ ++ dev_dbg(&spi->dev, "addr=%08x, MOSI set to %s\n", ++ sp->addr, (val) ? "HIGH" : "LOW"); ++ ++ ap83_spi_rr(sp, sp->addr); ++} ++ ++static inline u32 getmiso(struct spi_device *spi) ++{ ++ u32 ret; ++ ++ ret = gpio_get_value(AP83_SPI_GPIO_MISO) ? 1 : 0; ++ dev_dbg(&spi->dev, "get MISO: %d\n", ret); ++ ++ return ret; ++} ++ ++static inline void do_spidelay(struct spi_device *spi, unsigned nsecs) ++{ ++ ndelay(nsecs); ++} ++ ++static void ap83_spi_chipselect(struct spi_device *spi, int on) ++{ ++ struct ap83_spi *sp = spidev_to_sp(spi); ++ ++ dev_dbg(&spi->dev, "set CS to %d\n", (on) ? 0 : 1); ++ ++ if (on) { ++ ar71xx_flash_acquire(); ++ ++ sp->addr = 0; ++ ap83_spi_rr(sp, sp->addr); ++ ++ gpio_set_value(AP83_SPI_GPIO_CS, 0); ++ } else { ++ gpio_set_value(AP83_SPI_GPIO_CS, 1); ++ ar71xx_flash_release(); ++ } ++} ++ ++#define spidelay(nsecs) \ ++ do { \ ++ /* Steal the spi_device pointer from our caller. \ ++ * The bitbang-API should probably get fixed here... */ \ ++ do_spidelay(spi, nsecs); \ ++ } while (0) ++ ++#define EXPAND_BITBANG_TXRX ++#include ++#include "spi_bitbang_txrx.h" ++ ++static u32 ap83_spi_txrx_mode0(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ dev_dbg(&spi->dev, "TXRX0 word=%08x, bits=%u\n", word, bits); ++ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); ++} ++ ++static u32 ap83_spi_txrx_mode1(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ dev_dbg(&spi->dev, "TXRX1 word=%08x, bits=%u\n", word, bits); ++ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); ++} ++ ++static u32 ap83_spi_txrx_mode2(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ dev_dbg(&spi->dev, "TXRX2 word=%08x, bits=%u\n", word, bits); ++ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); ++} ++ ++static u32 ap83_spi_txrx_mode3(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ dev_dbg(&spi->dev, "TXRX3 word=%08x, bits=%u\n", word, bits); ++ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); ++} ++ ++static int ap83_spi_probe(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct ap83_spi *sp; ++ struct ap83_spi_platform_data *pdata; ++ struct resource *r; ++ int ret; ++ ++ ret = gpio_request(AP83_SPI_GPIO_MISO, "spi-miso"); ++ if (ret) { ++ dev_err(&pdev->dev, "gpio request failed for MISO\n"); ++ return ret; ++ } ++ ++ ret = gpio_request(AP83_SPI_GPIO_CS, "spi-cs"); ++ if (ret) { ++ dev_err(&pdev->dev, "gpio request failed for CS\n"); ++ goto err_free_miso; ++ } ++ ++ ret = gpio_direction_input(AP83_SPI_GPIO_MISO); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set direction of MISO\n"); ++ goto err_free_cs; ++ } ++ ++ ret = gpio_direction_output(AP83_SPI_GPIO_CS, 0); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set direction of CS\n"); ++ goto err_free_cs; ++ } ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(*sp)); ++ if (master == NULL) { ++ dev_err(&pdev->dev, "failed to allocate spi master\n"); ++ return -ENOMEM; ++ } ++ ++ sp = spi_master_get_devdata(master); ++ platform_set_drvdata(pdev, sp); ++ ++ pdata = pdev->dev.platform_data; ++ ++ sp->bitbang.master = spi_master_get(master); ++ sp->bitbang.chipselect = ap83_spi_chipselect; ++ sp->bitbang.txrx_word[SPI_MODE_0] = ap83_spi_txrx_mode0; ++ sp->bitbang.txrx_word[SPI_MODE_1] = ap83_spi_txrx_mode1; ++ sp->bitbang.txrx_word[SPI_MODE_2] = ap83_spi_txrx_mode2; ++ sp->bitbang.txrx_word[SPI_MODE_3] = ap83_spi_txrx_mode3; ++ ++ sp->bitbang.master->bus_num = pdev->id; ++ sp->bitbang.master->num_chipselect = 1; ++ ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (r == NULL) { ++ ret = -ENOENT; ++ goto err_spi_put; ++ } ++ ++ sp->base = ioremap_nocache(r->start, r->end - r->start + 1); ++ if (!sp->base) { ++ ret = -ENXIO; ++ goto err_spi_put; ++ } ++ ++ ret = spi_bitbang_start(&sp->bitbang); ++ if (!ret) ++ goto err_unmap; ++ ++ dev_info(&pdev->dev, "AP83 SPI adapter at %08x\n", r->start); ++ ++ return 0; ++ ++err_unmap: ++ iounmap(sp->base); ++err_spi_put: ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(sp->bitbang.master); ++ ++err_free_cs: ++ gpio_free(AP83_SPI_GPIO_CS); ++err_free_miso: ++ gpio_free(AP83_SPI_GPIO_MISO); ++ return ret; ++} ++ ++static int ap83_spi_remove(struct platform_device *pdev) ++{ ++ struct ap83_spi *sp = platform_get_drvdata(pdev); ++ ++ spi_bitbang_stop(&sp->bitbang); ++ iounmap(sp->base); ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(sp->bitbang.master); ++ ++ return 0; ++} ++ ++static struct platform_driver ap83_spi_drv = { ++ .probe = ap83_spi_probe, ++ .remove = ap83_spi_remove, ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init ap83_spi_init(void) ++{ ++ return platform_driver_register(&ap83_spi_drv); ++} ++module_init(ap83_spi_init); ++ ++static void __exit ap83_spi_exit(void) ++{ ++ platform_driver_unregister(&ap83_spi_drv); ++} ++module_exit(ap83_spi_exit); ++ ++MODULE_ALIAS("platform:" DRV_NAME); ++MODULE_DESCRIPTION(DRV_DESC); ++MODULE_VERSION(DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-2.6.39.orig/drivers/spi/ar71xx_spi.c linux-2.6.39/drivers/spi/ar71xx_spi.c +--- linux-2.6.39.orig/drivers/spi/ar71xx_spi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/spi/ar71xx_spi.c 2011-04-27 12:19:22.317665385 +0200 +@@ -0,0 +1,283 @@ ++/* ++ * Atheros AR71xx SPI Controller driver ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define DRV_DESC "Atheros AR71xx SPI Controller driver" ++#define DRV_VERSION "0.2.4" ++#define DRV_NAME "ar71xx-spi" ++ ++#undef PER_BIT_READ ++ ++struct ar71xx_spi { ++ struct spi_bitbang bitbang; ++ u32 ioc_base; ++ u32 reg_ctrl; ++ ++ void __iomem *base; ++ ++ struct platform_device *pdev; ++ u32 (*get_ioc_base)(u8 chip_select, int cs_high, ++ int is_on); ++}; ++ ++static inline u32 ar71xx_spi_rr(struct ar71xx_spi *sp, unsigned reg) ++{ ++ return __raw_readl(sp->base + reg); ++} ++ ++static inline void ar71xx_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val) ++{ ++ __raw_writel(val, sp->base + reg); ++} ++ ++static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi) ++{ ++ return spi_master_get_devdata(spi->master); ++} ++ ++static u32 ar71xx_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on) ++{ ++ u32 ret; ++ ++ if (is_on == AR71XX_SPI_CS_INACTIVE) ++ ret = SPI_IOC_CS_ALL; ++ else ++ ret = SPI_IOC_CS_ALL & ~SPI_IOC_CS(chip_select); ++ ++ return ret; ++} ++ ++static void ar71xx_spi_chipselect(struct spi_device *spi, int value) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ void __iomem *base = sp->base; ++ u32 ioc_base; ++ ++ switch (value) { ++ case BITBANG_CS_INACTIVE: ++ ioc_base = sp->get_ioc_base(spi->chip_select, ++ (spi->mode & SPI_CS_HIGH) != 0, ++ AR71XX_SPI_CS_INACTIVE); ++ __raw_writel(ioc_base, base + SPI_REG_IOC); ++ break; ++ ++ case BITBANG_CS_ACTIVE: ++ ioc_base = sp->get_ioc_base(spi->chip_select, ++ (spi->mode & SPI_CS_HIGH) != 0, ++ AR71XX_SPI_CS_ACTIVE); ++ ++ __raw_writel(ioc_base, base + SPI_REG_IOC); ++ sp->ioc_base = ioc_base; ++ break; ++ } ++} ++ ++static void ar71xx_spi_setup_regs(struct spi_device *spi) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ ++ /* enable GPIO mode */ ++ ar71xx_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO); ++ ++ /* save CTRL register */ ++ sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_CTRL); ++ ++ /* TODO: setup speed? */ ++ ar71xx_spi_wr(sp, SPI_REG_CTRL, 0x43); ++} ++ ++static void ar71xx_spi_restore_regs(struct spi_device *spi) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ ++ /* restore CTRL register */ ++ ar71xx_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl); ++ /* disable GPIO mode */ ++ ar71xx_spi_wr(sp, SPI_REG_FS, 0); ++} ++ ++static int ar71xx_spi_setup(struct spi_device *spi) ++{ ++ int status; ++ ++ if (spi->bits_per_word > 32) ++ return -EINVAL; ++ ++ if (!spi->controller_state) ++ ar71xx_spi_setup_regs(spi); ++ ++ status = spi_bitbang_setup(spi); ++ if (status && !spi->controller_state) ++ ar71xx_spi_restore_regs(spi); ++ ++ return status; ++} ++ ++static void ar71xx_spi_cleanup(struct spi_device *spi) ++{ ++ ar71xx_spi_restore_regs(spi); ++ spi_bitbang_cleanup(spi); ++} ++ ++static u32 ar71xx_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs, ++ u32 word, u8 bits) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ void __iomem *base = sp->base; ++ u32 ioc = sp->ioc_base; ++ u32 ret; ++ ++ /* clock starts at inactive polarity */ ++ for (word <<= (32 - bits); likely(bits); bits--) { ++ u32 out; ++ ++ if (word & (1 << 31)) ++ out = ioc | SPI_IOC_DO; ++ else ++ out = ioc & ~SPI_IOC_DO; ++ ++ /* setup MSB (to slave) on trailing edge */ ++ __raw_writel(out, base + SPI_REG_IOC); ++ ++ __raw_writel(out | SPI_IOC_CLK, base + SPI_REG_IOC); ++ ++ word <<= 1; ++ ++#ifdef PER_BIT_READ ++ /* sample MSB (from slave) on leading edge */ ++ ret = __raw_readl(base + SPI_REG_RDS); ++ __raw_writel(out, base + SPI_REG_IOC); ++#endif ++ ++ } ++ ++#ifndef PER_BIT_READ ++ ret = __raw_readl(base + SPI_REG_RDS); ++#endif ++ return ret; ++} ++ ++static int ar71xx_spi_probe(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct ar71xx_spi *sp; ++ struct ar71xx_spi_platform_data *pdata; ++ struct resource *r; ++ int ret; ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(*sp)); ++ if (master == NULL) { ++ dev_err(&pdev->dev, "failed to allocate spi master\n"); ++ return -ENOMEM; ++ } ++ ++ sp = spi_master_get_devdata(master); ++ platform_set_drvdata(pdev, sp); ++ ++ pdata = pdev->dev.platform_data; ++ ++ master->setup = ar71xx_spi_setup; ++ master->cleanup = ar71xx_spi_cleanup; ++ ++ sp->bitbang.master = spi_master_get(master); ++ sp->bitbang.chipselect = ar71xx_spi_chipselect; ++ sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0; ++ sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; ++ ++ sp->get_ioc_base = ar71xx_spi_get_ioc_base; ++ if (pdata) { ++ sp->bitbang.master->bus_num = pdata->bus_num; ++ sp->bitbang.master->num_chipselect = pdata->num_chipselect; ++ if (pdata->get_ioc_base) ++ sp->get_ioc_base = pdata->get_ioc_base; ++ } else { ++ sp->bitbang.master->bus_num = 0; ++ sp->bitbang.master->num_chipselect = 3; ++ } ++ ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (r == NULL) { ++ ret = -ENOENT; ++ goto err1; ++ } ++ ++ sp->base = ioremap_nocache(r->start, r->end - r->start + 1); ++ if (!sp->base) { ++ ret = -ENXIO; ++ goto err1; ++ } ++ ++ ret = spi_bitbang_start(&sp->bitbang); ++ if (!ret) ++ return 0; ++ ++ iounmap(sp->base); ++err1: ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(sp->bitbang.master); ++ ++ return ret; ++} ++ ++static int ar71xx_spi_remove(struct platform_device *pdev) ++{ ++ struct ar71xx_spi *sp = platform_get_drvdata(pdev); ++ ++ spi_bitbang_stop(&sp->bitbang); ++ iounmap(sp->base); ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(sp->bitbang.master); ++ ++ return 0; ++} ++ ++static struct platform_driver ar71xx_spi_drv = { ++ .probe = ar71xx_spi_probe, ++ .remove = ar71xx_spi_remove, ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init ar71xx_spi_init(void) ++{ ++ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); ++ return platform_driver_register(&ar71xx_spi_drv); ++} ++module_init(ar71xx_spi_init); ++ ++static void __exit ar71xx_spi_exit(void) ++{ ++ platform_driver_unregister(&ar71xx_spi_drv); ++} ++module_exit(ar71xx_spi_exit); ++ ++MODULE_ALIAS("platform:" DRV_NAME); ++MODULE_DESCRIPTION(DRV_DESC); ++MODULE_VERSION(DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_AUTHOR("Imre Kaloz "); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-2.6.39.orig/drivers/spi/Kconfig linux-2.6.39/drivers/spi/Kconfig +--- linux-2.6.39.orig/drivers/spi/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/spi/Kconfig 2011-08-23 15:10:24.167989908 +0200 +@@ -67,6 +67,13 @@ + This enables support for the SPI controller present on the + Atheros AR71XX/AR724X/AR913X SoCs. + ++config SPI_AR71XX ++ tristate "Atheros AR71xx SPI Controller" ++ depends on SPI_MASTER && ATHEROS_AR71XX ++ select SPI_BITBANG ++ help ++ This is the SPI contoller driver for Atheros AR71xx. ++ + config SPI_ATMEL + tristate "Atmel SPI Controller" + depends on (ARCH_AT91 || AVR32) +@@ -301,6 +308,12 @@ + config SPI_PXA2XX_PCI + def_bool SPI_PXA2XX && X86_32 && PCI + ++config SPI_RB4XX ++ tristate "Mikrotik RB4XX SPI master" ++ depends on SPI_MASTER && AR71XX_MACH_RB4XX ++ help ++ SPI controller driver for the Mikrotik RB4xx series boards. ++ + config SPI_S3C24XX + tristate "Samsung S3C24XX series SPI" + depends on ARCH_S3C2410 && EXPERIMENTAL +@@ -457,6 +470,13 @@ + sysfs interface, with each line presented as a kind of GPIO + exposing both switch control and diagnostic feedback. + ++config SPI_RB4XX_CPLD ++ tristate "MikroTik RB4XX CPLD driver" ++ depends on AR71XX_MACH_RB4XX ++ help ++ SPI driver for the Xilinx CPLD chip present on the ++ MikroTik RB4xx boards. ++ + # + # Add new SPI protocol masters in alphabetical order above this line + # +diff -Nur linux-2.6.39.orig/drivers/spi/Kconfig.orig linux-2.6.39/drivers/spi/Kconfig.orig +--- linux-2.6.39.orig/drivers/spi/Kconfig.orig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/spi/Kconfig.orig 2011-08-23 15:10:11.277991848 +0200 +@@ -0,0 +1,482 @@ ++# ++# SPI driver configuration ++# ++# NOTE: the reason this doesn't show SPI slave support is mostly that ++# nobody's needed a slave side API yet. The master-role API is not ++# fully appropriate there, so it'd need some thought to do well. ++# ++menuconfig SPI ++ bool "SPI support" ++ depends on HAS_IOMEM ++ help ++ The "Serial Peripheral Interface" is a low level synchronous ++ protocol. Chips that support SPI can have data transfer rates ++ up to several tens of Mbit/sec. Chips are addressed with a ++ controller and a chipselect. Most SPI slaves don't support ++ dynamic device discovery; some are even write-only or read-only. ++ ++ SPI is widely used by microcontrollers to talk with sensors, ++ eeprom and flash memory, codecs and various other controller ++ chips, analog to digital (and d-to-a) converters, and more. ++ MMC and SD cards can be accessed using SPI protocol; and for ++ DataFlash cards used in MMC sockets, SPI must always be used. ++ ++ SPI is one of a family of similar protocols using a four wire ++ interface (select, clock, data in, data out) including Microwire ++ (half duplex), SSP, SSI, and PSP. This driver framework should ++ work with most such devices and controllers. ++ ++if SPI ++ ++config SPI_DEBUG ++ boolean "Debug support for SPI drivers" ++ depends on DEBUG_KERNEL ++ help ++ Say "yes" to enable debug messaging (like dev_dbg and pr_debug), ++ sysfs, and debugfs support in SPI controller and protocol drivers. ++ ++# ++# MASTER side ... talking to discrete SPI slave chips including microcontrollers ++# ++ ++config SPI_MASTER ++# boolean "SPI Master Support" ++ boolean ++ default SPI ++ help ++ If your system has an master-capable SPI controller (which ++ provides the clock and chipselect), you can enable that ++ controller and the protocol drivers for the SPI slave chips ++ that are connected. ++ ++if SPI_MASTER ++ ++comment "SPI Master Controller Drivers" ++ ++config SPI_ALTERA ++ tristate "Altera SPI Controller" ++ select SPI_BITBANG ++ help ++ This is the driver for the Altera SPI Controller. ++ ++config SPI_ATH79 ++ tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver" ++ depends on ATH79 && GENERIC_GPIO ++ select SPI_BITBANG ++ help ++ This enables support for the SPI controller present on the ++ Atheros AR71XX/AR724X/AR913X SoCs. ++ ++config SPI_AR71XX ++ tristate "Atheros AR71xx SPI Controller" ++ depends on SPI_MASTER && ATHEROS_AR71XX ++ select SPI_BITBANG ++ help ++ This is the SPI contoller driver for Atheros AR71xx. ++ ++config SPI_ATMEL ++ tristate "Atmel SPI Controller" ++ depends on (ARCH_AT91 || AVR32) ++ help ++ This selects a driver for the Atmel SPI Controller, present on ++ many AT32 (AVR32) and AT91 (ARM) chips. ++ ++config SPI_BFIN ++ tristate "SPI controller driver for ADI Blackfin5xx" ++ depends on BLACKFIN ++ help ++ This is the SPI controller master driver for Blackfin 5xx processor. ++ ++config SPI_AU1550 ++ tristate "Au1550/Au12x0 SPI Controller" ++ depends on (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL ++ select SPI_BITBANG ++ help ++ If you say yes to this option, support will be included for the ++ Au1550 SPI controller (may also work with Au1200,Au1210,Au1250). ++ ++ This driver can also be built as a module. If so, the module ++ will be called au1550_spi. ++ ++config SPI_BITBANG ++ tristate "Utilities for Bitbanging SPI masters" ++ help ++ With a few GPIO pins, your system can bitbang the SPI protocol. ++ Select this to get SPI support through I/O pins (GPIO, parallel ++ port, etc). Or, some systems' SPI master controller drivers use ++ this code to manage the per-word or per-transfer accesses to the ++ hardware shift registers. ++ ++ This is library code, and is automatically selected by drivers that ++ need it. You only need to select this explicitly to support driver ++ modules that aren't part of this kernel tree. ++ ++config SPI_BUTTERFLY ++ tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)" ++ depends on PARPORT ++ select SPI_BITBANG ++ help ++ This uses a custom parallel port cable to connect to an AVR ++ Butterfly , an ++ inexpensive battery powered microcontroller evaluation board. ++ This same cable can be used to flash new firmware. ++ ++config SPI_COLDFIRE_QSPI ++ tristate "Freescale Coldfire QSPI controller" ++ depends on (M520x || M523x || M5249 || M527x || M528x || M532x) ++ help ++ This enables support for the Coldfire QSPI controller in master ++ mode. ++ ++ This driver can also be built as a module. If so, the module ++ will be called coldfire_qspi. ++ ++config SPI_DAVINCI ++ tristate "Texas Instruments DaVinci/DA8x/OMAP-L/AM1x SoC SPI controller" ++ depends on SPI_MASTER && ARCH_DAVINCI ++ select SPI_BITBANG ++ help ++ SPI master controller for DaVinci/DA8x/OMAP-L/AM1x SPI modules. ++ ++ This driver can also be built as a module. The module will be called ++ davinci_spi. ++ ++config SPI_EP93XX ++ tristate "Cirrus Logic EP93xx SPI controller" ++ depends on ARCH_EP93XX ++ help ++ This enables using the Cirrus EP93xx SPI controller in master ++ mode. ++ ++ To compile this driver as a module, choose M here. The module will be ++ called ep93xx_spi. ++ ++config SPI_GPIO ++ tristate "GPIO-based bitbanging SPI Master" ++ depends on GENERIC_GPIO ++ select SPI_BITBANG ++ help ++ This simple GPIO bitbanging SPI master uses the arch-neutral GPIO ++ interface to manage MOSI, MISO, SCK, and chipselect signals. SPI ++ slaves connected to a bus using this driver are configured as usual, ++ except that the spi_board_info.controller_data holds the GPIO number ++ for the chipselect used by this controller driver. ++ ++ Note that this driver often won't achieve even 1 Mbit/sec speeds, ++ making it unusually slow for SPI. If your platform can inline ++ GPIO operations, you should be able to leverage that for better ++ speed with a custom version of this driver; see the source code. ++ ++config SPI_IMX_VER_IMX1 ++ def_bool y if SOC_IMX1 ++ ++config SPI_IMX_VER_0_0 ++ def_bool y if SOC_IMX21 || SOC_IMX27 ++ ++config SPI_IMX_VER_0_4 ++ def_bool y if SOC_IMX31 ++ ++config SPI_IMX_VER_0_7 ++ def_bool y if ARCH_MX25 || SOC_IMX35 || SOC_IMX51 || SOC_IMX53 ++ ++config SPI_IMX_VER_2_3 ++ def_bool y if SOC_IMX51 || SOC_IMX53 ++ ++config SPI_IMX ++ tristate "Freescale i.MX SPI controllers" ++ depends on ARCH_MXC ++ select SPI_BITBANG ++ default m if IMX_HAVE_PLATFORM_SPI_IMX ++ help ++ This enables using the Freescale i.MX SPI controllers in master ++ mode. ++ ++config SPI_LM70_LLP ++ tristate "Parallel port adapter for LM70 eval board (DEVELOPMENT)" ++ depends on PARPORT && EXPERIMENTAL ++ select SPI_BITBANG ++ help ++ This driver supports the NS LM70 LLP Evaluation Board, ++ which interfaces to an LM70 temperature sensor using ++ a parallel port. ++ ++config SPI_MPC52xx ++ tristate "Freescale MPC52xx SPI (non-PSC) controller support" ++ depends on PPC_MPC52xx && SPI ++ select SPI_MASTER_OF ++ help ++ This drivers supports the MPC52xx SPI controller in master SPI ++ mode. ++ ++config SPI_MPC52xx_PSC ++ tristate "Freescale MPC52xx PSC SPI controller" ++ depends on PPC_MPC52xx && EXPERIMENTAL ++ help ++ This enables using the Freescale MPC52xx Programmable Serial ++ Controller in master SPI mode. ++ ++config SPI_MPC512x_PSC ++ tristate "Freescale MPC512x PSC SPI controller" ++ depends on SPI_MASTER && PPC_MPC512x ++ help ++ This enables using the Freescale MPC5121 Programmable Serial ++ Controller in SPI master mode. ++ ++config SPI_FSL_LIB ++ tristate ++ depends on FSL_SOC ++ ++config SPI_FSL_SPI ++ tristate "Freescale SPI controller" ++ depends on FSL_SOC ++ select SPI_FSL_LIB ++ help ++ This enables using the Freescale SPI controllers in master mode. ++ MPC83xx platform uses the controller in cpu mode or CPM/QE mode. ++ MPC8569 uses the controller in QE mode, MPC8610 in cpu mode. ++ ++config SPI_FSL_ESPI ++ tristate "Freescale eSPI controller" ++ depends on FSL_SOC ++ select SPI_FSL_LIB ++ help ++ This enables using the Freescale eSPI controllers in master mode. ++ From MPC8536, 85xx platform uses the controller, and all P10xx, ++ P20xx, P30xx,P40xx, P50xx uses this controller. ++ ++config SPI_OC_TINY ++ tristate "OpenCores tiny SPI" ++ depends on GENERIC_GPIO ++ select SPI_BITBANG ++ help ++ This is the driver for OpenCores tiny SPI master controller. ++ ++config SPI_OMAP_UWIRE ++ tristate "OMAP1 MicroWire" ++ depends on ARCH_OMAP1 ++ select SPI_BITBANG ++ help ++ This hooks up to the MicroWire controller on OMAP1 chips. ++ ++config SPI_OMAP24XX ++ tristate "McSPI driver for OMAP" ++ depends on ARCH_OMAP2PLUS ++ help ++ SPI master controller for OMAP24XX and later Multichannel SPI ++ (McSPI) modules. ++ ++config SPI_OMAP_100K ++ tristate "OMAP SPI 100K" ++ depends on SPI_MASTER && (ARCH_OMAP850 || ARCH_OMAP730) ++ help ++ OMAP SPI 100K master controller for omap7xx boards. ++ ++config SPI_ORION ++ tristate "Orion SPI master (EXPERIMENTAL)" ++ depends on PLAT_ORION && EXPERIMENTAL ++ help ++ This enables using the SPI master controller on the Orion chips. ++ ++config SPI_PL022 ++ tristate "ARM AMBA PL022 SSP controller (EXPERIMENTAL)" ++ depends on ARM_AMBA && EXPERIMENTAL ++ default y if MACH_U300 ++ default y if ARCH_REALVIEW ++ default y if INTEGRATOR_IMPD1 ++ default y if ARCH_VERSATILE ++ help ++ This selects the ARM(R) AMBA(R) PrimeCell PL022 SSP ++ controller. If you have an embedded system with an AMBA(R) ++ bus and a PL022 controller, say Y or M here. ++ ++config SPI_PPC4xx ++ tristate "PPC4xx SPI Controller" ++ depends on PPC32 && 4xx && SPI_MASTER ++ select SPI_BITBANG ++ help ++ This selects a driver for the PPC4xx SPI Controller. ++ ++config SPI_PXA2XX ++ tristate "PXA2xx SSP SPI master" ++ depends on (ARCH_PXA || (X86_32 && PCI)) && EXPERIMENTAL ++ select PXA_SSP if ARCH_PXA ++ help ++ This enables using a PXA2xx or Sodaville SSP port as a SPI master ++ controller. The driver can be configured to use any SSP port and ++ additional documentation can be found a Documentation/spi/pxa2xx. ++ ++config SPI_PXA2XX_PCI ++ def_bool SPI_PXA2XX && X86_32 && PCI ++ ++config SPI_S3C24XX ++ tristate "Samsung S3C24XX series SPI" ++ depends on ARCH_S3C2410 && EXPERIMENTAL ++ select SPI_BITBANG ++ help ++ SPI driver for Samsung S3C24XX series ARM SoCs ++ ++config SPI_S3C24XX_FIQ ++ bool "S3C24XX driver with FIQ pseudo-DMA" ++ depends on SPI_S3C24XX ++ select FIQ ++ help ++ Enable FIQ support for the S3C24XX SPI driver to provide pseudo ++ DMA by using the fast-interrupt request framework, This allows ++ the driver to get DMA-like performance when there are either ++ no free DMA channels, or when doing transfers that required both ++ TX and RX data paths. ++ ++config SPI_S3C24XX_GPIO ++ tristate "Samsung S3C24XX series SPI by GPIO" ++ depends on ARCH_S3C2410 && EXPERIMENTAL ++ select SPI_BITBANG ++ help ++ SPI driver for Samsung S3C24XX series ARM SoCs using ++ GPIO lines to provide the SPI bus. This can be used where ++ the inbuilt hardware cannot provide the transfer mode, or ++ where the board is using non hardware connected pins. ++ ++config SPI_S3C64XX ++ tristate "Samsung S3C64XX series type SPI" ++ depends on (ARCH_S3C64XX || ARCH_S5P64X0) ++ select S3C64XX_DMA if ARCH_S3C64XX ++ help ++ SPI driver for Samsung S3C64XX and newer SoCs. ++ ++config SPI_SH_MSIOF ++ tristate "SuperH MSIOF SPI controller" ++ depends on SUPERH && HAVE_CLK ++ select SPI_BITBANG ++ help ++ SPI driver for SuperH MSIOF blocks. ++ ++config SPI_SH ++ tristate "SuperH SPI controller" ++ depends on SUPERH ++ help ++ SPI driver for SuperH SPI blocks. ++ ++config SPI_SH_SCI ++ tristate "SuperH SCI SPI controller" ++ depends on SUPERH ++ select SPI_BITBANG ++ help ++ SPI driver for SuperH SCI blocks. ++ ++config SPI_STMP3XXX ++ tristate "Freescale STMP37xx/378x SPI/SSP controller" ++ depends on ARCH_STMP3XXX && SPI_MASTER ++ help ++ SPI driver for Freescale STMP37xx/378x SoC SSP interface ++ ++config SPI_TEGRA ++ tristate "Nvidia Tegra SPI controller" ++ depends on ARCH_TEGRA ++ select TEGRA_SYSTEM_DMA ++ help ++ SPI driver for NVidia Tegra SoCs ++ ++config SPI_TI_SSP ++ tristate "TI Sequencer Serial Port - SPI Support" ++ depends on MFD_TI_SSP ++ help ++ This selects an SPI master implementation using a TI sequencer ++ serial port. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called ti-ssp-spi. ++ ++config SPI_TOPCLIFF_PCH ++ tristate "Topcliff PCH SPI Controller" ++ depends on PCI ++ help ++ SPI driver for the Topcliff PCH (Platform Controller Hub) SPI bus ++ used in some x86 embedded processors. ++ ++config SPI_TXX9 ++ tristate "Toshiba TXx9 SPI controller" ++ depends on GENERIC_GPIO && CPU_TX49XX ++ help ++ SPI driver for Toshiba TXx9 MIPS SoCs ++ ++config SPI_XILINX ++ tristate "Xilinx SPI controller common module" ++ depends on HAS_IOMEM && EXPERIMENTAL ++ select SPI_BITBANG ++ help ++ This exposes the SPI controller IP from the Xilinx EDK. ++ ++ See the "OPB Serial Peripheral Interface (SPI) (v1.00e)" ++ Product Specification document (DS464) for hardware details. ++ ++ Or for the DS570, see "XPS Serial Peripheral Interface (SPI) (v2.00b)" ++ ++config SPI_NUC900 ++ tristate "Nuvoton NUC900 series SPI" ++ depends on ARCH_W90X900 && EXPERIMENTAL ++ select SPI_BITBANG ++ help ++ SPI driver for Nuvoton NUC900 series ARM SoCs ++ ++# ++# Add new SPI master controllers in alphabetical order above this line ++# ++ ++config SPI_DESIGNWARE ++ tristate "DesignWare SPI controller core support" ++ depends on SPI_MASTER ++ help ++ general driver for SPI controller core from DesignWare ++ ++config SPI_DW_PCI ++ tristate "PCI interface driver for DW SPI core" ++ depends on SPI_DESIGNWARE && PCI ++ ++config SPI_DW_MID_DMA ++ bool "DMA support for DW SPI controller on Intel Moorestown platform" ++ depends on SPI_DW_PCI && INTEL_MID_DMAC ++ ++config SPI_DW_MMIO ++ tristate "Memory-mapped io interface driver for DW SPI core" ++ depends on SPI_DESIGNWARE && HAVE_CLK ++ ++# ++# There are lots of SPI device types, with sensors and memory ++# being probably the most widely used ones. ++# ++comment "SPI Protocol Masters" ++ ++config SPI_SPIDEV ++ tristate "User mode SPI device driver support" ++ depends on EXPERIMENTAL ++ help ++ This supports user mode SPI protocol drivers. ++ ++ Note that this application programming interface is EXPERIMENTAL ++ and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes. ++ ++config SPI_TLE62X0 ++ tristate "Infineon TLE62X0 (for power switching)" ++ depends on SYSFS ++ help ++ SPI driver for Infineon TLE62X0 series line driver chips, ++ such as the TLE6220, TLE6230 and TLE6240. This provides a ++ sysfs interface, with each line presented as a kind of GPIO ++ exposing both switch control and diagnostic feedback. ++ ++config SPI_RB4XX_CPLD ++ tristate "MikroTik RB4XX CPLD driver" ++ depends on AR71XX_MACH_RB4XX ++ help ++ SPI driver for the Xilinx CPLD chip present on the ++ MikroTik RB4xx boards. ++ ++# ++# Add new SPI protocol masters in alphabetical order above this line ++# ++ ++endif # SPI_MASTER ++ ++# (slave support would go here) ++ ++endif # SPI +diff -Nur linux-2.6.39.orig/drivers/spi/Makefile linux-2.6.39/drivers/spi/Makefile +--- linux-2.6.39.orig/drivers/spi/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/spi/Makefile 2011-08-23 15:10:24.199233941 +0200 +@@ -10,6 +10,7 @@ + + # SPI master controller drivers (bus) + obj-$(CONFIG_SPI_ALTERA) += spi_altera.o ++obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o + obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o + obj-$(CONFIG_SPI_ATH79) += ath79_spi.o + obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o +@@ -54,6 +55,7 @@ + obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o + obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o + obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o ++obj-$(CONFIG_SPI_RB4XX) += rb4xx_spi.o + + # special build for s3c24xx spi driver with fiq support + spi_s3c24xx_hw-y := spi_s3c24xx.o +@@ -62,6 +64,7 @@ + # ... add above this line ... + + # SPI protocol drivers (device/link on bus) ++obj-$(CONFIG_SPI_RB4XX_CPLD) += spi_rb4xx_cpld.o + obj-$(CONFIG_SPI_SPIDEV) += spidev.o + obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o + # ... add above this line ... +diff -Nur linux-2.6.39.orig/drivers/spi/Makefile.orig linux-2.6.39/drivers/spi/Makefile.orig +--- linux-2.6.39.orig/drivers/spi/Makefile.orig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/spi/Makefile.orig 2011-08-23 15:10:11.300479072 +0200 +@@ -0,0 +1,75 @@ ++# ++# Makefile for kernel SPI drivers. ++# ++ ++ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG ++ ++# small core, mostly translating board-specific ++# config declarations into driver model code ++obj-$(CONFIG_SPI_MASTER) += spi.o ++ ++# SPI master controller drivers (bus) ++obj-$(CONFIG_SPI_ALTERA) += spi_altera.o ++obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o ++obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o ++obj-$(CONFIG_SPI_ATH79) += ath79_spi.o ++obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o ++obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o ++obj-$(CONFIG_SPI_AU1550) += au1550_spi.o ++obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o ++obj-$(CONFIG_SPI_COLDFIRE_QSPI) += coldfire_qspi.o ++obj-$(CONFIG_SPI_DAVINCI) += davinci_spi.o ++obj-$(CONFIG_SPI_DESIGNWARE) += dw_spi.o ++obj-$(CONFIG_SPI_DW_PCI) += dw_spi_midpci.o ++dw_spi_midpci-objs := dw_spi_pci.o dw_spi_mid.o ++obj-$(CONFIG_SPI_DW_MMIO) += dw_spi_mmio.o ++obj-$(CONFIG_SPI_EP93XX) += ep93xx_spi.o ++obj-$(CONFIG_SPI_GPIO) += spi_gpio.o ++obj-$(CONFIG_SPI_IMX) += spi_imx.o ++obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o ++obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o ++obj-$(CONFIG_SPI_PXA2XX_PCI) += pxa2xx_spi_pci.o ++obj-$(CONFIG_SPI_OC_TINY) += spi_oc_tiny.o ++obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o ++obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o ++obj-$(CONFIG_SPI_OMAP_100K) += omap_spi_100k.o ++obj-$(CONFIG_SPI_ORION) += orion_spi.o ++obj-$(CONFIG_SPI_PL022) += amba-pl022.o ++obj-$(CONFIG_SPI_MPC512x_PSC) += mpc512x_psc_spi.o ++obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o ++obj-$(CONFIG_SPI_MPC52xx) += mpc52xx_spi.o ++obj-$(CONFIG_SPI_FSL_LIB) += spi_fsl_lib.o ++obj-$(CONFIG_SPI_FSL_ESPI) += spi_fsl_espi.o ++obj-$(CONFIG_SPI_FSL_SPI) += spi_fsl_spi.o ++obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o ++obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o ++obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o ++obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o ++obj-$(CONFIG_SPI_TEGRA) += spi_tegra.o ++obj-$(CONFIG_SPI_TI_SSP) += ti-ssp-spi.o ++obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi_topcliff_pch.o ++obj-$(CONFIG_SPI_TXX9) += spi_txx9.o ++obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o ++obj-$(CONFIG_SPI_SH) += spi_sh.o ++obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o ++obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o ++obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o ++obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o ++ ++# special build for s3c24xx spi driver with fiq support ++spi_s3c24xx_hw-y := spi_s3c24xx.o ++spi_s3c24xx_hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi_s3c24xx_fiq.o ++ ++# ... add above this line ... ++ ++# SPI protocol drivers (device/link on bus) ++obj-$(CONFIG_SPI_RB4XX_CPLD) += spi_rb4xx_cpld.o ++obj-$(CONFIG_SPI_SPIDEV) += spidev.o ++obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o ++# ... add above this line ... ++ ++# SPI slave controller drivers (upstream link) ++# ... add above this line ... ++ ++# SPI slave drivers (protocol for that link) ++# ... add above this line ... +diff -Nur linux-2.6.39.orig/drivers/spi/pb44_spi.c linux-2.6.39/drivers/spi/pb44_spi.c +--- linux-2.6.39.orig/drivers/spi/pb44_spi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/spi/pb44_spi.c 2011-04-27 12:19:22.317665385 +0200 +@@ -0,0 +1,299 @@ ++/* ++ * Atheros PB44 board SPI controller driver ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define DRV_DESC "Atheros PB44 SPI Controller driver" ++#define DRV_VERSION "0.1.0" ++#define DRV_NAME "pb44-spi" ++ ++#undef PER_BIT_READ ++ ++struct ar71xx_spi { ++ struct spi_bitbang bitbang; ++ u32 ioc_base; ++ u32 reg_ctrl; ++ ++ void __iomem *base; ++ ++ struct platform_device *pdev; ++}; ++ ++static inline u32 pb44_spi_rr(struct ar71xx_spi *sp, unsigned reg) ++{ ++ return __raw_readl(sp->base + reg); ++} ++ ++static inline void pb44_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val) ++{ ++ __raw_writel(val, sp->base + reg); ++} ++ ++static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi) ++{ ++ return spi_master_get_devdata(spi->master); ++} ++ ++static void pb44_spi_chipselect(struct spi_device *spi, int is_active) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active; ++ ++ if (is_active) { ++ /* set initial clock polarity */ ++ if (spi->mode & SPI_CPOL) ++ sp->ioc_base |= SPI_IOC_CLK; ++ else ++ sp->ioc_base &= ~SPI_IOC_CLK; ++ ++ pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base); ++ } ++ ++ if (spi->chip_select) { ++ unsigned long gpio = (unsigned long) spi->controller_data; ++ ++ /* SPI is normally active-low */ ++ gpio_set_value(gpio, cs_high); ++ } else { ++ if (cs_high) ++ sp->ioc_base |= SPI_IOC_CS0; ++ else ++ sp->ioc_base &= ~SPI_IOC_CS0; ++ ++ pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base); ++ } ++ ++} ++ ++static int pb44_spi_setup_cs(struct spi_device *spi) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ ++ /* enable GPIO mode */ ++ pb44_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO); ++ ++ /* save CTRL register */ ++ sp->reg_ctrl = pb44_spi_rr(sp, SPI_REG_CTRL); ++ sp->ioc_base = pb44_spi_rr(sp, SPI_REG_IOC); ++ ++ /* TODO: setup speed? */ ++ pb44_spi_wr(sp, SPI_REG_CTRL, 0x43); ++ ++ if (spi->chip_select) { ++ unsigned long gpio = (unsigned long) spi->controller_data; ++ int status = 0; ++ ++ status = gpio_request(gpio, dev_name(&spi->dev)); ++ if (status) ++ return status; ++ ++ status = gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH); ++ if (status) { ++ gpio_free(gpio); ++ return status; ++ } ++ } else { ++ if (spi->mode & SPI_CS_HIGH) ++ sp->ioc_base |= SPI_IOC_CS0; ++ else ++ sp->ioc_base &= ~SPI_IOC_CS0; ++ pb44_spi_wr(sp, SPI_REG_IOC, sp->ioc_base); ++ } ++ ++ return 0; ++} ++ ++static void pb44_spi_cleanup_cs(struct spi_device *spi) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ ++ if (spi->chip_select) { ++ unsigned long gpio = (unsigned long) spi->controller_data; ++ gpio_free(gpio); ++ } ++ ++ /* restore CTRL register */ ++ pb44_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl); ++ /* disable GPIO mode */ ++ pb44_spi_wr(sp, SPI_REG_FS, 0); ++} ++ ++static int pb44_spi_setup(struct spi_device *spi) ++{ ++ int status = 0; ++ ++ if (spi->bits_per_word > 32) ++ return -EINVAL; ++ ++ if (!spi->controller_state) { ++ status = pb44_spi_setup_cs(spi); ++ if (status) ++ return status; ++ } ++ ++ status = spi_bitbang_setup(spi); ++ if (status && !spi->controller_state) ++ pb44_spi_cleanup_cs(spi); ++ ++ return status; ++} ++ ++static void pb44_spi_cleanup(struct spi_device *spi) ++{ ++ pb44_spi_cleanup_cs(spi); ++ spi_bitbang_cleanup(spi); ++} ++ ++static u32 pb44_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs, ++ u32 word, u8 bits) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ u32 ioc = sp->ioc_base; ++ u32 ret; ++ ++ /* clock starts at inactive polarity */ ++ for (word <<= (32 - bits); likely(bits); bits--) { ++ u32 out; ++ ++ if (word & (1 << 31)) ++ out = ioc | SPI_IOC_DO; ++ else ++ out = ioc & ~SPI_IOC_DO; ++ ++ /* setup MSB (to slave) on trailing edge */ ++ pb44_spi_wr(sp, SPI_REG_IOC, out); ++ pb44_spi_wr(sp, SPI_REG_IOC, out | SPI_IOC_CLK); ++ ++ word <<= 1; ++ ++#ifdef PER_BIT_READ ++ /* sample MSB (from slave) on leading edge */ ++ ret = pb44_spi_rr(sp, SPI_REG_RDS); ++ pb44_spi_wr(sp, SPI_REG_IOC, out); ++#endif ++ } ++ ++#ifndef PER_BIT_READ ++ ret = pb44_spi_rr(sp, SPI_REG_RDS); ++#endif ++ return ret; ++} ++ ++static int pb44_spi_probe(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct ar71xx_spi *sp; ++ struct ar71xx_spi_platform_data *pdata; ++ struct resource *r; ++ int ret; ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(*sp)); ++ if (master == NULL) { ++ dev_err(&pdev->dev, "failed to allocate spi master\n"); ++ return -ENOMEM; ++ } ++ ++ sp = spi_master_get_devdata(master); ++ platform_set_drvdata(pdev, sp); ++ ++ pdata = pdev->dev.platform_data; ++ ++ master->setup = pb44_spi_setup; ++ master->cleanup = pb44_spi_cleanup; ++ if (pdata) { ++ master->bus_num = pdata->bus_num; ++ master->num_chipselect = pdata->num_chipselect; ++ } else { ++ master->bus_num = 0; ++ master->num_chipselect = 1; ++ } ++ ++ sp->bitbang.master = spi_master_get(master); ++ sp->bitbang.chipselect = pb44_spi_chipselect; ++ sp->bitbang.txrx_word[SPI_MODE_0] = pb44_spi_txrx_mode0; ++ sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; ++ sp->bitbang.flags = SPI_CS_HIGH; ++ ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (r == NULL) { ++ ret = -ENOENT; ++ goto err1; ++ } ++ ++ sp->base = ioremap_nocache(r->start, r->end - r->start + 1); ++ if (!sp->base) { ++ ret = -ENXIO; ++ goto err1; ++ } ++ ++ ret = spi_bitbang_start(&sp->bitbang); ++ if (!ret) ++ return 0; ++ ++ iounmap(sp->base); ++err1: ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(sp->bitbang.master); ++ ++ return ret; ++} ++ ++static int pb44_spi_remove(struct platform_device *pdev) ++{ ++ struct ar71xx_spi *sp = platform_get_drvdata(pdev); ++ ++ spi_bitbang_stop(&sp->bitbang); ++ iounmap(sp->base); ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(sp->bitbang.master); ++ ++ return 0; ++} ++ ++static struct platform_driver pb44_spi_drv = { ++ .probe = pb44_spi_probe, ++ .remove = pb44_spi_remove, ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init pb44_spi_init(void) ++{ ++ return platform_driver_register(&pb44_spi_drv); ++} ++module_init(pb44_spi_init); ++ ++static void __exit pb44_spi_exit(void) ++{ ++ platform_driver_unregister(&pb44_spi_drv); ++} ++module_exit(pb44_spi_exit); ++ ++MODULE_ALIAS("platform:" DRV_NAME); ++MODULE_DESCRIPTION(DRV_DESC); ++MODULE_VERSION(DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-2.6.39.orig/drivers/spi/rb4xx_spi.c linux-2.6.39/drivers/spi/rb4xx_spi.c +--- linux-2.6.39.orig/drivers/spi/rb4xx_spi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/spi/rb4xx_spi.c 2011-04-27 12:19:22.307664943 +0200 +@@ -0,0 +1,474 @@ ++/* ++ * SPI controller driver for the Mikrotik RB4xx boards ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This file was based on the patches for Linux 2.6.27.39 published by ++ * MikroTik for their RouterBoard 4xx series devices. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define DRV_NAME "rb4xx-spi" ++#define DRV_DESC "Mikrotik RB4xx SPI controller driver" ++#define DRV_VERSION "0.1.0" ++ ++#define SPI_CTRL_FASTEST 0x40 ++#define SPI_FLASH_HZ 33333334 ++#define SPI_CPLD_HZ 33333334 ++ ++#define CPLD_CMD_READ_FAST 0x0b ++ ++#undef RB4XX_SPI_DEBUG ++ ++struct rb4xx_spi { ++ void __iomem *base; ++ struct spi_master *master; ++ ++ unsigned spi_ctrl_flash; ++ unsigned spi_ctrl_fread; ++ ++ spinlock_t lock; ++ struct list_head queue; ++ int busy:1; ++ int cs_wait; ++}; ++ ++static unsigned spi_clk_low = SPI_IOC_CS1; ++ ++#ifdef RB4XX_SPI_DEBUG ++static inline void do_spi_delay(void) ++{ ++ ndelay(20000); ++} ++#else ++static inline void do_spi_delay(void) { } ++#endif ++ ++static inline void do_spi_init(struct spi_device *spi) ++{ ++ unsigned cs = SPI_IOC_CS0 | SPI_IOC_CS1; ++ ++ if (!(spi->mode & SPI_CS_HIGH)) ++ cs ^= (spi->chip_select == 2) ? SPI_IOC_CS1 : SPI_IOC_CS0; ++ ++ spi_clk_low = cs; ++} ++ ++static inline void do_spi_finish(void __iomem *base) ++{ ++ do_spi_delay(); ++ __raw_writel(SPI_IOC_CS0 | SPI_IOC_CS1, base + SPI_REG_IOC); ++} ++ ++static inline void do_spi_clk(void __iomem *base, int bit) ++{ ++ unsigned bval = spi_clk_low | ((bit & 1) ? SPI_IOC_DO : 0); ++ ++ do_spi_delay(); ++ __raw_writel(bval, base + SPI_REG_IOC); ++ do_spi_delay(); ++ __raw_writel(bval | SPI_IOC_CLK, base + SPI_REG_IOC); ++} ++ ++static void do_spi_byte(void __iomem *base, unsigned char byte) ++{ ++ do_spi_clk(base, byte >> 7); ++ do_spi_clk(base, byte >> 6); ++ do_spi_clk(base, byte >> 5); ++ do_spi_clk(base, byte >> 4); ++ do_spi_clk(base, byte >> 3); ++ do_spi_clk(base, byte >> 2); ++ do_spi_clk(base, byte >> 1); ++ do_spi_clk(base, byte); ++ ++ pr_debug("spi_byte sent 0x%02x got 0x%02x\n", ++ (unsigned)byte, ++ (unsigned char)__raw_readl(base + SPI_REG_RDS)); ++} ++ ++static inline void do_spi_clk_fast(void __iomem *base, unsigned bit1, ++ unsigned bit2) ++{ ++ unsigned bval = (spi_clk_low | ++ ((bit1 & 1) ? SPI_IOC_DO : 0) | ++ ((bit2 & 1) ? SPI_IOC_CS2 : 0)); ++ do_spi_delay(); ++ __raw_writel(bval, base + SPI_REG_IOC); ++ do_spi_delay(); ++ __raw_writel(bval | SPI_IOC_CLK, base + SPI_REG_IOC); ++} ++ ++static void do_spi_byte_fast(void __iomem *base, unsigned char byte) ++{ ++ do_spi_clk_fast(base, byte >> 7, byte >> 6); ++ do_spi_clk_fast(base, byte >> 5, byte >> 4); ++ do_spi_clk_fast(base, byte >> 3, byte >> 2); ++ do_spi_clk_fast(base, byte >> 1, byte >> 0); ++ ++ pr_debug("spi_byte_fast sent 0x%02x got 0x%02x\n", ++ (unsigned)byte, ++ (unsigned char) __raw_readl(base + SPI_REG_RDS)); ++} ++ ++static int rb4xx_spi_txrx(void __iomem *base, struct spi_transfer *t) ++{ ++ const unsigned char *rxv_ptr = NULL; ++ const unsigned char *tx_ptr = t->tx_buf; ++ unsigned char *rx_ptr = t->rx_buf; ++ unsigned i; ++ ++ pr_debug("spi_txrx len %u tx %u rx %u\n", ++ t->len, ++ (t->tx_buf ? 1 : 0), ++ (t->rx_buf ? 1 : 0)); ++ ++ if (t->verify) { ++ rxv_ptr = tx_ptr; ++ tx_ptr = NULL; ++ } ++ ++ for (i = 0; i < t->len; ++i) { ++ unsigned char sdata = tx_ptr ? tx_ptr[i] : 0; ++ ++ if (t->fast_write) ++ do_spi_byte_fast(base, sdata); ++ else ++ do_spi_byte(base, sdata); ++ ++ if (rx_ptr) { ++ rx_ptr[i] = __raw_readl(base + SPI_REG_RDS) & 0xff; ++ } else if (rxv_ptr) { ++ unsigned char c = __raw_readl(base + SPI_REG_RDS); ++ if (rxv_ptr[i] != c) ++ return i; ++ } ++ } ++ ++ return i; ++} ++ ++static int rb4xx_spi_read_fast(struct rb4xx_spi *rbspi, ++ struct spi_message *m) ++{ ++ struct spi_transfer *t; ++ const unsigned char *tx_ptr; ++ unsigned addr; ++ void __iomem *base = rbspi->base; ++ ++ /* check for exactly two transfers */ ++ if (list_empty(&m->transfers) || ++ list_is_last(m->transfers.next, &m->transfers) || ++ !list_is_last(m->transfers.next->next, &m->transfers)) { ++ return -1; ++ } ++ ++ /* first transfer contains command and address */ ++ t = list_entry(m->transfers.next, ++ struct spi_transfer, transfer_list); ++ ++ if (t->len != 5 || t->tx_buf == NULL) ++ return -1; ++ ++ tx_ptr = t->tx_buf; ++ if (tx_ptr[0] != CPLD_CMD_READ_FAST) ++ return -1; ++ ++ addr = tx_ptr[1]; ++ addr = tx_ptr[2] | (addr << 8); ++ addr = tx_ptr[3] | (addr << 8); ++ addr += (unsigned) base; ++ ++ m->actual_length += t->len; ++ ++ /* second transfer contains data itself */ ++ t = list_entry(m->transfers.next->next, ++ struct spi_transfer, transfer_list); ++ ++ if (t->tx_buf && !t->verify) ++ return -1; ++ ++ __raw_writel(SPI_FS_GPIO, base + SPI_REG_FS); ++ __raw_writel(rbspi->spi_ctrl_fread, base + SPI_REG_CTRL); ++ __raw_writel(0, base + SPI_REG_FS); ++ ++ if (t->rx_buf) { ++ memcpy(t->rx_buf, (const void *)addr, t->len); ++ } else if (t->tx_buf) { ++ unsigned char buf[t->len]; ++ memcpy(buf, (const void *)addr, t->len); ++ if (memcmp(t->tx_buf, buf, t->len) != 0) ++ m->status = -EMSGSIZE; ++ } ++ m->actual_length += t->len; ++ ++ if (rbspi->spi_ctrl_flash != rbspi->spi_ctrl_fread) { ++ __raw_writel(SPI_FS_GPIO, base + SPI_REG_FS); ++ __raw_writel(rbspi->spi_ctrl_flash, base + SPI_REG_CTRL); ++ __raw_writel(0, base + SPI_REG_FS); ++ } ++ ++ return 0; ++} ++ ++static int rb4xx_spi_msg(struct rb4xx_spi *rbspi, struct spi_message *m) ++{ ++ struct spi_transfer *t = NULL; ++ void __iomem *base = rbspi->base; ++ ++ m->status = 0; ++ if (list_empty(&m->transfers)) ++ return -1; ++ ++ if (m->fast_read) ++ if (rb4xx_spi_read_fast(rbspi, m) == 0) ++ return -1; ++ ++ __raw_writel(SPI_FS_GPIO, base + SPI_REG_FS); ++ __raw_writel(SPI_CTRL_FASTEST, base + SPI_REG_CTRL); ++ do_spi_init(m->spi); ++ ++ list_for_each_entry(t, &m->transfers, transfer_list) { ++ int len; ++ ++ len = rb4xx_spi_txrx(base, t); ++ if (len != t->len) { ++ m->status = -EMSGSIZE; ++ break; ++ } ++ m->actual_length += len; ++ ++ if (t->cs_change) { ++ if (list_is_last(&t->transfer_list, &m->transfers)) { ++ /* wait for continuation */ ++ return m->spi->chip_select; ++ } ++ do_spi_finish(base); ++ ndelay(100); ++ } ++ } ++ ++ do_spi_finish(base); ++ __raw_writel(rbspi->spi_ctrl_flash, base + SPI_REG_CTRL); ++ __raw_writel(0, base + SPI_REG_FS); ++ return -1; ++} ++ ++static void rb4xx_spi_process_queue_locked(struct rb4xx_spi *rbspi, ++ unsigned long *flags) ++{ ++ int cs = rbspi->cs_wait; ++ ++ rbspi->busy = 1; ++ while (!list_empty(&rbspi->queue)) { ++ struct spi_message *m; ++ ++ list_for_each_entry(m, &rbspi->queue, queue) ++ if (cs < 0 || cs == m->spi->chip_select) ++ break; ++ ++ if (&m->queue == &rbspi->queue) ++ break; ++ ++ list_del_init(&m->queue); ++ spin_unlock_irqrestore(&rbspi->lock, *flags); ++ ++ cs = rb4xx_spi_msg(rbspi, m); ++ m->complete(m->context); ++ ++ spin_lock_irqsave(&rbspi->lock, *flags); ++ } ++ ++ rbspi->cs_wait = cs; ++ rbspi->busy = 0; ++ ++ if (cs >= 0) { ++ /* TODO: add timer to unlock cs after 1s inactivity */ ++ } ++} ++ ++static int rb4xx_spi_transfer(struct spi_device *spi, ++ struct spi_message *m) ++{ ++ struct rb4xx_spi *rbspi = spi_master_get_devdata(spi->master); ++ unsigned long flags; ++ ++ m->actual_length = 0; ++ m->status = -EINPROGRESS; ++ ++ spin_lock_irqsave(&rbspi->lock, flags); ++ list_add_tail(&m->queue, &rbspi->queue); ++ if (rbspi->busy || ++ (rbspi->cs_wait >= 0 && rbspi->cs_wait != m->spi->chip_select)) { ++ /* job will be done later */ ++ spin_unlock_irqrestore(&rbspi->lock, flags); ++ return 0; ++ } ++ ++ /* process job in current context */ ++ rb4xx_spi_process_queue_locked(rbspi, &flags); ++ spin_unlock_irqrestore(&rbspi->lock, flags); ++ ++ return 0; ++} ++ ++static int rb4xx_spi_setup(struct spi_device *spi) ++{ ++ struct rb4xx_spi *rbspi = spi_master_get_devdata(spi->master); ++ unsigned long flags; ++ ++ if (spi->mode & ~(SPI_CS_HIGH)) { ++ dev_err(&spi->dev, "mode %x not supported\n", ++ (unsigned) spi->mode); ++ return -EINVAL; ++ } ++ ++ if (spi->bits_per_word != 8 && spi->bits_per_word != 0) { ++ dev_err(&spi->dev, "bits_per_word %u not supported\n", ++ (unsigned) spi->bits_per_word); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&rbspi->lock, flags); ++ if (rbspi->cs_wait == spi->chip_select && !rbspi->busy) { ++ rbspi->cs_wait = -1; ++ rb4xx_spi_process_queue_locked(rbspi, &flags); ++ } ++ spin_unlock_irqrestore(&rbspi->lock, flags); ++ ++ return 0; ++} ++ ++static unsigned get_spi_ctrl(unsigned hz_max, const char *name) ++{ ++ unsigned div; ++ ++ div = (ar71xx_ahb_freq - 1) / (2 * hz_max); ++ ++ /* ++ * CPU has a bug at (div == 0) - first bit read is random ++ */ ++ if (div == 0) ++ ++div; ++ ++ if (name) { ++ unsigned ahb_khz = (ar71xx_ahb_freq + 500) / 1000; ++ unsigned div_real = 2 * (div + 1); ++ pr_debug("rb4xx: %s SPI clock %u kHz (AHB %u kHz / %u)\n", ++ name, ++ ahb_khz / div_real, ++ ahb_khz, div_real); ++ } ++ ++ return SPI_CTRL_FASTEST + div; ++} ++ ++static int rb4xx_spi_probe(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct rb4xx_spi *rbspi; ++ struct resource *r; ++ int err = 0; ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(*rbspi)); ++ if (master == NULL) { ++ dev_err(&pdev->dev, "no memory for spi_master\n"); ++ err = -ENOMEM; ++ goto err_out; ++ } ++ ++ master->bus_num = 0; ++ master->num_chipselect = 3; ++ master->setup = rb4xx_spi_setup; ++ master->transfer = rb4xx_spi_transfer; ++ ++ rbspi = spi_master_get_devdata(master); ++ platform_set_drvdata(pdev, rbspi); ++ ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (r == NULL) { ++ err = -ENOENT; ++ goto err_put_master; ++ } ++ ++ rbspi->base = ioremap(r->start, r->end - r->start + 1); ++ if (!rbspi->base) { ++ err = -ENXIO; ++ goto err_put_master; ++ } ++ ++ rbspi->master = master; ++ rbspi->spi_ctrl_flash = get_spi_ctrl(SPI_FLASH_HZ, "FLASH"); ++ rbspi->spi_ctrl_fread = get_spi_ctrl(SPI_CPLD_HZ, "CPLD"); ++ rbspi->cs_wait = -1; ++ ++ spin_lock_init(&rbspi->lock); ++ INIT_LIST_HEAD(&rbspi->queue); ++ ++ err = spi_register_master(master); ++ if (err) { ++ dev_err(&pdev->dev, "failed to register SPI master\n"); ++ goto err_iounmap; ++ } ++ ++ return 0; ++ ++err_iounmap: ++ iounmap(rbspi->base); ++err_put_master: ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(master); ++err_out: ++ return err; ++} ++ ++static int rb4xx_spi_remove(struct platform_device *pdev) ++{ ++ struct rb4xx_spi *rbspi = platform_get_drvdata(pdev); ++ ++ iounmap(rbspi->base); ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(rbspi->master); ++ ++ return 0; ++} ++ ++static struct platform_driver rb4xx_spi_drv = { ++ .probe = rb4xx_spi_probe, ++ .remove = rb4xx_spi_remove, ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init rb4xx_spi_init(void) ++{ ++ return platform_driver_register(&rb4xx_spi_drv); ++} ++subsys_initcall(rb4xx_spi_init); ++ ++static void __exit rb4xx_spi_exit(void) ++{ ++ platform_driver_unregister(&rb4xx_spi_drv); ++} ++ ++module_exit(rb4xx_spi_exit); ++ ++MODULE_DESCRIPTION(DRV_DESC); ++MODULE_VERSION(DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-2.6.39.orig/drivers/spi/spi_rb4xx_cpld.c linux-2.6.39/drivers/spi/spi_rb4xx_cpld.c +--- linux-2.6.39.orig/drivers/spi/spi_rb4xx_cpld.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/spi/spi_rb4xx_cpld.c 2011-04-27 12:19:22.317665385 +0200 +@@ -0,0 +1,440 @@ ++/* ++ * SPI driver for the CPLD chip on the Mikrotik RB4xx boards ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This file was based on the patches for Linux 2.6.27.39 published by ++ * MikroTik for their RouterBoard 4xx series devices. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define DRV_NAME "spi-rb4xx-cpld" ++#define DRV_DESC "RB4xx CPLD driver" ++#define DRV_VERSION "0.1.0" ++ ++#define CPLD_CMD_WRITE_NAND 0x08 /* send cmd, n x send data, send indle */ ++#define CPLD_CMD_WRITE_CFG 0x09 /* send cmd, n x send cfg */ ++#define CPLD_CMD_READ_NAND 0x0a /* send cmd, send idle, n x read data */ ++#define CPLD_CMD_READ_FAST 0x0b /* send cmd, 4 x idle, n x read data */ ++#define CPLD_CMD_LED5_ON 0x0c /* send cmd */ ++#define CPLD_CMD_LED5_OFF 0x0d /* send cmd */ ++ ++struct rb4xx_cpld { ++ struct spi_device *spi; ++ struct mutex lock; ++ struct gpio_chip chip; ++ unsigned int config; ++}; ++ ++static struct rb4xx_cpld *rb4xx_cpld; ++ ++static inline struct rb4xx_cpld *gpio_to_cpld(struct gpio_chip *chip) ++{ ++ return container_of(chip, struct rb4xx_cpld, chip); ++} ++ ++static int rb4xx_cpld_write_cmd(struct rb4xx_cpld *cpld, unsigned char cmd) ++{ ++ struct spi_transfer t[1]; ++ struct spi_message m; ++ unsigned char tx_buf[1]; ++ int err; ++ ++ spi_message_init(&m); ++ memset(&t, 0, sizeof(t)); ++ ++ t[0].tx_buf = tx_buf; ++ t[0].len = sizeof(tx_buf); ++ spi_message_add_tail(&t[0], &m); ++ ++ tx_buf[0] = cmd; ++ ++ err = spi_sync(cpld->spi, &m); ++ return err; ++} ++ ++static int rb4xx_cpld_write_cfg(struct rb4xx_cpld *cpld, unsigned char config) ++{ ++ struct spi_transfer t[1]; ++ struct spi_message m; ++ unsigned char cmd[2]; ++ int err; ++ ++ spi_message_init(&m); ++ memset(&t, 0, sizeof(t)); ++ ++ t[0].tx_buf = cmd; ++ t[0].len = sizeof(cmd); ++ spi_message_add_tail(&t[0], &m); ++ ++ cmd[0] = CPLD_CMD_WRITE_CFG; ++ cmd[1] = config; ++ ++ err = spi_sync(cpld->spi, &m); ++ return err; ++} ++ ++static int __rb4xx_cpld_change_cfg(struct rb4xx_cpld *cpld, unsigned mask, ++ unsigned value) ++{ ++ unsigned int config; ++ int err; ++ ++ config = cpld->config & ~mask; ++ config |= value; ++ ++ if ((cpld->config ^ config) & 0xff) { ++ err = rb4xx_cpld_write_cfg(cpld, config); ++ if (err) ++ return err; ++ } ++ ++ if ((cpld->config ^ config) & CPLD_CFG_nLED5) { ++ err = rb4xx_cpld_write_cmd(cpld, (value) ? CPLD_CMD_LED5_ON : ++ CPLD_CMD_LED5_OFF); ++ if (err) ++ return err; ++ } ++ ++ cpld->config = config; ++ return 0; ++} ++ ++int rb4xx_cpld_change_cfg(unsigned mask, unsigned value) ++{ ++ int ret; ++ ++ if (rb4xx_cpld == NULL) ++ return -ENODEV; ++ ++ mutex_lock(&rb4xx_cpld->lock); ++ ret = __rb4xx_cpld_change_cfg(rb4xx_cpld, mask, value); ++ mutex_unlock(&rb4xx_cpld->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(rb4xx_cpld_change_cfg); ++ ++int rb4xx_cpld_read_from(unsigned addr, unsigned char *rx_buf, ++ const unsigned char *verify_buf, unsigned count) ++{ ++ const unsigned char cmd[5] = { ++ CPLD_CMD_READ_FAST, ++ (addr >> 16) & 0xff, ++ (addr >> 8) & 0xff, ++ addr & 0xff, ++ 0 ++ }; ++ struct spi_transfer t[2] = { ++ { ++ .tx_buf = &cmd, ++ .len = 5, ++ }, ++ { ++ .tx_buf = verify_buf, ++ .rx_buf = rx_buf, ++ .len = count, ++ .verify = (verify_buf != NULL), ++ }, ++ }; ++ struct spi_message m; ++ ++ if (rb4xx_cpld == NULL) ++ return -ENODEV; ++ ++ spi_message_init(&m); ++ m.fast_read = 1; ++ spi_message_add_tail(&t[0], &m); ++ spi_message_add_tail(&t[1], &m); ++ return spi_sync(rb4xx_cpld->spi, &m); ++} ++EXPORT_SYMBOL_GPL(rb4xx_cpld_read_from); ++ ++#if 0 ++int rb4xx_cpld_read(unsigned char *buf, unsigned char *verify_buf, ++ unsigned count) ++{ ++ struct spi_transfer t[2]; ++ struct spi_message m; ++ unsigned char cmd[2]; ++ ++ if (rb4xx_cpld == NULL) ++ return -ENODEV; ++ ++ spi_message_init(&m); ++ memset(&t, 0, sizeof(t)); ++ ++ /* send command */ ++ t[0].tx_buf = cmd; ++ t[0].len = sizeof(cmd); ++ spi_message_add_tail(&t[0], &m); ++ ++ cmd[0] = CPLD_CMD_READ_NAND; ++ cmd[1] = 0; ++ ++ /* read data */ ++ t[1].rx_buf = buf; ++ t[1].len = count; ++ spi_message_add_tail(&t[1], &m); ++ ++ return spi_sync(rb4xx_cpld->spi, &m); ++} ++#else ++int rb4xx_cpld_read(unsigned char *rx_buf, const unsigned char *verify_buf, ++ unsigned count) ++{ ++ static const unsigned char cmd[2] = { CPLD_CMD_READ_NAND, 0 }; ++ struct spi_transfer t[2] = { ++ { ++ .tx_buf = &cmd, ++ .len = 2, ++ }, { ++ .tx_buf = verify_buf, ++ .rx_buf = rx_buf, ++ .len = count, ++ .verify = (verify_buf != NULL), ++ }, ++ }; ++ struct spi_message m; ++ ++ if (rb4xx_cpld == NULL) ++ return -ENODEV; ++ ++ spi_message_init(&m); ++ spi_message_add_tail(&t[0], &m); ++ spi_message_add_tail(&t[1], &m); ++ return spi_sync(rb4xx_cpld->spi, &m); ++} ++#endif ++EXPORT_SYMBOL_GPL(rb4xx_cpld_read); ++ ++int rb4xx_cpld_write(const unsigned char *buf, unsigned count) ++{ ++#if 0 ++ struct spi_transfer t[3]; ++ struct spi_message m; ++ unsigned char cmd[1]; ++ ++ if (rb4xx_cpld == NULL) ++ return -ENODEV; ++ ++ memset(&t, 0, sizeof(t)); ++ spi_message_init(&m); ++ ++ /* send command */ ++ t[0].tx_buf = cmd; ++ t[0].len = sizeof(cmd); ++ spi_message_add_tail(&t[0], &m); ++ ++ cmd[0] = CPLD_CMD_WRITE_NAND; ++ ++ /* write data */ ++ t[1].tx_buf = buf; ++ t[1].len = count; ++ spi_message_add_tail(&t[1], &m); ++ ++ /* send idle */ ++ t[2].len = 1; ++ spi_message_add_tail(&t[2], &m); ++ ++ return spi_sync(rb4xx_cpld->spi, &m); ++#else ++ static const unsigned char cmd = CPLD_CMD_WRITE_NAND; ++ struct spi_transfer t[3] = { ++ { ++ .tx_buf = &cmd, ++ .len = 1, ++ }, { ++ .tx_buf = buf, ++ .len = count, ++ .fast_write = 1, ++ }, { ++ .len = 1, ++ .fast_write = 1, ++ }, ++ }; ++ struct spi_message m; ++ ++ if (rb4xx_cpld == NULL) ++ return -ENODEV; ++ ++ spi_message_init(&m); ++ spi_message_add_tail(&t[0], &m); ++ spi_message_add_tail(&t[1], &m); ++ spi_message_add_tail(&t[2], &m); ++ return spi_sync(rb4xx_cpld->spi, &m); ++#endif ++} ++EXPORT_SYMBOL_GPL(rb4xx_cpld_write); ++ ++static int rb4xx_cpld_gpio_get(struct gpio_chip *chip, unsigned offset) ++{ ++ struct rb4xx_cpld *cpld = gpio_to_cpld(chip); ++ int ret; ++ ++ mutex_lock(&cpld->lock); ++ ret = (cpld->config >> offset) & 1; ++ mutex_unlock(&cpld->lock); ++ ++ return ret; ++} ++ ++static void rb4xx_cpld_gpio_set(struct gpio_chip *chip, unsigned offset, ++ int value) ++{ ++ struct rb4xx_cpld *cpld = gpio_to_cpld(chip); ++ ++ mutex_lock(&cpld->lock); ++ __rb4xx_cpld_change_cfg(cpld, (1 << offset), !!value << offset); ++ mutex_unlock(&cpld->lock); ++} ++ ++static int rb4xx_cpld_gpio_direction_input(struct gpio_chip *chip, ++ unsigned offset) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static int rb4xx_cpld_gpio_direction_output(struct gpio_chip *chip, ++ unsigned offset, ++ int value) ++{ ++ struct rb4xx_cpld *cpld = gpio_to_cpld(chip); ++ int ret; ++ ++ mutex_lock(&cpld->lock); ++ ret = __rb4xx_cpld_change_cfg(cpld, (1 << offset), !!value << offset); ++ mutex_unlock(&cpld->lock); ++ ++ return ret; ++} ++ ++static int rb4xx_cpld_gpio_init(struct rb4xx_cpld *cpld, unsigned int base) ++{ ++ int err; ++ ++ /* init config */ ++ cpld->config = CPLD_CFG_nLED1 | CPLD_CFG_nLED2 | CPLD_CFG_nLED3 | ++ CPLD_CFG_nLED4 | CPLD_CFG_nCE; ++ rb4xx_cpld_write_cfg(cpld, cpld->config); ++ ++ /* setup GPIO chip */ ++ cpld->chip.label = DRV_NAME; ++ ++ cpld->chip.get = rb4xx_cpld_gpio_get; ++ cpld->chip.set = rb4xx_cpld_gpio_set; ++ cpld->chip.direction_input = rb4xx_cpld_gpio_direction_input; ++ cpld->chip.direction_output = rb4xx_cpld_gpio_direction_output; ++ ++ cpld->chip.base = base; ++ cpld->chip.ngpio = CPLD_NUM_GPIOS; ++ cpld->chip.can_sleep = 1; ++ cpld->chip.dev = &cpld->spi->dev; ++ cpld->chip.owner = THIS_MODULE; ++ ++ err = gpiochip_add(&cpld->chip); ++ if (err) ++ dev_err(&cpld->spi->dev, "adding GPIO chip failed, err=%d\n", ++ err); ++ ++ return err; ++} ++ ++static int __devinit rb4xx_cpld_probe(struct spi_device *spi) ++{ ++ struct rb4xx_cpld *cpld; ++ struct rb4xx_cpld_platform_data *pdata; ++ int err; ++ ++ pdata = spi->dev.platform_data; ++ if (!pdata) { ++ dev_dbg(&spi->dev, "no platform data\n"); ++ return -EINVAL; ++ } ++ ++ cpld = kzalloc(sizeof(*cpld), GFP_KERNEL); ++ if (!cpld) { ++ dev_err(&spi->dev, "no memory for private data\n"); ++ return -ENOMEM; ++ } ++ ++ mutex_init(&cpld->lock); ++ cpld->spi = spi_dev_get(spi); ++ dev_set_drvdata(&spi->dev, cpld); ++ ++ spi->mode = SPI_MODE_0; ++ spi->bits_per_word = 8; ++ err = spi_setup(spi); ++ if (err) { ++ dev_err(&spi->dev, "spi_setup failed, err=%d\n", err); ++ goto err_drvdata; ++ } ++ ++ err = rb4xx_cpld_gpio_init(cpld, pdata->gpio_base); ++ if (err) ++ goto err_drvdata; ++ ++ rb4xx_cpld = cpld; ++ ++ return 0; ++ ++err_drvdata: ++ dev_set_drvdata(&spi->dev, NULL); ++ kfree(cpld); ++ ++ return err; ++} ++ ++static int __devexit rb4xx_cpld_remove(struct spi_device *spi) ++{ ++ struct rb4xx_cpld *cpld; ++ ++ rb4xx_cpld = NULL; ++ cpld = dev_get_drvdata(&spi->dev); ++ dev_set_drvdata(&spi->dev, NULL); ++ kfree(cpld); ++ ++ return 0; ++} ++ ++static struct spi_driver rb4xx_cpld_driver = { ++ .driver = { ++ .name = DRV_NAME, ++ .bus = &spi_bus_type, ++ .owner = THIS_MODULE, ++ }, ++ .probe = rb4xx_cpld_probe, ++ .remove = __devexit_p(rb4xx_cpld_remove), ++}; ++ ++static int __init rb4xx_cpld_init(void) ++{ ++ return spi_register_driver(&rb4xx_cpld_driver); ++} ++module_init(rb4xx_cpld_init); ++ ++static void __exit rb4xx_cpld_exit(void) ++{ ++ spi_unregister_driver(&rb4xx_cpld_driver); ++} ++module_exit(rb4xx_cpld_exit); ++ ++MODULE_DESCRIPTION(DRV_DESC); ++MODULE_VERSION(DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-2.6.39.orig/drivers/spi/spi_vsc7385.c linux-2.6.39/drivers/spi/spi_vsc7385.c +--- linux-2.6.39.orig/drivers/spi/spi_vsc7385.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/spi/spi_vsc7385.c 2011-04-27 12:19:22.317665385 +0200 +@@ -0,0 +1,621 @@ ++/* ++ * SPI driver for the Vitesse VSC7385 ethernet switch ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRV_NAME "spi-vsc7385" ++#define DRV_DESC "Vitesse VSC7385 Gbit ethernet switch driver" ++#define DRV_VERSION "0.1.0" ++ ++#define VSC73XX_BLOCK_MAC 0x1 ++#define VSC73XX_BLOCK_2 0x2 ++#define VSC73XX_BLOCK_MII 0x3 ++#define VSC73XX_BLOCK_4 0x4 ++#define VSC73XX_BLOCK_5 0x5 ++#define VSC73XX_BLOCK_SYSTEM 0x7 ++ ++#define VSC73XX_SUBBLOCK_PORT_0 0 ++#define VSC73XX_SUBBLOCK_PORT_1 1 ++#define VSC73XX_SUBBLOCK_PORT_2 2 ++#define VSC73XX_SUBBLOCK_PORT_3 3 ++#define VSC73XX_SUBBLOCK_PORT_4 4 ++#define VSC73XX_SUBBLOCK_PORT_MAC 6 ++ ++/* MAC Block registers */ ++#define VSC73XX_MAC_CFG 0x0 ++#define VSC73XX_ADVPORTM 0x19 ++#define VSC73XX_RXOCT 0x50 ++#define VSC73XX_TXOCT 0x51 ++#define VSC73XX_C_RX0 0x52 ++#define VSC73XX_C_RX1 0x53 ++#define VSC73XX_C_RX2 0x54 ++#define VSC73XX_C_TX0 0x55 ++#define VSC73XX_C_TX1 0x56 ++#define VSC73XX_C_TX2 0x57 ++#define VSC73XX_C_CFG 0x58 ++ ++/* MAC_CFG register bits */ ++#define VSC73XX_MAC_CFG_WEXC_DIS (1 << 31) ++#define VSC73XX_MAC_CFG_PORT_RST (1 << 29) ++#define VSC73XX_MAC_CFG_TX_EN (1 << 28) ++#define VSC73XX_MAC_CFG_SEED_LOAD (1 << 27) ++#define VSC73XX_MAC_CFG_FDX (1 << 18) ++#define VSC73XX_MAC_CFG_GIGE (1 << 17) ++#define VSC73XX_MAC_CFG_RX_EN (1 << 16) ++#define VSC73XX_MAC_CFG_VLAN_DBLAWR (1 << 15) ++#define VSC73XX_MAC_CFG_VLAN_AWR (1 << 14) ++#define VSC73XX_MAC_CFG_100_BASE_T (1 << 13) ++#define VSC73XX_MAC_CFG_TX_IPG(x) (((x) & 0x1f) << 6) ++#define VSC73XX_MAC_CFG_MAC_RX_RST (1 << 5) ++#define VSC73XX_MAC_CFG_MAC_TX_RST (1 << 4) ++#define VSC73XX_MAC_CFG_BIT2 (1 << 2) ++#define VSC73XX_MAC_CFG_CLK_SEL(x) ((x) & 0x3) ++ ++/* ADVPORTM register bits */ ++#define VSC73XX_ADVPORTM_IFG_PPM (1 << 7) ++#define VSC73XX_ADVPORTM_EXC_COL_CONT (1 << 6) ++#define VSC73XX_ADVPORTM_EXT_PORT (1 << 5) ++#define VSC73XX_ADVPORTM_INV_GTX (1 << 4) ++#define VSC73XX_ADVPORTM_ENA_GTX (1 << 3) ++#define VSC73XX_ADVPORTM_DDR_MODE (1 << 2) ++#define VSC73XX_ADVPORTM_IO_LOOPBACK (1 << 1) ++#define VSC73XX_ADVPORTM_HOST_LOOPBACK (1 << 0) ++ ++/* MII Block registers */ ++#define VSC73XX_MII_STAT 0x0 ++#define VSC73XX_MII_CMD 0x1 ++#define VSC73XX_MII_DATA 0x2 ++ ++/* System Block registers */ ++#define VSC73XX_ICPU_SIPAD 0x01 ++#define VSC73XX_ICPU_CLOCK_DELAY 0x05 ++#define VSC73XX_ICPU_CTRL 0x10 ++#define VSC73XX_ICPU_ADDR 0x11 ++#define VSC73XX_ICPU_SRAM 0x12 ++#define VSC73XX_ICPU_MBOX_VAL 0x15 ++#define VSC73XX_ICPU_MBOX_SET 0x16 ++#define VSC73XX_ICPU_MBOX_CLR 0x17 ++#define VSC73XX_ICPU_CHIPID 0x18 ++#define VSC73XX_ICPU_GPIO 0x34 ++ ++#define VSC73XX_ICPU_CTRL_CLK_DIV (1 << 8) ++#define VSC73XX_ICPU_CTRL_SRST_HOLD (1 << 7) ++#define VSC73XX_ICPU_CTRL_BOOT_EN (1 << 3) ++#define VSC73XX_ICPU_CTRL_EXT_ACC_EN (1 << 2) ++#define VSC73XX_ICPU_CTRL_CLK_EN (1 << 1) ++#define VSC73XX_ICPU_CTRL_SRST (1 << 0) ++ ++#define VSC73XX_ICPU_CHIPID_ID_SHIFT 12 ++#define VSC73XX_ICPU_CHIPID_ID_MASK 0xffff ++#define VSC73XX_ICPU_CHIPID_REV_SHIFT 28 ++#define VSC73XX_ICPU_CHIPID_REV_MASK 0xf ++#define VSC73XX_ICPU_CHIPID_ID_7385 0x7385 ++#define VSC73XX_ICPU_CHIPID_ID_7395 0x7395 ++ ++#define VSC73XX_CMD_MODE_READ 0 ++#define VSC73XX_CMD_MODE_WRITE 1 ++#define VSC73XX_CMD_MODE_SHIFT 4 ++#define VSC73XX_CMD_BLOCK_SHIFT 5 ++#define VSC73XX_CMD_BLOCK_MASK 0x7 ++#define VSC73XX_CMD_SUBBLOCK_MASK 0xf ++ ++#define VSC7385_CLOCK_DELAY ((3 << 4) | 3) ++#define VSC7385_CLOCK_DELAY_MASK ((3 << 4) | 3) ++ ++#define VSC73XX_ICPU_CTRL_STOP (VSC73XX_ICPU_CTRL_SRST_HOLD | \ ++ VSC73XX_ICPU_CTRL_BOOT_EN | \ ++ VSC73XX_ICPU_CTRL_EXT_ACC_EN) ++ ++#define VSC73XX_ICPU_CTRL_START (VSC73XX_ICPU_CTRL_CLK_DIV | \ ++ VSC73XX_ICPU_CTRL_BOOT_EN | \ ++ VSC73XX_ICPU_CTRL_CLK_EN | \ ++ VSC73XX_ICPU_CTRL_SRST) ++ ++#define VSC7385_ADVPORTM_MASK (VSC73XX_ADVPORTM_IFG_PPM | \ ++ VSC73XX_ADVPORTM_EXC_COL_CONT | \ ++ VSC73XX_ADVPORTM_EXT_PORT | \ ++ VSC73XX_ADVPORTM_INV_GTX | \ ++ VSC73XX_ADVPORTM_ENA_GTX | \ ++ VSC73XX_ADVPORTM_DDR_MODE | \ ++ VSC73XX_ADVPORTM_IO_LOOPBACK | \ ++ VSC73XX_ADVPORTM_HOST_LOOPBACK) ++ ++#define VSC7385_ADVPORTM_INIT (VSC73XX_ADVPORTM_EXT_PORT | \ ++ VSC73XX_ADVPORTM_ENA_GTX | \ ++ VSC73XX_ADVPORTM_DDR_MODE) ++ ++#define VSC7385_MAC_CFG_RESET (VSC73XX_MAC_CFG_PORT_RST | \ ++ VSC73XX_MAC_CFG_MAC_RX_RST | \ ++ VSC73XX_MAC_CFG_MAC_TX_RST) ++ ++#define VSC73XX_MAC_CFG_INIT (VSC73XX_MAC_CFG_TX_EN | \ ++ VSC73XX_MAC_CFG_FDX | \ ++ VSC73XX_MAC_CFG_GIGE | \ ++ VSC73XX_MAC_CFG_RX_EN) ++ ++#define VSC73XX_RESET_DELAY 100 ++ ++struct vsc7385 { ++ struct spi_device *spi; ++ struct mutex lock; ++ struct vsc7385_platform_data *pdata; ++}; ++ ++static int vsc7385_is_addr_valid(u8 block, u8 subblock) ++{ ++ switch (block) { ++ case VSC73XX_BLOCK_MAC: ++ switch (subblock) { ++ case 0 ... 4: ++ case 6: ++ return 1; ++ } ++ break; ++ ++ case VSC73XX_BLOCK_2: ++ case VSC73XX_BLOCK_SYSTEM: ++ switch (subblock) { ++ case 0: ++ return 1; ++ } ++ break; ++ ++ case VSC73XX_BLOCK_MII: ++ case VSC73XX_BLOCK_4: ++ case VSC73XX_BLOCK_5: ++ switch (subblock) { ++ case 0 ... 1: ++ return 1; ++ } ++ break; ++ } ++ ++ return 0; ++} ++ ++static inline u8 vsc7385_make_addr(u8 mode, u8 block, u8 subblock) ++{ ++ u8 ret; ++ ++ ret = (block & VSC73XX_CMD_BLOCK_MASK) << VSC73XX_CMD_BLOCK_SHIFT; ++ ret |= (mode & 1) << VSC73XX_CMD_MODE_SHIFT; ++ ret |= subblock & VSC73XX_CMD_SUBBLOCK_MASK; ++ ++ return ret; ++} ++ ++static int vsc7385_read(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg, ++ u32 *value) ++{ ++ u8 cmd[4]; ++ u8 buf[4]; ++ struct spi_transfer t[2]; ++ struct spi_message m; ++ int err; ++ ++ if (!vsc7385_is_addr_valid(block, subblock)) ++ return -EINVAL; ++ ++ spi_message_init(&m); ++ ++ memset(&t, 0, sizeof(t)); ++ ++ t[0].tx_buf = cmd; ++ t[0].len = sizeof(cmd); ++ spi_message_add_tail(&t[0], &m); ++ ++ t[1].rx_buf = buf; ++ t[1].len = sizeof(buf); ++ spi_message_add_tail(&t[1], &m); ++ ++ cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_READ, block, subblock); ++ cmd[1] = reg; ++ cmd[2] = 0; ++ cmd[3] = 0; ++ ++ mutex_lock(&vsc->lock); ++ err = spi_sync(vsc->spi, &m); ++ mutex_unlock(&vsc->lock); ++ ++ if (err) ++ return err; ++ ++ *value = (((u32) buf[0]) << 24) | (((u32) buf[1]) << 16) | ++ (((u32) buf[2]) << 8) | ((u32) buf[3]); ++ ++ return 0; ++} ++ ++ ++static int vsc7385_write(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg, ++ u32 value) ++{ ++ u8 cmd[2]; ++ u8 buf[4]; ++ struct spi_transfer t[2]; ++ struct spi_message m; ++ int err; ++ ++ if (!vsc7385_is_addr_valid(block, subblock)) ++ return -EINVAL; ++ ++ spi_message_init(&m); ++ ++ memset(&t, 0, sizeof(t)); ++ ++ t[0].tx_buf = cmd; ++ t[0].len = sizeof(cmd); ++ spi_message_add_tail(&t[0], &m); ++ ++ t[1].tx_buf = buf; ++ t[1].len = sizeof(buf); ++ spi_message_add_tail(&t[1], &m); ++ ++ cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_WRITE, block, subblock); ++ cmd[1] = reg; ++ ++ buf[0] = (value >> 24) & 0xff; ++ buf[1] = (value >> 16) & 0xff; ++ buf[2] = (value >> 8) & 0xff; ++ buf[3] = value & 0xff; ++ ++ mutex_lock(&vsc->lock); ++ err = spi_sync(vsc->spi, &m); ++ mutex_unlock(&vsc->lock); ++ ++ return err; ++} ++ ++static inline int vsc7385_write_verify(struct vsc7385 *vsc, u8 block, ++ u8 subblock, u8 reg, u32 value, ++ u32 read_mask, u32 read_val) ++{ ++ struct spi_device *spi = vsc->spi; ++ u32 t; ++ int err; ++ ++ err = vsc7385_write(vsc, block, subblock, reg, value); ++ if (err) ++ return err; ++ ++ err = vsc7385_read(vsc, block, subblock, reg, &t); ++ if (err) ++ return err; ++ ++ if ((t & read_mask) != read_val) { ++ dev_err(&spi->dev, "register write error\n"); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static inline int vsc7385_set_clock_delay(struct vsc7385 *vsc, u32 val) ++{ ++ return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, ++ VSC73XX_ICPU_CLOCK_DELAY, val); ++} ++ ++static inline int vsc7385_get_clock_delay(struct vsc7385 *vsc, u32 *val) ++{ ++ return vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, ++ VSC73XX_ICPU_CLOCK_DELAY, val); ++} ++ ++static inline int vsc7385_icpu_stop(struct vsc7385 *vsc) ++{ ++ return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL, ++ VSC73XX_ICPU_CTRL_STOP); ++} ++ ++static inline int vsc7385_icpu_start(struct vsc7385 *vsc) ++{ ++ return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL, ++ VSC73XX_ICPU_CTRL_START); ++} ++ ++static inline int vsc7385_icpu_reset(struct vsc7385 *vsc) ++{ ++ int rc; ++ ++ rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_ADDR, ++ 0x0000); ++ if (rc) ++ dev_err(&vsc->spi->dev, ++ "could not reset microcode, err=%d\n", rc); ++ ++ return rc; ++} ++ ++static int vsc7385_upload_ucode(struct vsc7385 *vsc) ++{ ++ struct spi_device *spi = vsc->spi; ++ const struct firmware *firmware; ++ char *ucode_name; ++ unsigned char *dp; ++ unsigned int curVal; ++ int i; ++ int diffs; ++ int rc; ++ ++ ucode_name = (vsc->pdata->ucode_name) ? vsc->pdata->ucode_name ++ : "vsc7385_ucode.bin"; ++ rc = request_firmware(&firmware, ucode_name, &spi->dev); ++ if (rc) { ++ dev_err(&spi->dev, "request_firmware failed, err=%d\n", ++ rc); ++ return rc; ++ } ++ ++ rc = vsc7385_icpu_stop(vsc); ++ if (rc) ++ goto out; ++ ++ rc = vsc7385_icpu_reset(vsc); ++ if (rc) ++ goto out; ++ ++ dev_info(&spi->dev, "uploading microcode...\n"); ++ ++ dp = (unsigned char *) firmware->data; ++ for (i = 0; i < firmware->size; i++) { ++ rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, ++ VSC73XX_ICPU_SRAM, *dp++); ++ if (rc) { ++ dev_err(&spi->dev, "could not load microcode, err=%d\n", ++ rc); ++ goto out; ++ } ++ } ++ ++ rc = vsc7385_icpu_reset(vsc); ++ if (rc) ++ goto out; ++ ++ dev_info(&spi->dev, "verifying microcode...\n"); ++ ++ dp = (unsigned char *) firmware->data; ++ diffs = 0; ++ for (i = 0; i < firmware->size; i++) { ++ rc = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, ++ VSC73XX_ICPU_SRAM, &curVal); ++ if (rc) { ++ dev_err(&spi->dev, "could not read microcode %d\n", ++ rc); ++ goto out; ++ } ++ ++ if (curVal > 0xff) { ++ dev_err(&spi->dev, "bad val read: %04x : %02x %02x\n", ++ i, *dp, curVal); ++ rc = -EIO; ++ goto out; ++ } ++ ++ if ((curVal & 0xff) != *dp) { ++ diffs++; ++ dev_err(&spi->dev, "verify error: %04x : %02x %02x\n", ++ i, *dp, curVal); ++ ++ if (diffs > 4) ++ break; ++ } ++ dp++; ++ } ++ ++ if (diffs) { ++ dev_err(&spi->dev, "microcode verification failed\n"); ++ rc = -EIO; ++ goto out; ++ } ++ ++ dev_info(&spi->dev, "microcode uploaded\n"); ++ ++ rc = vsc7385_icpu_start(vsc); ++ ++out: ++ release_firmware(firmware); ++ return rc; ++} ++ ++static int vsc7385_setup(struct vsc7385 *vsc) ++{ ++ struct vsc7385_platform_data *pdata = vsc->pdata; ++ u32 t; ++ int err; ++ ++ err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_SYSTEM, 0, ++ VSC73XX_ICPU_CLOCK_DELAY, ++ VSC7385_CLOCK_DELAY, ++ VSC7385_CLOCK_DELAY_MASK, ++ VSC7385_CLOCK_DELAY); ++ if (err) ++ goto err; ++ ++ err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_MAC, ++ VSC73XX_SUBBLOCK_PORT_MAC, VSC73XX_ADVPORTM, ++ VSC7385_ADVPORTM_INIT, ++ VSC7385_ADVPORTM_MASK, ++ VSC7385_ADVPORTM_INIT); ++ if (err) ++ goto err; ++ ++ err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC, ++ VSC73XX_MAC_CFG, VSC7385_MAC_CFG_RESET); ++ if (err) ++ goto err; ++ ++ t = VSC73XX_MAC_CFG_INIT; ++ t |= VSC73XX_MAC_CFG_TX_IPG(pdata->mac_cfg.tx_ipg); ++ t |= VSC73XX_MAC_CFG_CLK_SEL(pdata->mac_cfg.clk_sel); ++ if (pdata->mac_cfg.bit2) ++ t |= VSC73XX_MAC_CFG_BIT2; ++ ++ err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC, ++ VSC73XX_MAC_CFG, t); ++ if (err) ++ goto err; ++ ++ return 0; ++ ++err: ++ return err; ++} ++ ++static int vsc7385_detect(struct vsc7385 *vsc) ++{ ++ struct spi_device *spi = vsc->spi; ++ u32 t; ++ u32 id; ++ u32 rev; ++ int err; ++ ++ err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, ++ VSC73XX_ICPU_MBOX_VAL, &t); ++ if (err) { ++ dev_err(&spi->dev, "unable to read mailbox, err=%d\n", err); ++ return err; ++ } ++ ++ if (t == 0xffffffff) { ++ dev_dbg(&spi->dev, "assert chip reset\n"); ++ if (vsc->pdata->reset) ++ vsc->pdata->reset(); ++ ++ } ++ ++ err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, ++ VSC73XX_ICPU_CHIPID, &t); ++ if (err) { ++ dev_err(&spi->dev, "unable to read chip id, err=%d\n", err); ++ return err; ++ } ++ ++ id = (t >> VSC73XX_ICPU_CHIPID_ID_SHIFT) & VSC73XX_ICPU_CHIPID_ID_MASK; ++ switch (id) { ++ case VSC73XX_ICPU_CHIPID_ID_7385: ++ case VSC73XX_ICPU_CHIPID_ID_7395: ++ break; ++ default: ++ dev_err(&spi->dev, "unsupported chip, id=%04x\n", id); ++ return -ENODEV; ++ } ++ ++ rev = (t >> VSC73XX_ICPU_CHIPID_REV_SHIFT) & ++ VSC73XX_ICPU_CHIPID_REV_MASK; ++ dev_info(&spi->dev, "VSC%04X (rev. %d) switch found\n", id, rev); ++ ++ return 0; ++} ++ ++static int __devinit vsc7385_probe(struct spi_device *spi) ++{ ++ struct vsc7385 *vsc; ++ struct vsc7385_platform_data *pdata; ++ int err; ++ ++ printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n"); ++ ++ pdata = spi->dev.platform_data; ++ if (!pdata) { ++ dev_err(&spi->dev, "no platform data specified\n"); ++ return -ENODEV; ++ } ++ ++ vsc = kzalloc(sizeof(*vsc), GFP_KERNEL); ++ if (!vsc) { ++ dev_err(&spi->dev, "no memory for private data\n"); ++ return -ENOMEM; ++ } ++ ++ mutex_init(&vsc->lock); ++ vsc->pdata = pdata; ++ vsc->spi = spi_dev_get(spi); ++ dev_set_drvdata(&spi->dev, vsc); ++ ++ spi->mode = SPI_MODE_0; ++ spi->bits_per_word = 8; ++ err = spi_setup(spi); ++ if (err) { ++ dev_err(&spi->dev, "spi_setup failed, err=%d\n", err); ++ goto err_drvdata; ++ } ++ ++ err = vsc7385_detect(vsc); ++ if (err) { ++ dev_err(&spi->dev, "no chip found, err=%d\n", err); ++ goto err_drvdata; ++ } ++ ++ err = vsc7385_upload_ucode(vsc); ++ if (err) ++ goto err_drvdata; ++ ++ err = vsc7385_setup(vsc); ++ if (err) ++ goto err_drvdata; ++ ++ return 0; ++ ++err_drvdata: ++ dev_set_drvdata(&spi->dev, NULL); ++ kfree(vsc); ++ return err; ++} ++ ++static int __devexit vsc7385_remove(struct spi_device *spi) ++{ ++ struct vsc7385_data *vsc; ++ ++ vsc = dev_get_drvdata(&spi->dev); ++ dev_set_drvdata(&spi->dev, NULL); ++ kfree(vsc); ++ ++ return 0; ++} ++ ++static struct spi_driver vsc7385_driver = { ++ .driver = { ++ .name = DRV_NAME, ++ .bus = &spi_bus_type, ++ .owner = THIS_MODULE, ++ }, ++ .probe = vsc7385_probe, ++ .remove = __devexit_p(vsc7385_remove), ++}; ++ ++static int __init vsc7385_init(void) ++{ ++ return spi_register_driver(&vsc7385_driver); ++} ++module_init(vsc7385_init); ++ ++static void __exit vsc7385_exit(void) ++{ ++ spi_unregister_driver(&vsc7385_driver); ++} ++module_exit(vsc7385_exit); ++ ++MODULE_DESCRIPTION(DRV_DESC); ++MODULE_VERSION(DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL v2"); ++ +diff -Nur linux-2.6.39.orig/drivers/tty/serial/ar933x_uart.c linux-2.6.39/drivers/tty/serial/ar933x_uart.c +--- linux-2.6.39.orig/drivers/tty/serial/ar933x_uart.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/tty/serial/ar933x_uart.c 2011-08-06 09:32:37.098016752 +0200 +@@ -0,0 +1,688 @@ ++/* ++ * Atheros AR933X SoC built-in UART driver ++ * ++ * Copyright (C) 2011 Gabor Juhos ++ * ++ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define DRIVER_NAME "ar933x-uart" ++ ++#define AR933X_DUMMY_STATUS_RD 0x01 ++ ++static struct uart_driver ar933x_uart_driver; ++ ++struct ar933x_uart_port { ++ struct uart_port port; ++ unsigned int ier; /* shadow Interrupt Enable Register */ ++}; ++ ++static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, ++ int offset) ++{ ++ return readl(up->port.membase + offset); ++} ++ ++static inline void ar933x_uart_write(struct ar933x_uart_port *up, ++ int offset, unsigned int value) ++{ ++ writel(value, up->port.membase + offset); ++} ++ ++static inline void ar933x_uart_rmw(struct ar933x_uart_port *up, ++ unsigned int offset, ++ unsigned int mask, ++ unsigned int val) ++{ ++ unsigned int t; ++ ++ t = ar933x_uart_read(up, offset); ++ t &= ~mask; ++ t |= val; ++ ar933x_uart_write(up, offset, t); ++} ++ ++static inline void ar933x_uart_rmw_set(struct ar933x_uart_port *up, ++ unsigned int offset, ++ unsigned int val) ++{ ++ ar933x_uart_rmw(up, offset, 0, val); ++} ++ ++static inline void ar933x_uart_rmw_clear(struct ar933x_uart_port *up, ++ unsigned int offset, ++ unsigned int val) ++{ ++ ar933x_uart_rmw(up, offset, val, 0); ++} ++ ++static inline void ar933x_uart_start_tx_interrupt(struct ar933x_uart_port *up) ++{ ++ up->ier |= AR933X_UART_INT_TX_EMPTY; ++ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); ++} ++ ++static inline void ar933x_uart_stop_tx_interrupt(struct ar933x_uart_port *up) ++{ ++ up->ier &= ~AR933X_UART_INT_TX_EMPTY; ++ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); ++} ++ ++static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch) ++{ ++ unsigned int rdata; ++ ++ rdata = ch & AR933X_UART_DATA_TX_RX_MASK; ++ rdata |= AR933X_UART_DATA_TX_CSR; ++ ar933x_uart_write(up, AR933X_UART_DATA_REG, rdata); ++} ++ ++static unsigned int ar933x_uart_tx_empty(struct uart_port *port) ++{ ++ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; ++ unsigned long flags; ++ unsigned int rdata; ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG); ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ ++ return (rdata & AR933X_UART_DATA_TX_CSR) ? 0 : TIOCSER_TEMT; ++} ++ ++static unsigned int ar933x_uart_get_mctrl(struct uart_port *port) ++{ ++ return TIOCM_CAR; ++} ++ ++static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) ++{ ++} ++ ++static void ar933x_uart_start_tx(struct uart_port *port) ++{ ++ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; ++ ++ ar933x_uart_start_tx_interrupt(up); ++} ++ ++static void ar933x_uart_stop_tx(struct uart_port *port) ++{ ++ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; ++ ++ ar933x_uart_stop_tx_interrupt(up); ++} ++ ++static void ar933x_uart_stop_rx(struct uart_port *port) ++{ ++ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; ++ ++ up->ier &= ~AR933X_UART_INT_RX_VALID; ++ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); ++} ++ ++static void ar933x_uart_break_ctl(struct uart_port *port, int break_state) ++{ ++ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ if (break_state == -1) ++ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, ++ AR933X_UART_CS_TX_BREAK); ++ else ++ ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, ++ AR933X_UART_CS_TX_BREAK); ++ spin_unlock_irqrestore(&up->port.lock, flags); ++} ++ ++static void ar933x_uart_enable_ms(struct uart_port *port) ++{ ++} ++ ++static void ar933x_uart_set_termios(struct uart_port *port, ++ struct ktermios *new, ++ struct ktermios *old) ++{ ++ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; ++ unsigned int cs; ++ unsigned long flags; ++ unsigned int baud, scale; ++ ++ /* Only CS8 is supported */ ++ new->c_cflag &= ~CSIZE; ++ new->c_cflag |= CS8; ++ ++ /* Only one stop bit is supported */ ++ new->c_cflag &= ~CSTOPB; ++ ++ cs = 0; ++ if (new->c_cflag & PARENB) { ++ if (!(new->c_cflag & PARODD)) ++ cs |= AR933X_UART_CS_PARITY_EVEN; ++ else ++ cs |= AR933X_UART_CS_PARITY_ODD; ++ } else { ++ cs |= AR933X_UART_CS_PARITY_NONE; ++ } ++ ++ /* Mark/space parity is not supported */ ++ new->c_cflag &= ~CMSPAR; ++ ++ baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); ++ scale = (port->uartclk / (16 * baud)) - 1; ++ ++ /* ++ * Ok, we're now changing the port state. Do it with ++ * interrupts disabled. ++ */ ++ spin_lock_irqsave(&up->port.lock, flags); ++ ++ /* Update the per-port timeout. */ ++ uart_update_timeout(port, new->c_cflag, baud); ++ ++ up->port.ignore_status_mask = 0; ++ ++ /* ignore all characters if CREAD is not set */ ++ if ((new->c_cflag & CREAD) == 0) ++ up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD; ++ ++ ar933x_uart_write(up, AR933X_UART_CLOCK_REG, ++ scale << AR933X_UART_CLOCK_SCALE_S | 8192); ++ ++ /* setup configuration register */ ++ ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs); ++ ++ /* enable host interrupt */ ++ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, ++ AR933X_UART_CS_HOST_INT_EN); ++ ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ ++ if (tty_termios_baud_rate(new)) ++ tty_termios_encode_baud_rate(new, baud, baud); ++} ++ ++static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) ++{ ++ struct tty_struct *tty; ++ int max_count = 256; ++ ++ tty = tty_port_tty_get(&up->port.state->port); ++ do { ++ unsigned int rdata; ++ unsigned char ch; ++ ++ rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG); ++ if ((rdata & AR933X_UART_DATA_RX_CSR) == 0) ++ break; ++ ++ /* remove the character from the FIFO */ ++ ar933x_uart_write(up, AR933X_UART_DATA_REG, ++ AR933X_UART_DATA_RX_CSR); ++ ++ if (!tty) { ++ /* discard the data if no tty available */ ++ continue; ++ } ++ ++ up->port.icount.rx++; ++ ch = rdata & AR933X_UART_DATA_TX_RX_MASK; ++ ++ if (uart_handle_sysrq_char(&up->port, ch)) ++ continue; ++ ++ if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0) ++ tty_insert_flip_char(tty, ch, TTY_NORMAL); ++ } while (max_count-- > 0); ++ ++ if (tty) { ++ tty_flip_buffer_push(tty); ++ tty_kref_put(tty); ++ } ++} ++ ++static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) ++{ ++ struct circ_buf *xmit = &up->port.state->xmit; ++ int count; ++ ++ if (uart_tx_stopped(&up->port)) ++ return; ++ ++ count = up->port.fifosize; ++ do { ++ unsigned int rdata; ++ ++ rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG); ++ if ((rdata & AR933X_UART_DATA_TX_CSR) == 0) ++ break; ++ ++ if (up->port.x_char) { ++ ar933x_uart_putc(up, up->port.x_char); ++ up->port.icount.tx++; ++ up->port.x_char = 0; ++ continue; ++ } ++ ++ if (uart_circ_empty(xmit)) ++ break; ++ ++ ar933x_uart_putc(up, xmit->buf[xmit->tail]); ++ ++ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); ++ up->port.icount.tx++; ++ } while (--count > 0); ++ ++ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) ++ uart_write_wakeup(&up->port); ++ ++ if (!uart_circ_empty(xmit)) ++ ar933x_uart_start_tx_interrupt(up); ++} ++ ++static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id) ++{ ++ struct ar933x_uart_port *up = dev_id; ++ unsigned int status; ++ ++ status = ar933x_uart_read(up, AR933X_UART_CS_REG); ++ if ((status & AR933X_UART_CS_HOST_INT) == 0) ++ return IRQ_NONE; ++ ++ spin_lock(&up->port.lock); ++ ++ status = ar933x_uart_read(up, AR933X_UART_INT_REG); ++ status &= ar933x_uart_read(up, AR933X_UART_INT_EN_REG); ++ ++ if (status & AR933X_UART_INT_RX_VALID) { ++ ar933x_uart_write(up, AR933X_UART_INT_REG, ++ AR933X_UART_INT_RX_VALID); ++ ar933x_uart_rx_chars(up); ++ } ++ ++ if (status & AR933X_UART_INT_TX_EMPTY) { ++ ar933x_uart_write(up, AR933X_UART_INT_REG, ++ AR933X_UART_INT_TX_EMPTY); ++ ar933x_uart_stop_tx_interrupt(up); ++ ar933x_uart_tx_chars(up); ++ } ++ ++ spin_unlock(&up->port.lock); ++ ++ return IRQ_HANDLED; ++} ++ ++static int ar933x_uart_startup(struct uart_port *port) ++{ ++ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; ++ unsigned long flags; ++ int ret; ++ ++ ret = request_irq(up->port.irq, ar933x_uart_interrupt, ++ up->port.irqflags, dev_name(up->port.dev), up); ++ if (ret) ++ return ret; ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ ++ /* Enable HOST interrupts */ ++ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, ++ AR933X_UART_CS_HOST_INT_EN); ++ ++ /* Enable RX interrupts */ ++ up->ier = AR933X_UART_INT_RX_VALID; ++ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); ++ ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ ++ return 0; ++} ++ ++static void ar933x_uart_shutdown(struct uart_port *port) ++{ ++ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; ++ ++ /* Disable all interrupts */ ++ up->ier = 0; ++ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); ++ ++ /* Disable break condition */ ++ ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, ++ AR933X_UART_CS_TX_BREAK); ++ ++ free_irq(up->port.irq, up); ++} ++ ++static const char *ar933x_uart_type(struct uart_port *port) ++{ ++ return (port->type == PORT_AR933X) ? "AR933X UART" : NULL; ++} ++ ++static void ar933x_uart_release_port(struct uart_port *port) ++{ ++ /* Nothing to release ... */ ++} ++ ++static int ar933x_uart_request_port(struct uart_port *port) ++{ ++ /* UARTs always present */ ++ return 0; ++} ++ ++static void ar933x_uart_config_port(struct uart_port *port, int flags) ++{ ++ if (flags & UART_CONFIG_TYPE) ++ port->type = PORT_AR933X; ++} ++ ++static int ar933x_uart_verify_port(struct uart_port *port, ++ struct serial_struct *ser) ++{ ++ if (ser->type != PORT_UNKNOWN && ++ ser->type != PORT_AR933X) ++ return -EINVAL; ++ ++ if (ser->irq < 0 || ser->irq >= NR_IRQS) ++ return -EINVAL; ++ ++ if (ser->baud_base < 28800) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static struct uart_ops ar933x_uart_ops = { ++ .tx_empty = ar933x_uart_tx_empty, ++ .set_mctrl = ar933x_uart_set_mctrl, ++ .get_mctrl = ar933x_uart_get_mctrl, ++ .stop_tx = ar933x_uart_stop_tx, ++ .start_tx = ar933x_uart_start_tx, ++ .stop_rx = ar933x_uart_stop_rx, ++ .enable_ms = ar933x_uart_enable_ms, ++ .break_ctl = ar933x_uart_break_ctl, ++ .startup = ar933x_uart_startup, ++ .shutdown = ar933x_uart_shutdown, ++ .set_termios = ar933x_uart_set_termios, ++ .type = ar933x_uart_type, ++ .release_port = ar933x_uart_release_port, ++ .request_port = ar933x_uart_request_port, ++ .config_port = ar933x_uart_config_port, ++ .verify_port = ar933x_uart_verify_port, ++}; ++ ++#ifdef CONFIG_SERIAL_AR933X_CONSOLE ++ ++static struct ar933x_uart_port * ++ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS]; ++ ++static void ar933x_uart_wait_xmitr(struct ar933x_uart_port *up) ++{ ++ unsigned int status; ++ unsigned int timeout = 60000; ++ ++ /* Wait up to 60ms for the character(s) to be sent. */ ++ do { ++ status = ar933x_uart_read(up, AR933X_UART_DATA_REG); ++ if (--timeout == 0) ++ break; ++ udelay(1); ++ } while ((status & AR933X_UART_DATA_TX_CSR) == 0); ++} ++ ++static void ar933x_uart_console_putchar(struct uart_port *port, int ch) ++{ ++ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; ++ ++ ar933x_uart_wait_xmitr(up); ++ ar933x_uart_putc(up, ch); ++} ++ ++static void ar933x_uart_console_write(struct console *co, const char *s, ++ unsigned int count) ++{ ++ struct ar933x_uart_port *up = ar933x_console_ports[co->index]; ++ unsigned long flags; ++ unsigned int int_en; ++ int locked = 1; ++ ++ local_irq_save(flags); ++ ++ if (up->port.sysrq) ++ locked = 0; ++ else if (oops_in_progress) ++ locked = spin_trylock(&up->port.lock); ++ else ++ spin_lock(&up->port.lock); ++ ++ /* ++ * First save the IER then disable the interrupts ++ */ ++ int_en = ar933x_uart_read(up, AR933X_UART_INT_EN_REG); ++ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, 0); ++ ++ uart_console_write(&up->port, s, count, ar933x_uart_console_putchar); ++ ++ /* ++ * Finally, wait for transmitter to become empty ++ * and restore the IER ++ */ ++ ar933x_uart_wait_xmitr(up); ++ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, int_en); ++ ++ ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_ALLINTS); ++ ++ if (locked) ++ spin_unlock(&up->port.lock); ++ ++ local_irq_restore(flags); ++} ++ ++static int ar933x_uart_console_setup(struct console *co, char *options) ++{ ++ struct ar933x_uart_port *up; ++ int baud = 115200; ++ int bits = 8; ++ int parity = 'n'; ++ int flow = 'n'; ++ ++ if (co->index < 0 || co->index >= CONFIG_SERIAL_AR933X_NR_UARTS) ++ return -EINVAL; ++ ++ up = ar933x_console_ports[co->index]; ++ if (!up) ++ return -ENODEV; ++ ++ if (options) ++ uart_parse_options(options, &baud, &parity, &bits, &flow); ++ ++ return uart_set_options(&up->port, co, baud, parity, bits, flow); ++} ++ ++static struct console ar933x_uart_console = { ++ .name = "ttyATH", ++ .write = ar933x_uart_console_write, ++ .device = uart_console_device, ++ .setup = ar933x_uart_console_setup, ++ .flags = CON_PRINTBUFFER, ++ .index = -1, ++ .data = &ar933x_uart_driver, ++}; ++ ++static void ar933x_uart_add_console_port(struct ar933x_uart_port *up) ++{ ++ ar933x_console_ports[up->port.line] = up; ++} ++ ++#define AR933X_SERIAL_CONSOLE (&ar933x_uart_console) ++ ++#else ++ ++static inline void ar933x_uart_add_console_port(struct ar933x_uart_port *up) {} ++ ++#define AR933X_SERIAL_CONSOLE NULL ++ ++#endif /* CONFIG_SERIAL_AR933X_CONSOLE */ ++ ++static struct uart_driver ar933x_uart_driver = { ++ .owner = THIS_MODULE, ++ .driver_name = DRIVER_NAME, ++ .dev_name = "ttyATH", ++ .nr = CONFIG_SERIAL_AR933X_NR_UARTS, ++ .cons = AR933X_SERIAL_CONSOLE, ++}; ++ ++static int __devinit ar933x_uart_probe(struct platform_device *pdev) ++{ ++ struct ar933x_uart_platform_data *pdata; ++ struct ar933x_uart_port *up; ++ struct uart_port *port; ++ struct resource *mem_res; ++ struct resource *irq_res; ++ int id; ++ int ret; ++ ++ pdata = pdev->dev.platform_data; ++ if (!pdata) ++ return -EINVAL; ++ ++ id = pdev->id; ++ if (id == -1) ++ id = 0; ++ ++ if (id > CONFIG_SERIAL_AR933X_NR_UARTS) ++ return -EINVAL; ++ ++ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!mem_res) { ++ dev_err(&pdev->dev, "no MEM resource\n"); ++ return -EINVAL; ++ } ++ ++ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (!irq_res) { ++ dev_err(&pdev->dev, "no IRQ resource\n"); ++ return -EINVAL; ++ } ++ ++ up = kzalloc(sizeof(struct ar933x_uart_port), GFP_KERNEL); ++ if (!up) ++ return -ENOMEM; ++ ++ port = &up->port; ++ port->mapbase = mem_res->start; ++ ++ port->membase = ioremap(mem_res->start, AR933X_UART_REGS_SIZE); ++ if (!port->membase) { ++ ret = -ENOMEM; ++ goto err_free_up; ++ } ++ ++ port->line = id; ++ port->irq = irq_res->start; ++ port->dev = &pdev->dev; ++ port->type = PORT_AR933X; ++ port->iotype = UPIO_MEM32; ++ port->uartclk = pdata->uartclk; ++ ++ port->regshift = 2; ++ port->fifosize = AR933X_UART_FIFO_SIZE; ++ port->ops = &ar933x_uart_ops; ++ ++ ar933x_uart_add_console_port(up); ++ ++ ret = uart_add_one_port(&ar933x_uart_driver, &up->port); ++ if (ret) ++ goto err_unmap; ++ ++ platform_set_drvdata(pdev, up); ++ return 0; ++ ++err_unmap: ++ iounmap(up->port.membase); ++err_free_up: ++ kfree(up); ++ return ret; ++} ++ ++static int __devexit ar933x_uart_remove(struct platform_device *pdev) ++{ ++ struct ar933x_uart_port *up; ++ ++ up = platform_get_drvdata(pdev); ++ platform_set_drvdata(pdev, NULL); ++ ++ if (up) { ++ uart_remove_one_port(&ar933x_uart_driver, &up->port); ++ iounmap(up->port.membase); ++ kfree(up); ++ } ++ ++ return 0; ++} ++ ++static struct platform_driver ar933x_uart_platform_driver = { ++ .probe = ar933x_uart_probe, ++ .remove = __devexit_p(ar933x_uart_remove), ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init ar933x_uart_init(void) ++{ ++ int ret; ++ ++ ar933x_uart_driver.nr = CONFIG_SERIAL_AR933X_NR_UARTS; ++ ret = uart_register_driver(&ar933x_uart_driver); ++ if (ret) ++ goto err_out; ++ ++ ret = platform_driver_register(&ar933x_uart_platform_driver); ++ if (ret) ++ goto err_unregister_uart_driver; ++ ++ return 0; ++ ++err_unregister_uart_driver: ++ uart_unregister_driver(&ar933x_uart_driver); ++err_out: ++ return ret; ++} ++ ++static void __exit ar933x_uart_exit(void) ++{ ++ platform_driver_unregister(&ar933x_uart_platform_driver); ++ uart_unregister_driver(&ar933x_uart_driver); ++} ++ ++module_init(ar933x_uart_init); ++module_exit(ar933x_uart_exit); ++ ++MODULE_DESCRIPTION("Atheros AR933X UART driver"); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRIVER_NAME); +diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-ar71xx.c linux-2.6.39/drivers/usb/host/ehci-ar71xx.c +--- linux-2.6.39.orig/drivers/usb/host/ehci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/usb/host/ehci-ar71xx.c 2011-04-27 12:19:22.267661616 +0200 +@@ -0,0 +1,242 @@ ++/* ++ * Bus Glue for Atheros AR71xx built-in EHCI controller. ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Copyright (C) 2007 Atheros Communications, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++ ++#include ++ ++extern int usb_disabled(void); ++ ++static int ehci_ar71xx_init(struct usb_hcd *hcd) ++{ ++ struct ehci_hcd *ehci = hcd_to_ehci(hcd); ++ int ret; ++ ++ ehci->caps = hcd->regs; ++ ehci->regs = hcd->regs + ++ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); ++ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); ++ ++ ehci->sbrn = 0x20; ++ ehci->has_synopsys_hc_bug = 1; ++ ++ ehci_reset(ehci); ++ ++ ret = ehci_init(hcd); ++ if (ret) ++ return ret; ++ ++ ehci_port_power(ehci, 0); ++ ++ return 0; ++} ++ ++static int ehci_ar91xx_init(struct usb_hcd *hcd) ++{ ++ struct ehci_hcd *ehci = hcd_to_ehci(hcd); ++ int ret; ++ ++ ehci->caps = hcd->regs + 0x100; ++ ehci->regs = hcd->regs + 0x100 + ++ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); ++ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); ++ ++ hcd->has_tt = 1; ++ ehci->sbrn = 0x20; ++ ++ ehci_reset(ehci); ++ ++ ret = ehci_init(hcd); ++ if (ret) ++ return ret; ++ ++ ehci_port_power(ehci, 0); ++ ++ return 0; ++} ++ ++static int ehci_ar71xx_probe(const struct hc_driver *driver, ++ struct usb_hcd **hcd_out, ++ struct platform_device *pdev) ++{ ++ struct usb_hcd *hcd; ++ struct resource *res; ++ int irq; ++ int ret; ++ ++ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (!res) { ++ dev_dbg(&pdev->dev, "no IRQ specified for %s\n", ++ dev_name(&pdev->dev)); ++ return -ENODEV; ++ } ++ irq = res->start; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_dbg(&pdev->dev, "no base address specified for %s\n", ++ dev_name(&pdev->dev)); ++ return -ENODEV; ++ } ++ ++ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); ++ if (!hcd) ++ return -ENOMEM; ++ ++ hcd->rsrc_start = res->start; ++ hcd->rsrc_len = res->end - res->start + 1; ++ ++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { ++ dev_dbg(&pdev->dev, "controller already in use\n"); ++ ret = -EBUSY; ++ goto err_put_hcd; ++ } ++ ++ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); ++ if (!hcd->regs) { ++ dev_dbg(&pdev->dev, "error mapping memory\n"); ++ ret = -EFAULT; ++ goto err_release_region; ++ } ++ ++ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); ++ if (ret) ++ goto err_iounmap; ++ ++ return 0; ++ ++err_iounmap: ++ iounmap(hcd->regs); ++ ++err_release_region: ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++err_put_hcd: ++ usb_put_hcd(hcd); ++ return ret; ++} ++ ++static void ehci_ar71xx_remove(struct usb_hcd *hcd, ++ struct platform_device *pdev) ++{ ++ usb_remove_hcd(hcd); ++ iounmap(hcd->regs); ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++ usb_put_hcd(hcd); ++} ++ ++static const struct hc_driver ehci_ar71xx_hc_driver = { ++ .description = hcd_name, ++ .product_desc = "Atheros AR71xx built-in EHCI controller", ++ .hcd_priv_size = sizeof(struct ehci_hcd), ++ ++ .irq = ehci_irq, ++ .flags = HCD_MEMORY | HCD_USB2, ++ ++ .reset = ehci_ar71xx_init, ++ .start = ehci_run, ++ .stop = ehci_stop, ++ .shutdown = ehci_shutdown, ++ ++ .urb_enqueue = ehci_urb_enqueue, ++ .urb_dequeue = ehci_urb_dequeue, ++ .endpoint_disable = ehci_endpoint_disable, ++ .endpoint_reset = ehci_endpoint_reset, ++ ++ .get_frame_number = ehci_get_frame, ++ ++ .hub_status_data = ehci_hub_status_data, ++ .hub_control = ehci_hub_control, ++#ifdef CONFIG_PM ++ .hub_suspend = ehci_hub_suspend, ++ .hub_resume = ehci_hub_resume, ++#endif ++ .relinquish_port = ehci_relinquish_port, ++ .port_handed_over = ehci_port_handed_over, ++ ++ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, ++}; ++ ++static const struct hc_driver ehci_ar91xx_hc_driver = { ++ .description = hcd_name, ++ .product_desc = "Atheros AR91xx built-in EHCI controller", ++ .hcd_priv_size = sizeof(struct ehci_hcd), ++ .irq = ehci_irq, ++ .flags = HCD_MEMORY | HCD_USB2, ++ ++ .reset = ehci_ar91xx_init, ++ .start = ehci_run, ++ .stop = ehci_stop, ++ .shutdown = ehci_shutdown, ++ ++ .urb_enqueue = ehci_urb_enqueue, ++ .urb_dequeue = ehci_urb_dequeue, ++ .endpoint_disable = ehci_endpoint_disable, ++ .endpoint_reset = ehci_endpoint_reset, ++ ++ .get_frame_number = ehci_get_frame, ++ ++ .hub_status_data = ehci_hub_status_data, ++ .hub_control = ehci_hub_control, ++#ifdef CONFIG_PM ++ .hub_suspend = ehci_hub_suspend, ++ .hub_resume = ehci_hub_resume, ++#endif ++ .relinquish_port = ehci_relinquish_port, ++ .port_handed_over = ehci_port_handed_over, ++ ++ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, ++}; ++ ++static int ehci_ar71xx_driver_probe(struct platform_device *pdev) ++{ ++ struct ar71xx_ehci_platform_data *pdata; ++ struct usb_hcd *hcd = NULL; ++ int ret; ++ ++ if (usb_disabled()) ++ return -ENODEV; ++ ++ pdata = pdev->dev.platform_data; ++ if (!pdata) { ++ dev_err(&pdev->dev, "no platform data specified for %s\n", ++ dev_name(&pdev->dev)); ++ return -ENODEV; ++ } ++ ++ if (pdata->is_ar91xx) ++ ret = ehci_ar71xx_probe(&ehci_ar91xx_hc_driver, &hcd, pdev); ++ else ++ ret = ehci_ar71xx_probe(&ehci_ar71xx_hc_driver, &hcd, pdev); ++ ++ return ret; ++} ++ ++static int ehci_ar71xx_driver_remove(struct platform_device *pdev) ++{ ++ struct usb_hcd *hcd = platform_get_drvdata(pdev); ++ ++ ehci_ar71xx_remove(hcd, pdev); ++ return 0; ++} ++ ++MODULE_ALIAS("platform:ar71xx-ehci"); ++ ++static struct platform_driver ehci_ar71xx_driver = { ++ .probe = ehci_ar71xx_driver_probe, ++ .remove = ehci_ar71xx_driver_remove, ++ .driver = { ++ .name = "ar71xx-ehci", ++ } ++}; +diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-hcd.c linux-2.6.39/drivers/usb/host/ehci-hcd.c +--- linux-2.6.39.orig/drivers/usb/host/ehci-hcd.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/usb/host/ehci-hcd.c 2011-08-22 16:21:42.807985568 +0200 +@@ -1265,6 +1265,11 @@ + #define PLATFORM_DRIVER tegra_ehci_driver + #endif + ++#ifdef CONFIG_USB_EHCI_AR71XX ++#include "ehci-ar71xx.c" ++#define PLATFORM_DRIVER ehci_ar71xx_driver ++#endif ++ + #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ + !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ + !defined(XILINX_OF_PLATFORM_DRIVER) +diff -Nur linux-2.6.39.orig/drivers/usb/host/Kconfig linux-2.6.39/drivers/usb/host/Kconfig +--- linux-2.6.39.orig/drivers/usb/host/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/usb/host/Kconfig 2011-08-22 16:21:42.767983341 +0200 +@@ -129,6 +129,13 @@ + config USB_FSL_MPH_DR_OF + tristate + ++config USB_EHCI_AR71XX ++ bool "USB EHCI support for AR71xx" ++ depends on USB_EHCI_HCD && ATHEROS_AR71XX ++ default y ++ help ++ Support for Atheros AR71xx built-in EHCI controller ++ + config USB_EHCI_FSL + bool "Support for Freescale on-chip EHCI USB controller" + depends on USB_EHCI_HCD && FSL_SOC +@@ -287,6 +294,13 @@ + Enables support for the on-chip OHCI controller on + OMAP3 and later chips. + ++config USB_OHCI_AR71XX ++ bool "USB OHCI support for Atheros AR71xx" ++ depends on USB_OHCI_HCD && ATHEROS_AR71XX ++ default y ++ help ++ Support for Atheros AR71xx built-in OHCI controller ++ + config USB_OHCI_HCD_PPC_SOC + bool "OHCI support for on-chip PPC USB controller" + depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) +diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-ar71xx.c linux-2.6.39/drivers/usb/host/ohci-ar71xx.c +--- linux-2.6.39.orig/drivers/usb/host/ohci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/usb/host/ohci-ar71xx.c 2011-04-27 12:19:22.267661616 +0200 +@@ -0,0 +1,165 @@ ++/* ++ * OHCI HCD (Host Controller Driver) for USB. ++ * ++ * Bus Glue for Atheros AR71xx built-in OHCI controller. ++ * ++ * Copyright (C) 2008 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Copyright (C) 2007 Atheros Communications, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++ ++extern int usb_disabled(void); ++ ++static int usb_hcd_ar71xx_probe(const struct hc_driver *driver, ++ struct platform_device *pdev) ++{ ++ struct usb_hcd *hcd; ++ struct resource *res; ++ int irq; ++ int ret; + -+#define AR7240_PORT_CPU 0 -+#define AR7240_NUM_PORTS 6 -+#define AR7240_NUM_PHYS 5 ++ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (!res) { ++ dev_dbg(&pdev->dev, "no IRQ specified for %s\n", ++ dev_name(&pdev->dev)); ++ return -ENODEV; ++ } ++ irq = res->start; + -+#define AR7240_PHY_ID1 0x004d -+#define AR7240_PHY_ID2 0xd041 ++ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); ++ if (!hcd) ++ return -ENOMEM; + -+#define AR7240_PORT_MASK(_port) BIT((_port)) -+#define AR7240_PORT_MASK_ALL BITM(AR7240_NUM_PORTS) -+#define AR7240_PORT_MASK_BUT(_port) (AR7240_PORT_MASK_ALL & ~BIT((_port))) ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_dbg(&pdev->dev, "no base address specified for %s\n", ++ dev_name(&pdev->dev)); ++ ret = -ENODEV; ++ goto err_put_hcd; ++ } ++ hcd->rsrc_start = res->start; ++ hcd->rsrc_len = res->end - res->start + 1; + -+struct ar7240sw { -+ struct mii_bus *mii_bus; -+ struct mutex reg_mutex; -+ struct mutex stats_mutex; -+}; ++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { ++ dev_dbg(&pdev->dev, "controller already in use\n"); ++ ret = -EBUSY; ++ goto err_put_hcd; ++ } + -+struct ar7240sw_hw_stat { -+ char string[ETH_GSTRING_LEN]; -+ int sizeof_stat; -+ int reg; -+}; ++ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); ++ if (!hcd->regs) { ++ dev_dbg(&pdev->dev, "error mapping memory\n"); ++ ret = -EFAULT; ++ goto err_release_region; ++ } + -+static inline struct ar7240sw *dsa_to_ar7240sw(struct dsa_switch *ds) -+{ -+ return (struct ar7240sw *)(ds + 1); -+} ++ ohci_hcd_init(hcd_to_ohci(hcd)); + -+static inline void ar7240sw_init(struct ar7240sw *as, struct mii_bus *mii) -+{ -+ as->mii_bus = mii; -+ mutex_init(&as->reg_mutex); -+ mutex_init(&as->stats_mutex); -+} ++ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); ++ if (ret) ++ goto err_stop_hcd; + -+static inline u16 mk_phy_addr(u32 reg) -+{ -+ return (0x17 & ((reg >> 4) | 0x10)); -+} ++ return 0; + -+static inline u16 mk_phy_reg(u32 reg) -+{ -+ return ((reg << 1) & 0x1e); ++err_stop_hcd: ++ iounmap(hcd->regs); ++err_release_region: ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++err_put_hcd: ++ usb_put_hcd(hcd); ++ return ret; +} + -+static inline u16 mk_high_addr(u32 reg) ++void usb_hcd_ar71xx_remove(struct usb_hcd *hcd, struct platform_device *pdev) +{ -+ return ((reg >> 7) & 0x1ff); ++ usb_remove_hcd(hcd); ++ iounmap(hcd->regs); ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++ usb_put_hcd(hcd); +} + -+static u32 __ar7240sw_reg_read(struct ar7240sw *as, u32 reg) ++static int __devinit ohci_ar71xx_start(struct usb_hcd *hcd) +{ -+ struct mii_bus *mii = as->mii_bus; -+ u16 phy_addr; -+ u16 phy_reg; -+ u32 hi, lo; -+ -+ reg = (reg & 0xfffffffc) >> 2; ++ struct ohci_hcd *ohci = hcd_to_ohci(hcd); ++ int ret; + -+ mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg)); ++ ret = ohci_init(ohci); ++ if (ret < 0) ++ return ret; + -+ phy_addr = mk_phy_addr(reg); -+ phy_reg = mk_phy_reg(reg); ++ ret = ohci_run(ohci); ++ if (ret < 0) ++ goto err; + -+ lo = (u32) mdiobus_read(mii, phy_addr, phy_reg); -+ hi = (u32) mdiobus_read(mii, phy_addr, phy_reg + 1); ++ return 0; + -+ return ((hi << 16) | lo); ++err: ++ ohci_stop(hcd); ++ return ret; +} + -+static void __ar7240sw_reg_write(struct ar7240sw *as, u32 reg, u32 val) -+{ -+ struct mii_bus *mii = as->mii_bus; -+ u16 phy_addr; -+ u16 phy_reg; -+ -+ reg = (reg & 0xfffffffc) >> 2; -+ -+ mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg)); -+ -+ phy_addr = mk_phy_addr(reg); -+ phy_reg = mk_phy_reg(reg); ++static const struct hc_driver ohci_ar71xx_hc_driver = { ++ .description = hcd_name, ++ .product_desc = "Atheros AR71xx built-in OHCI controller", ++ .hcd_priv_size = sizeof(struct ohci_hcd), + -+ mdiobus_write(mii, phy_addr, phy_reg + 1, (val >> 16)); -+ mdiobus_write(mii, phy_addr, phy_reg, (val & 0xffff)); -+} ++ .irq = ohci_irq, ++ .flags = HCD_USB11 | HCD_MEMORY, + -+static u32 ar7240sw_reg_read(struct ar7240sw *as, u32 reg_addr) -+{ -+ u32 ret; ++ .start = ohci_ar71xx_start, ++ .stop = ohci_stop, ++ .shutdown = ohci_shutdown, + -+ mutex_lock(&as->reg_mutex); -+ ret = __ar7240sw_reg_read(as, reg_addr); -+ mutex_unlock(&as->reg_mutex); ++ .urb_enqueue = ohci_urb_enqueue, ++ .urb_dequeue = ohci_urb_dequeue, ++ .endpoint_disable = ohci_endpoint_disable, + -+ return ret; -+} ++ /* ++ * scheduling support ++ */ ++ .get_frame_number = ohci_get_frame, + -+static void ar7240sw_reg_write(struct ar7240sw *as, u32 reg_addr, u32 reg_val) -+{ -+ mutex_lock(&as->reg_mutex); -+ __ar7240sw_reg_write(as, reg_addr, reg_val); -+ mutex_unlock(&as->reg_mutex); -+} ++ /* ++ * root hub support ++ */ ++ .hub_status_data = ohci_hub_status_data, ++ .hub_control = ohci_hub_control, ++ .start_port_reset = ohci_start_port_reset, ++}; + -+static u32 ar7240sw_reg_rmw(struct ar7240sw *as, u32 reg, u32 mask, u32 val) ++static int ohci_hcd_ar71xx_drv_probe(struct platform_device *pdev) +{ -+ u32 t; -+ -+ mutex_lock(&as->reg_mutex); -+ t = __ar7240sw_reg_read(as, reg); -+ t &= ~mask; -+ t |= val; -+ __ar7240sw_reg_write(as, reg, t); -+ mutex_unlock(&as->reg_mutex); ++ if (usb_disabled()) ++ return -ENODEV; + -+ return t; ++ return usb_hcd_ar71xx_probe(&ohci_ar71xx_hc_driver, pdev); +} + -+static void ar7240sw_reg_set(struct ar7240sw *as, u32 reg, u32 val) ++static int ohci_hcd_ar71xx_drv_remove(struct platform_device *pdev) +{ -+ u32 t; ++ struct usb_hcd *hcd = platform_get_drvdata(pdev); + -+ mutex_lock(&as->reg_mutex); -+ t = __ar7240sw_reg_read(as, reg); -+ t |= val; -+ __ar7240sw_reg_write(as, reg, t); -+ mutex_unlock(&as->reg_mutex); ++ usb_hcd_ar71xx_remove(hcd, pdev); ++ return 0; +} + -+static int ar7240sw_reg_wait(struct ar7240sw *as, u32 reg, u32 mask, u32 val, -+ unsigned timeout) -+{ -+ int i; -+ -+ for (i = 0; i < timeout; i++) { -+ u32 t; ++MODULE_ALIAS("platform:ar71xx-ohci"); + -+ t = ar7240sw_reg_read(as, reg); -+ if ((t & mask) == val) -+ return 0; ++static struct platform_driver ohci_hcd_ar71xx_driver = { ++ .probe = ohci_hcd_ar71xx_drv_probe, ++ .remove = ohci_hcd_ar71xx_drv_remove, ++ .shutdown = usb_hcd_platform_shutdown, ++ .driver = { ++ .name = "ar71xx-ohci", ++ .owner = THIS_MODULE, ++ }, ++}; +diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-hcd.c linux-2.6.39/drivers/usb/host/ohci-hcd.c +--- linux-2.6.39.orig/drivers/usb/host/ohci-hcd.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/usb/host/ohci-hcd.c 2011-08-22 16:21:42.847983209 +0200 +@@ -1105,6 +1105,11 @@ + #define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver + #endif + ++#ifdef CONFIG_USB_OHCI_AR71XX ++#include "ohci-ar71xx.c" ++#define PLATFORM_DRIVER ohci_hcd_ar71xx_driver ++#endif + -+ msleep(1); -+ } + #if !defined(PCI_DRIVER) && \ + !defined(PLATFORM_DRIVER) && \ + !defined(OMAP1_PLATFORM_DRIVER) && \ +diff -Nur linux-2.6.39.orig/drivers/watchdog/ar71xx_wdt.c linux-2.6.39/drivers/watchdog/ar71xx_wdt.c +--- linux-2.6.39.orig/drivers/watchdog/ar71xx_wdt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/watchdog/ar71xx_wdt.c 2011-08-06 09:32:37.118022037 +0200 +@@ -0,0 +1,299 @@ ++/* ++ * Driver for the Atheros AR71xx SoC's built-in hardware watchdog timer. ++ * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2008 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros 2.6.31 BSP ++ * ++ * This driver was based on: drivers/watchdog/ixp4xx_wdt.c ++ * Author: Deepak Saxena ++ * Copyright 2004 (c) MontaVista, Software, Inc. ++ * ++ * which again was based on sa1100 driver, ++ * Copyright (C) 2000 Oleg Drokin ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ + -+ return -ETIMEDOUT; -+} ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+static u16 ar7240sw_phy_read(struct ar7240sw *as, unsigned phy_addr, -+ unsigned reg_addr) -+{ -+ u32 t; -+ int err; ++#include + -+ if (phy_addr >= AR7240_NUM_PHYS) -+ return 0xffff; ++#define DRV_NAME "ar71xx-wdt" ++#define DRV_DESC "Atheros AR71xx hardware watchdog driver" ++#define DRV_VERSION "0.1.0" + -+ t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | -+ (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | -+ AR7240_MDIO_CTRL_MASTER_EN | -+ AR7240_MDIO_CTRL_BUSY | -+ AR7240_MDIO_CTRL_CMD_READ; ++#define WDT_TIMEOUT 15 /* seconds */ + -+ ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t); -+ err = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL, -+ AR7240_MDIO_CTRL_BUSY, 0, 5); -+ if (err) -+ return 0xffff; ++static int nowayout = WATCHDOG_NOWAYOUT; + -+ t = ar7240sw_reg_read(as, AR7240_REG_MDIO_CTRL); -+ return (t & AR7240_MDIO_CTRL_DATA_M); -+} ++#ifdef CONFIG_WATCHDOG_NOWAYOUT ++module_param(nowayout, int, 0); ++MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " ++ "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); ++#endif + -+static int ar7240sw_phy_write(struct ar7240sw *as, unsigned phy_addr, -+ unsigned reg_addr, u16 reg_val) -+{ -+ u32 t; -+ int ret; ++static unsigned long wdt_flags; + -+ if (phy_addr >= AR7240_NUM_PHYS) -+ return -EINVAL; ++#define WDT_FLAGS_BUSY 0 ++#define WDT_FLAGS_EXPECT_CLOSE 1 + -+ t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | -+ (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | -+ AR7240_MDIO_CTRL_MASTER_EN | -+ AR7240_MDIO_CTRL_BUSY | -+ AR7240_MDIO_CTRL_CMD_WRITE | -+ reg_val; ++static int wdt_timeout = WDT_TIMEOUT; ++static int boot_status; ++static int max_timeout; ++static u32 wdt_clk_freq; + -+ ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t); -+ ret = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL, -+ AR7240_MDIO_CTRL_BUSY, 0, 5); -+ return ret; ++static inline void ar71xx_wdt_keepalive(void) ++{ ++ ar71xx_reset_wr(AR71XX_RESET_REG_WDOG, wdt_clk_freq * wdt_timeout); +} + -+static int ar7240sw_capture_stats(struct ar7240sw *as) ++static inline void ar71xx_wdt_enable(void) +{ -+ int ret; -+ -+ /* Capture the hardware statistics for all ports */ -+ ar7240sw_reg_write(as, AR7240_REG_MIB_FUNCTION0, -+ (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S)); -+ -+ /* Wait for the capturing to complete. */ -+ ret = ar7240sw_reg_wait(as, AR7240_REG_MIB_FUNCTION0, -+ AR7240_MIB_BUSY, 0, 10); -+ return ret; ++ printk(KERN_DEBUG DRV_NAME ": enabling watchdog timer\n"); ++ ar71xx_wdt_keepalive(); ++ udelay(2); ++ ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR); +} + -+static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port) ++static inline void ar71xx_wdt_disable(void) +{ -+ ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port), -+ AR7240_PORT_CTRL_STATE_DISABLED); ++ printk(KERN_DEBUG DRV_NAME ": disabling watchdog timer\n"); ++ ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE); +} + -+static int ar7240sw_reset(struct ar7240sw *as) ++static int ar71xx_wdt_set_timeout(int val) +{ -+ int ret; -+ int i; -+ -+ /* Set all ports to disabled state. */ -+ for (i = 0; i < AR7240_NUM_PORTS; i++) -+ ar7240sw_disable_port(as, i); ++ if (val < 1 || val > max_timeout) ++ return -EINVAL; + -+ /* Wait for transmit queues to drain. */ -+ msleep(2); ++ wdt_timeout = val; ++ ar71xx_wdt_keepalive(); + -+ /* Reset the switch. */ -+ ar7240sw_reg_write(as, AR7240_REG_MASK_CTRL, -+ AR7240_MASK_CTRL_SOFT_RESET); ++ printk(KERN_DEBUG DRV_NAME ": timeout=%d secs\n", wdt_timeout); + -+ ret = ar7240sw_reg_wait(as, AR7240_REG_MASK_CTRL, -+ AR7240_MASK_CTRL_SOFT_RESET, 0, 1000); -+ return ret; ++ return 0; +} + -+static void ar7240sw_setup(struct ar7240sw *as) ++static int ar71xx_wdt_open(struct inode *inode, struct file *file) +{ -+ /* Enable CPU port, and disable mirror port */ -+ ar7240sw_reg_write(as, AR7240_REG_CPU_PORT, -+ AR7240_CPU_PORT_EN | -+ (15 << AR7240_MIRROR_PORT_S)); ++ if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags)) ++ return -EBUSY; + -+ /* Setup TAG priority mapping */ -+ ar7240sw_reg_write(as, AR7240_REG_TAG_PRIORITY, 0xfa50); ++ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); + -+ /* Enable ARP frame acknowledge */ -+ ar7240sw_reg_set(as, AR7240_REG_AT_CTRL, AR7240_AT_CTRL_ARP_EN); ++ ar71xx_wdt_enable(); + -+ /* Enable Broadcast frames transmitted to the CPU */ -+ ar7240sw_reg_set(as, AR7240_REG_FLOOD_MASK, -+ AR7240_FLOOD_MASK_BROAD_TO_CPU); ++ return nonseekable_open(inode, file); ++} + -+ /* setup MTU */ -+ ar7240sw_reg_rmw(as, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M, -+ 1536); ++static int ar71xx_wdt_release(struct inode *inode, struct file *file) ++{ ++ if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags)) { ++ ar71xx_wdt_disable(); ++ } else { ++ printk(KERN_CRIT DRV_NAME ": device closed unexpectedly, " ++ "watchdog timer will not stop!\n"); ++ } + -+ /* setup Service TAG */ -+ ar7240sw_reg_rmw(as, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M, -+ ETH_P_QINQ); ++ clear_bit(WDT_FLAGS_BUSY, &wdt_flags); ++ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); ++ ++ return 0; +} + -+static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port) ++static ssize_t ar71xx_wdt_write(struct file *file, const char *data, ++ size_t len, loff_t *ppos) +{ -+ u32 ctrl; -+ u32 dest_ports; -+ u32 vlan; -+ -+ ctrl = AR7240_PORT_CTRL_STATE_FORWARD; ++ if (len) { ++ if (!nowayout) { ++ size_t i; + -+ if (port == AR7240_PORT_CPU) { -+ ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port), -+ AR7240_PORT_STATUS_SPEED_1000 | -+ AR7240_PORT_STATUS_TXFLOW | -+ AR7240_PORT_STATUS_RXFLOW | -+ AR7240_PORT_STATUS_TXMAC | -+ AR7240_PORT_STATUS_RXMAC | -+ AR7240_PORT_STATUS_DUPLEX); ++ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); + -+ /* allow the CPU port to talk to each of the 'real' ports */ -+ dest_ports = AR7240_PORT_MASK_BUT(port); ++ for (i = 0; i != len; i++) { ++ char c; + -+ /* remove service tag from ingress frames */ -+ ctrl |= AR7240_PORT_CTRL_DOUBLE_TAG; -+ } else { -+ ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port), -+ AR7240_PORT_STATUS_LINK_AUTO); ++ if (get_user(c, data + i)) ++ return -EFAULT; + -+ /* -+ * allow each of the 'real' ports to only talk to the CPU -+ * port. -+ */ -+ dest_ports = AR7240_PORT_MASK(port) | -+ AR7240_PORT_MASK(AR7240_PORT_CPU); ++ if (c == 'V') ++ set_bit(WDT_FLAGS_EXPECT_CLOSE, ++ &wdt_flags); ++ } ++ } + -+ /* add service tag to egress frames */ -+ ctrl |= (AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG << -+ AR7240_PORT_CTRL_VLAN_MODE_S); ++ ar71xx_wdt_keepalive(); + } + -+ /* set default VID and and destination ports for this VLAN */ -+ vlan = port; -+ vlan |= (dest_ports << AR7240_PORT_VLAN_DEST_PORTS_S); -+ -+ ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port), ctrl); -+ ar7240sw_reg_write(as, AR7240_REG_PORT_VLAN(port), vlan); ++ return len; +} + -+static char *ar7240_dsa_probe(struct mii_bus *mii, int sw_addr) ++static struct watchdog_info ar71xx_wdt_info = { ++ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | ++ WDIOF_MAGICCLOSE | WDIOF_CARDRESET, ++ .firmware_version = 0, ++ .identity = "AR71XX watchdog", ++}; ++ ++static long ar71xx_wdt_ioctl(struct file *file, ++ unsigned int cmd, unsigned long arg) +{ -+ struct ar7240sw as; -+ u32 ctrl; -+ u16 phy_id1; -+ u16 phy_id2; -+ u8 ver; ++ int t; ++ int ret; + -+ ar7240sw_init(&as, mii); ++ switch (cmd) { ++ case WDIOC_GETSUPPORT: ++ ret = copy_to_user((struct watchdog_info *)arg, ++ &ar71xx_wdt_info, ++ sizeof(ar71xx_wdt_info)) ? -EFAULT : 0; ++ break; + -+ ctrl = ar7240sw_reg_read(&as, AR7240_REG_MASK_CTRL); ++ case WDIOC_GETSTATUS: ++ ret = put_user(0, (int *)arg) ? -EFAULT : 0; ++ break; + -+ ver = (ctrl >> AR7240_MASK_CTRL_VERSION_S) & AR7240_MASK_CTRL_VERSION_M; -+ if (ver != 1) { -+ pr_err("ar7240_dsa: unsupported chip, ctrl=%08x\n", ctrl); -+ return NULL; -+ } ++ case WDIOC_GETBOOTSTATUS: ++ ret = put_user(boot_status, (int *)arg) ? -EFAULT : 0; ++ break; + -+ phy_id1 = ar7240sw_phy_read(&as, 0, MII_PHYSID1); -+ phy_id2 = ar7240sw_phy_read(&as, 0, MII_PHYSID2); -+ if (phy_id1 != AR7240_PHY_ID1 || phy_id2 != AR7240_PHY_ID2) { -+ pr_err("ar7240_dsa: unknown phy id '%04x:%04x'\n", -+ phy_id1, phy_id2); -+ return NULL; ++ case WDIOC_KEEPALIVE: ++ ar71xx_wdt_keepalive(); ++ ret = 0; ++ break; ++ ++ case WDIOC_SETTIMEOUT: ++ ret = get_user(t, (int *)arg) ? -EFAULT : 0; ++ if (ret) ++ break; ++ ++ ret = ar71xx_wdt_set_timeout(t); ++ if (ret) ++ break; ++ ++ /* fallthrough */ ++ case WDIOC_GETTIMEOUT: ++ ret = put_user(wdt_timeout, (int *)arg) ? -EFAULT : 0; ++ break; ++ ++ default: ++ ret = -ENOTTY; ++ break; + } + -+ return "Atheros AR7240 built-in"; ++ return ret; +} + -+static int ar7240_dsa_setup(struct dsa_switch *ds) ++static const struct file_operations ar71xx_wdt_fops = { ++ .owner = THIS_MODULE, ++ .write = ar71xx_wdt_write, ++ .unlocked_ioctl = ar71xx_wdt_ioctl, ++ .open = ar71xx_wdt_open, ++ .release = ar71xx_wdt_release, ++}; ++ ++static struct miscdevice ar71xx_wdt_miscdev = { ++ .minor = WATCHDOG_MINOR, ++ .name = "watchdog", ++ .fops = &ar71xx_wdt_fops, ++}; ++ ++static int __devinit ar71xx_wdt_probe(struct platform_device *pdev) +{ -+ struct ar7240sw *as = dsa_to_ar7240sw(ds); -+ int i; + int ret; + -+ ar7240sw_init(as, ds->master_mii_bus); ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ wdt_clk_freq = ar71xx_ahb_freq; ++ break; ++ ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ wdt_clk_freq = ar71xx_ref_freq; ++ break; ++ ++ default: ++ BUG(); ++ } ++ ++ max_timeout = (0xfffffffful / wdt_clk_freq); ++ wdt_timeout = (max_timeout < WDT_TIMEOUT) ? max_timeout : WDT_TIMEOUT; ++ ++ if (ar71xx_reset_rr(AR71XX_RESET_REG_WDOG_CTRL) & WDOG_CTRL_LAST_RESET) ++ boot_status = WDIOF_CARDRESET; + -+ ret = ar7240sw_reset(as); ++ ret = misc_register(&ar71xx_wdt_miscdev); + if (ret) -+ return ret; ++ goto err_out; + -+ ar7240sw_setup(as); ++ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); + -+ for (i = 0; i < AR7240_NUM_PORTS; i++) { -+ if (dsa_is_cpu_port(ds, i) || (ds->phys_port_mask & (1 << i))) -+ ar7240sw_setup_port(as, i); -+ else -+ ar7240sw_disable_port(as, i); -+ } ++ printk(KERN_DEBUG DRV_NAME ": timeout=%d secs (max=%d)\n", ++ wdt_timeout, max_timeout); + + return 0; ++ ++err_out: ++ return ret; +} + -+static int ar7240_dsa_set_addr(struct dsa_switch *ds, u8 *addr) ++static int __devexit ar71xx_wdt_remove(struct platform_device *pdev) +{ -+ struct ar7240sw *as = dsa_to_ar7240sw(ds); -+ u32 t; ++ misc_deregister(&ar71xx_wdt_miscdev); ++ return 0; ++} + -+ t = (addr[4] << 8) | addr[5]; -+ ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR0, t); ++static struct platform_driver ar71xx_wdt_driver = { ++ .probe = ar71xx_wdt_probe, ++ .remove = __devexit_p(ar71xx_wdt_remove), ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; + -+ t = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3]; -+ ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR1, t); ++static int __init ar71xx_wdt_init(void) ++{ ++ return platform_driver_register(&ar71xx_wdt_driver); ++} ++module_init(ar71xx_wdt_init); + -+ return 0; ++static void __exit ar71xx_wdt_exit(void) ++{ ++ platform_driver_unregister(&ar71xx_wdt_driver); +} ++module_exit(ar71xx_wdt_exit); ++ ++MODULE_DESCRIPTION(DRV_DESC); ++MODULE_VERSION(DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos 0 && port < AR7240_NUM_PORTS) -+ return port - 1; ++ int led_pin; ++ u32 gpio_mask; ++ u32 gpio_val; + -+ return -EINVAL; -+} ++ bool is_clk_25mhz; ++ int (*get_mac_revision)(void); ++ int (*external_reset)(void); + }; + + #endif /* _LINUX_ATH9K_PLATFORM_H */ +diff -Nur linux-2.6.39.orig/include/linux/ip.h linux-2.6.39/include/linux/ip.h +--- linux-2.6.39.orig/include/linux/ip.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/include/linux/ip.h 2011-08-24 05:53:21.239229027 +0200 +@@ -102,7 +102,7 @@ + __be32 saddr; + __be32 daddr; + /*The options start here. */ +-}; ++} __packed; + + #ifdef __KERNEL__ + #include +diff -Nur linux-2.6.39.orig/include/linux/ipv6.h linux-2.6.39/include/linux/ipv6.h +--- linux-2.6.39.orig/include/linux/ipv6.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/include/linux/ipv6.h 2011-08-24 05:53:21.289229059 +0200 +@@ -126,7 +126,7 @@ + + struct in6_addr saddr; + struct in6_addr daddr; +-}; ++} __packed; + + #ifdef __KERNEL__ + /* +diff -Nur linux-2.6.39.orig/include/linux/myloader.h linux-2.6.39/include/linux/myloader.h +--- linux-2.6.39.orig/include/linux/myloader.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/include/linux/myloader.h 2011-08-24 03:12:08.307985040 +0200 +@@ -0,0 +1,120 @@ ++/* ++ * Compex's MyLoader specific definitions ++ * ++ * Copyright (C) 2006-2008 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ + -+static int ar7240_dsa_phy_read(struct dsa_switch *ds, int port, int regnum) -+{ -+ struct ar7240sw *as = dsa_to_ar7240sw(ds); -+ int phy_addr; ++#ifndef _MYLOADER_H_ ++#define _MYLOADER_H_ ++ ++/* Myloader specific magic numbers */ ++#define MYLO_MAGIC_SYS_PARAMS 0x20021107 ++#define MYLO_MAGIC_PARTITIONS 0x20021103 ++#define MYLO_MAGIC_BOARD_PARAMS 0x20021103 ++ ++/* Vendor ID's (seems to be same as the PCI vendor ID's) */ ++#define VENID_COMPEX 0x11F6 ++ ++/* Devices based on the ADM5120 */ ++#define DEVID_COMPEX_NP27G 0x0078 ++#define DEVID_COMPEX_NP28G 0x044C ++#define DEVID_COMPEX_NP28GHS 0x044E ++#define DEVID_COMPEX_WP54Gv1C 0x0514 ++#define DEVID_COMPEX_WP54G 0x0515 ++#define DEVID_COMPEX_WP54AG 0x0546 ++#define DEVID_COMPEX_WPP54AG 0x0550 ++#define DEVID_COMPEX_WPP54G 0x0555 ++ ++/* Devices based on the Atheros AR2317 */ ++#define DEVID_COMPEX_NP25G 0x05E6 ++#define DEVID_COMPEX_WPE53G 0x05DC ++ ++/* Devices based on the Atheros AR71xx */ ++#define DEVID_COMPEX_WP543 0x0640 ++ ++/* Devices based on the IXP422 */ ++#define DEVID_COMPEX_WP18 0x047E ++#define DEVID_COMPEX_NP18A 0x0489 ++ ++/* Other devices */ ++#define DEVID_COMPEX_NP26G8M 0x03E8 ++#define DEVID_COMPEX_NP26G16M 0x03E9 ++ ++struct mylo_partition { ++ uint16_t flags; /* partition flags */ ++ uint16_t type; /* type of the partition */ ++ uint32_t addr; /* relative address of the partition from the ++ flash start */ ++ uint32_t size; /* size of the partition in bytes */ ++ uint32_t param; /* if this is the active partition, the ++ MyLoader load code to this address */ ++}; ++ ++#define PARTITION_FLAG_ACTIVE 0x8000 /* this is the active partition, ++ * MyLoader loads firmware from here */ ++#define PARTITION_FLAG_ISRAM 0x2000 /* FIXME: this is a RAM partition? */ ++#define PARTIIION_FLAG_RAMLOAD 0x1000 /* FIXME: load this partition into the RAM? */ ++#define PARTITION_FLAG_PRELOAD 0x0800 /* the partition data preloaded to RAM ++ * before decompression */ ++#define PARTITION_FLAG_LZMA 0x0100 /* partition data compressed by LZMA */ ++#define PARTITION_FLAG_HAVEHDR 0x0002 /* the partition data have a header */ ++ ++#define PARTITION_TYPE_FREE 0 ++#define PARTITION_TYPE_USED 1 ++ ++#define MYLO_MAX_PARTITIONS 8 /* maximum number of partitions in the ++ partition table */ ++ ++struct mylo_partition_table { ++ uint32_t magic; /* must be MYLO_MAGIC_PARTITIONS */ ++ uint32_t res0; /* unknown/unused */ ++ uint32_t res1; /* unknown/unused */ ++ uint32_t res2; /* unknown/unused */ ++ struct mylo_partition partitions[MYLO_MAX_PARTITIONS]; ++}; ++ ++struct mylo_partition_header { ++ uint32_t len; /* length of the partition data */ ++ uint32_t crc; /* CRC value of the partition data */ ++}; ++ ++struct mylo_system_params { ++ uint32_t magic; /* must be MYLO_MAGIC_SYS_PARAMS */ ++ uint32_t res0; ++ uint32_t res1; ++ uint32_t mylo_ver; ++ uint16_t vid; /* Vendor ID */ ++ uint16_t did; /* Device ID */ ++ uint16_t svid; /* Sub Vendor ID */ ++ uint16_t sdid; /* Sub Device ID */ ++ uint32_t rev; /* device revision */ ++ uint32_t fwhi; ++ uint32_t fwlo; ++ uint32_t tftp_addr; ++ uint32_t prog_start; ++ uint32_t flash_size; /* size of boot FLASH in bytes */ ++ uint32_t dram_size; /* size of onboard RAM in bytes */ ++}; ++ ++struct mylo_eth_addr { ++ uint8_t mac[6]; ++ uint8_t csum[2]; ++}; ++ ++#define MYLO_ETHADDR_COUNT 8 /* maximum number of ethernet address ++ in the board parameters */ ++ ++struct mylo_board_params { ++ uint32_t magic; /* must be MYLO_MAGIC_BOARD_PARAMS */ ++ uint32_t res0; ++ uint32_t res1; ++ uint32_t res2; ++ struct mylo_eth_addr addr[MYLO_ETHADDR_COUNT]; ++}; ++ ++#endif /* _MYLOADER_H_*/ +diff -Nur linux-2.6.39.orig/include/linux/netdevice.h linux-2.6.39/include/linux/netdevice.h +--- linux-2.6.39.orig/include/linux/netdevice.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/include/linux/netdevice.h 2011-08-22 22:00:06.937981400 +0200 +@@ -1182,6 +1182,7 @@ + void *ax25_ptr; /* AX.25 specific data */ + struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data, + assign before registering */ ++ void *phy_ptr; /* PHY device specific data */ + + /* + * Cache lines mostly used on receive path (including eth_type_trans()) +diff -Nur linux-2.6.39.orig/include/linux/nxp_74hc153.h linux-2.6.39/include/linux/nxp_74hc153.h +--- linux-2.6.39.orig/include/linux/nxp_74hc153.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/include/linux/nxp_74hc153.h 2011-04-27 12:19:21.817661653 +0200 +@@ -0,0 +1,24 @@ ++/* ++ * NXP 74HC153 - Dual 4-input multiplexer defines ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ + -+ phy_addr = ar7240_iort_to_phy_addr(port); -+ if (phy_addr < 0) -+ return 0xffff; ++#ifndef _NXP_74HC153_H ++#define _NXP_74HC153_H + -+ return ar7240sw_phy_read(as, phy_addr, regnum); -+} ++#define NXP_74HC153_DRIVER_NAME "nxp-74hc153" + -+static int ar7240_dsa_phy_write(struct dsa_switch *ds, int port, int regnum, -+ u16 val) -+{ -+ struct ar7240sw *as = dsa_to_ar7240sw(ds); -+ int phy_addr; ++struct nxp_74hc153_platform_data { ++ unsigned gpio_base; ++ unsigned gpio_pin_s0; ++ unsigned gpio_pin_s1; ++ unsigned gpio_pin_1y; ++ unsigned gpio_pin_2y; ++}; + -+ phy_addr = ar7240_iort_to_phy_addr(port); -+ if (phy_addr < 0) -+ return 0xffff; ++#endif /* _NXP_74HC153_H */ +diff -Nur linux-2.6.39.orig/include/linux/phy.h linux-2.6.39/include/linux/phy.h +--- linux-2.6.39.orig/include/linux/phy.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/include/linux/phy.h 2011-08-22 22:00:06.867980866 +0200 +@@ -332,6 +332,20 @@ + void (*adjust_link)(struct net_device *dev); + + void (*adjust_state)(struct net_device *dev); + -+ return ar7240sw_phy_write(as, phy_addr, regnum, val); -+} ++ /* ++ * By default these point to the original functions ++ * with the same name. adding them to the phy_device ++ * allows the phy driver to override them for packet ++ * mangling if the ethernet driver supports it ++ * This is required to support some really horrible ++ * switches such as the Marvell 88E6060 ++ */ ++ int (*netif_receive_skb)(struct sk_buff *skb); ++ int (*netif_rx)(struct sk_buff *skb); + -+static const char *ar7240sw_speed_str(unsigned speed) -+{ -+ switch (speed) { -+ case AR7240_PORT_STATUS_SPEED_10: -+ return "10"; -+ case AR7240_PORT_STATUS_SPEED_100: -+ return "100"; -+ case AR7240_PORT_STATUS_SPEED_1000: -+ return "1000"; -+ } ++ /* alignment offset for packets */ ++ int pkt_align; + }; + #define to_phy_device(d) container_of(d, struct phy_device, dev) + +@@ -508,6 +522,7 @@ + void phy_stop_machine(struct phy_device *phydev); + int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd); + int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd); ++int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr); + int phy_mii_ioctl(struct phy_device *phydev, + struct ifreq *ifr, int cmd); + int phy_start_interrupts(struct phy_device *phydev); +diff -Nur linux-2.6.39.orig/include/linux/spi/spi.h linux-2.6.39/include/linux/spi/spi.h +--- linux-2.6.39.orig/include/linux/spi/spi.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/include/linux/spi/spi.h 2011-08-23 15:10:37.559229523 +0200 +@@ -441,6 +441,8 @@ + dma_addr_t rx_dma; + + unsigned cs_change:1; ++ unsigned verify:1; ++ unsigned fast_write:1; + u8 bits_per_word; + u16 delay_usecs; + u32 speed_hz; +@@ -482,6 +484,7 @@ + struct spi_device *spi; + + unsigned is_dma_mapped:1; ++ unsigned fast_read:1; + + /* REVISIT: we might want a flag affecting the behavior of the + * last transfer ... allowing things like "read 16 bit length L" +diff -Nur linux-2.6.39.orig/include/linux/spi/vsc7385.h linux-2.6.39/include/linux/spi/vsc7385.h +--- linux-2.6.39.orig/include/linux/spi/vsc7385.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/include/linux/spi/vsc7385.h 2011-04-27 12:19:21.817661653 +0200 +@@ -0,0 +1,19 @@ ++/* ++ * Platform data definition for the Vitesse VSC7385 ethernet switch driver ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ return "????"; -+} ++struct vsc7385_platform_data { ++ void (*reset)(void); ++ char *ucode_name; ++ struct { ++ u32 tx_ipg:5; ++ u32 bit2:1; ++ u32 clk_sel:3; ++ } mac_cfg; ++}; +diff -Nur linux-2.6.39.orig/include/linux/switch.h linux-2.6.39/include/linux/switch.h +--- linux-2.6.39.orig/include/linux/switch.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/include/linux/switch.h 2011-08-22 22:09:59.799231408 +0200 +@@ -0,0 +1,204 @@ ++/* ++ * switch.h: Switch configuration API ++ * ++ * Copyright (C) 2008 Felix Fietkau ++ * ++ * 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. ++ */ + -+static void ar7240_dsa_poll_link(struct dsa_switch *ds) -+{ -+ struct ar7240sw *as = dsa_to_ar7240sw(ds); -+ int i; ++#ifndef __LINUX_SWITCH_H ++#define __LINUX_SWITCH_H + -+ for (i = 0; i < DSA_MAX_PORTS; i++) { -+ struct net_device *dev; -+ u32 status; -+ int link; -+ unsigned speed; -+ int duplex; ++#include ++#include ++#include ++#include ++#ifndef __KERNEL__ ++#include ++#include ++#include ++#else ++#include ++#endif + -+ dev = ds->ports[i]; -+ if (dev == NULL) -+ continue; ++/* main attributes */ ++enum { ++ SWITCH_ATTR_UNSPEC, ++ /* global */ ++ SWITCH_ATTR_TYPE, ++ /* device */ ++ SWITCH_ATTR_ID, ++ SWITCH_ATTR_DEV_NAME, ++ SWITCH_ATTR_ALIAS, ++ SWITCH_ATTR_NAME, ++ SWITCH_ATTR_VLANS, ++ SWITCH_ATTR_PORTS, ++ SWITCH_ATTR_CPU_PORT, ++ /* attributes */ ++ SWITCH_ATTR_OP_ID, ++ SWITCH_ATTR_OP_TYPE, ++ SWITCH_ATTR_OP_NAME, ++ SWITCH_ATTR_OP_PORT, ++ SWITCH_ATTR_OP_VLAN, ++ SWITCH_ATTR_OP_VALUE_INT, ++ SWITCH_ATTR_OP_VALUE_STR, ++ SWITCH_ATTR_OP_VALUE_PORTS, ++ SWITCH_ATTR_OP_DESCRIPTION, ++ /* port lists */ ++ SWITCH_ATTR_PORT, ++ SWITCH_ATTR_MAX ++}; ++ ++/* commands */ ++enum { ++ SWITCH_CMD_UNSPEC, ++ SWITCH_CMD_GET_SWITCH, ++ SWITCH_CMD_NEW_ATTR, ++ SWITCH_CMD_LIST_GLOBAL, ++ SWITCH_CMD_GET_GLOBAL, ++ SWITCH_CMD_SET_GLOBAL, ++ SWITCH_CMD_LIST_PORT, ++ SWITCH_CMD_GET_PORT, ++ SWITCH_CMD_SET_PORT, ++ SWITCH_CMD_LIST_VLAN, ++ SWITCH_CMD_GET_VLAN, ++ SWITCH_CMD_SET_VLAN ++}; ++ ++/* data types */ ++enum switch_val_type { ++ SWITCH_TYPE_UNSPEC, ++ SWITCH_TYPE_INT, ++ SWITCH_TYPE_STRING, ++ SWITCH_TYPE_PORTS, ++ SWITCH_TYPE_NOVAL, ++}; ++ ++/* port nested attributes */ ++enum { ++ SWITCH_PORT_UNSPEC, ++ SWITCH_PORT_ID, ++ SWITCH_PORT_FLAG_TAGGED, ++ SWITCH_PORT_ATTR_MAX ++}; ++ ++#define SWITCH_ATTR_DEFAULTS_OFFSET 0x1000 ++ ++#ifdef __KERNEL__ ++ ++struct switch_dev; ++struct switch_op; ++struct switch_val; ++struct switch_attr; ++struct switch_attrlist; ++ ++int register_switch(struct switch_dev *dev, struct net_device *netdev); ++void unregister_switch(struct switch_dev *dev); ++ ++/** ++ * struct switch_attrlist - attribute list ++ * ++ * @n_attr: number of attributes ++ * @attr: pointer to the attributes array ++ */ ++struct switch_attrlist { ++ int n_attr; ++ const struct switch_attr *attr; ++}; + -+ link = 0; -+ if (dev->flags & IFF_UP) { -+ status = ar7240sw_reg_read(as, -+ AR7240_REG_PORT_STATUS(i)); -+ link = !!(status & AR7240_PORT_STATUS_LINK_UP); -+ } ++/** ++ * struct switch_dev_ops - switch driver operations ++ * ++ * @attr_global: global switch attribute list ++ * @attr_port: port attribute list ++ * @attr_vlan: vlan attribute list ++ * ++ * Callbacks: ++ * ++ * @get_vlan_ports: read the port list of a VLAN ++ * @set_vlan_ports: set the port list of a VLAN ++ * ++ * @get_port_pvid: get the primary VLAN ID of a port ++ * @set_port_pvid: set the primary VLAN ID of a port ++ * ++ * @apply_config: apply all changed settings to the switch ++ * @reset_switch: resetting the switch ++ */ ++struct switch_dev_ops { ++ struct switch_attrlist attr_global, attr_port, attr_vlan; + -+ if (!link) { -+ if (netif_carrier_ok(dev)) { -+ pr_info("%s: link down\n", dev->name); -+ netif_carrier_off(dev); -+ } -+ continue; -+ } ++ int (*get_vlan_ports)(struct switch_dev *dev, struct switch_val *val); ++ int (*set_vlan_ports)(struct switch_dev *dev, struct switch_val *val); + -+ speed = (status & AR7240_PORT_STATUS_SPEED_M); -+ duplex = (status & AR7240_PORT_STATUS_DUPLEX) ? 1 : 0; -+ if (!netif_carrier_ok(dev)) { -+ pr_info("%s: link up, %sMb/s, %s duplex", -+ dev->name, -+ ar7240sw_speed_str(speed), -+ duplex ? "full" : "half"); -+ netif_carrier_on(dev); -+ } -+ } -+} ++ int (*get_port_pvid)(struct switch_dev *dev, int port, int *val); ++ int (*set_port_pvid)(struct switch_dev *dev, int port, int val); + -+static const struct ar7240sw_hw_stat ar7240_hw_stats[] = { -+ { "rx_broadcast" , 4, AR7240_STATS_RXBROAD, }, -+ { "rx_pause" , 4, AR7240_STATS_RXPAUSE, }, -+ { "rx_multicast" , 4, AR7240_STATS_RXMULTI, }, -+ { "rx_fcs_error" , 4, AR7240_STATS_RXFCSERR, }, -+ { "rx_align_error" , 4, AR7240_STATS_RXALIGNERR, }, -+ { "rx_undersize" , 4, AR7240_STATS_RXRUNT, }, -+ { "rx_fragments" , 4, AR7240_STATS_RXFRAGMENT, }, -+ { "rx_64bytes" , 4, AR7240_STATS_RX64BYTE, }, -+ { "rx_65_127bytes" , 4, AR7240_STATS_RX128BYTE, }, -+ { "rx_128_255bytes" , 4, AR7240_STATS_RX256BYTE, }, -+ { "rx_256_511bytes" , 4, AR7240_STATS_RX512BYTE, }, -+ { "rx_512_1023bytes" , 4, AR7240_STATS_RX1024BYTE, }, -+ { "rx_1024_1518bytes" , 4, AR7240_STATS_RX1518BYTE, }, -+ { "rx_1519_max_bytes" , 4, AR7240_STATS_RXMAXBYTE, }, -+ { "rx_oversize" , 4, AR7240_STATS_RXTOOLONG, }, -+ { "rx_good_bytes" , 8, AR7240_STATS_RXGOODBYTE, }, -+ { "rx_bad_bytes" , 8, AR7240_STATS_RXBADBYTE, }, -+ { "rx_overflow" , 4, AR7240_STATS_RXOVERFLOW, }, -+ { "filtered" , 4, AR7240_STATS_FILTERED, }, -+ { "tx_broadcast" , 4, AR7240_STATS_TXBROAD, }, -+ { "tx_pause" , 4, AR7240_STATS_TXPAUSE, }, -+ { "tx_multicast" , 4, AR7240_STATS_TXMULTI, }, -+ { "tx_underrun" , 4, AR7240_STATS_TXUNDERRUN, }, -+ { "tx_64bytes" , 4, AR7240_STATS_TX64BYTE, }, -+ { "tx_65_127bytes" , 4, AR7240_STATS_TX128BYTE, }, -+ { "tx_128_255bytes" , 4, AR7240_STATS_TX256BYTE, }, -+ { "tx_256_511bytes" , 4, AR7240_STATS_TX512BYTE, }, -+ { "tx_512_1023bytes" , 4, AR7240_STATS_TX1024BYTE, }, -+ { "tx_1024_1518bytes" , 4, AR7240_STATS_TX1518BYTE, }, -+ { "tx_1519_max_bytes" , 4, AR7240_STATS_TXMAXBYTE, }, -+ { "tx_oversize" , 4, AR7240_STATS_TXOVERSIZE, }, -+ { "tx_bytes" , 8, AR7240_STATS_TXBYTE, }, -+ { "tx_collisions" , 4, AR7240_STATS_TXCOLLISION, }, -+ { "tx_abort_collisions" , 4, AR7240_STATS_TXABORTCOL, }, -+ { "tx_multi_collisions" , 4, AR7240_STATS_TXMULTICOL, }, -+ { "tx_single_collisions", 4, AR7240_STATS_TXSINGLECOL, }, -+ { "tx_excessive_deferred", 4, AR7240_STATS_TXEXCDEFER, }, -+ { "tx_deferred" , 4, AR7240_STATS_TXDEFER, }, -+ { "tx_late_collisions" , 4, AR7240_STATS_TXLATECOL, }, -+}; -+ -+static void ar7240_dsa_get_strings(struct dsa_switch *ds, int port, -+ uint8_t *data) -+{ -+ int i; ++ int (*apply_config)(struct switch_dev *dev); ++ int (*reset_switch)(struct switch_dev *dev); ++}; + -+ for (i = 0; i < ARRAY_SIZE(ar7240_hw_stats); i++) { -+ memcpy(data + i * ETH_GSTRING_LEN, -+ ar7240_hw_stats[i].string, ETH_GSTRING_LEN); -+ } -+} ++struct switch_dev { ++ const struct switch_dev_ops *ops; ++ /* will be automatically filled */ ++ char devname[IFNAMSIZ]; + -+static void ar7240_dsa_get_ethtool_stats(struct dsa_switch *ds, int port, -+ uint64_t *data) -+{ -+ struct ar7240sw *as = dsa_to_ar7240sw(ds); -+ int err; -+ int i; ++ const char *name; ++ /* NB: either alias or netdev must be set */ ++ const char *alias; ++ struct net_device *netdev; + -+ mutex_lock(&as->stats_mutex); ++ int ports; ++ int vlans; ++ int cpu_port; + -+ err = ar7240sw_capture_stats(as); -+ if (err) -+ goto unlock; ++ /* the following fields are internal for swconfig */ ++ int id; ++ struct list_head dev_list; ++ unsigned long def_global, def_port, def_vlan; + -+ for (i = 0; i < ARRAY_SIZE(ar7240_hw_stats); i++) { -+ const struct ar7240sw_hw_stat *s = &ar7240_hw_stats[i]; -+ u32 reg = AR7240_REG_STATS_BASE(port); -+ u32 low; -+ u32 high; ++ spinlock_t lock; ++ struct switch_port *portbuf; ++}; + -+ low = ar7240sw_reg_read(as, reg + s->reg); -+ if (s->sizeof_stat == 8) -+ high = ar7240sw_reg_read(as, reg + s->reg); -+ else -+ high = 0; ++struct switch_port { ++ u32 id; ++ u32 flags; ++}; + -+ data[i] = (((u64) high) << 32) | low; -+ } ++struct switch_val { ++ const struct switch_attr *attr; ++ int port_vlan; ++ int len; ++ union { ++ const char *s; ++ u32 i; ++ struct switch_port *ports; ++ } value; ++}; + -+ unlock: -+ mutex_unlock(&as->stats_mutex); -+} ++struct switch_attr { ++ int disabled; ++ int type; ++ const char *name; ++ const char *description; + -+static int ar7240_dsa_get_sset_count(struct dsa_switch *ds) -+{ -+ return ARRAY_SIZE(ar7240_hw_stats); -+} ++ int (*set)(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val); ++ int (*get)(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val); + -+static struct dsa_switch_driver ar7240_dsa_driver = { -+ .tag_protocol = htons(ETH_P_QINQ), -+ .priv_size = sizeof(struct ar7240sw), -+ .probe = ar7240_dsa_probe, -+ .setup = ar7240_dsa_setup, -+ .set_addr = ar7240_dsa_set_addr, -+ .phy_read = ar7240_dsa_phy_read, -+ .phy_write = ar7240_dsa_phy_write, -+ .poll_link = ar7240_dsa_poll_link, -+ .get_strings = ar7240_dsa_get_strings, -+ .get_ethtool_stats = ar7240_dsa_get_ethtool_stats, -+ .get_sset_count = ar7240_dsa_get_sset_count, ++ /* for driver internal use */ ++ int id; ++ int ofs; ++ int max; +}; + -+int __init dsa_ar7240_init(void) -+{ -+ register_switch_driver(&ar7240_dsa_driver); -+ return 0; -+} -+module_init(dsa_ar7240_init); ++#endif + -+void __exit dsa_ar7240_cleanup(void) -+{ -+ unregister_switch_driver(&ar7240_dsa_driver); -+} -+module_exit(dsa_ar7240_cleanup); ++#endif +diff -Nur linux-2.6.39.orig/include/linux/tcp.h linux-2.6.39/include/linux/tcp.h +--- linux-2.6.39.orig/include/linux/tcp.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/include/linux/tcp.h 2011-08-24 05:53:21.379228748 +0200 +@@ -54,7 +54,7 @@ + __be16 window; + __sum16 check; + __be16 urg_ptr; +-}; ++} __packed; + + /* + * The union cast uses a gcc extension to avoid aliasing problems +diff -Nur linux-2.6.39.orig/include/linux/udp.h linux-2.6.39/include/linux/udp.h +--- linux-2.6.39.orig/include/linux/udp.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/include/linux/udp.h 2011-08-24 05:53:21.428824967 +0200 +@@ -24,7 +24,7 @@ + __be16 dest; + __be16 len; + __sum16 check; +-}; ++} __packed; + + /* UDP socket options */ + #define UDP_CORK 1 /* Never send partially complete segments */ diff -Nur linux-2.6.39.orig/net/dsa/mv88e6063.c linux-2.6.39/net/dsa/mv88e6063.c --- linux-2.6.39.orig/net/dsa/mv88e6063.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/net/dsa/mv88e6063.c 2011-05-27 14:36:51.000000000 +0200 ++++ linux-2.6.39/net/dsa/mv88e6063.c 2011-04-27 12:19:21.827661792 +0200 @@ -0,0 +1,294 @@ +/* + * net/dsa/mv88e6063.c - Driver for Marvell 88e6063 switch chips @@ -18297,134 +28270,25 @@ diff -Nur linux-2.6.39.orig/net/dsa/mv88e6063.c linux-2.6.39/net/dsa/mv88e6063.c + unregister_switch_driver(&mv88e6063_switch_driver); +} +module_exit(mv88e6063_cleanup); -diff -Nur linux-2.6.39.orig/net/dsa/tag_qinq.c linux-2.6.39/net/dsa/tag_qinq.c ---- linux-2.6.39.orig/net/dsa/tag_qinq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/net/dsa/tag_qinq.c 2011-05-27 14:36:51.000000000 +0200 -@@ -0,0 +1,127 @@ -+/* -+ * net/dsa/tag_qinq.c - QinQ tag format handling -+ * Copyright (c) 2010 Gabor Juhos -+ * -+ * This file was based on: -+ * net/dsa/tag_edsa.c - Ethertype DSA tagging -+ * Copyright (c) 2008-2009 Marvell Semiconductor -+ * -+ * 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. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "dsa_priv.h" -+ -+netdev_tx_t qinq_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct dsa_slave_priv *p = netdev_priv(dev); -+ struct vlan_ethhdr *veth; -+ unsigned int len; -+ int ret; -+ -+ if (skb_cow_head(skb, VLAN_HLEN) < 0) -+ goto out_free_skb; -+ -+ veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN); -+ -+ /* Move the mac addresses to the beginning of the new header. */ -+ memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN); -+ skb->mac_header -= VLAN_HLEN; -+ -+ /* setup VLAN header fields */ -+ veth->h_vlan_proto = htons(ETH_P_QINQ); -+ veth->h_vlan_TCI = htons(p->port); -+ -+ len = skb->len; -+ skb->protocol = htons(ETH_P_QINQ); -+ skb->dev = p->parent->dst->master_netdev; -+ -+ ret = dev_queue_xmit(skb); -+ if (unlikely(ret != NET_XMIT_SUCCESS)) -+ goto out_dropped; -+ -+ dev->stats.tx_packets++; -+ dev->stats.tx_bytes += len; -+ -+ return NETDEV_TX_OK; -+ -+ out_free_skb: -+ kfree_skb(skb); -+ out_dropped: -+ dev->stats.tx_dropped++; -+ return NETDEV_TX_OK; -+} -+ -+static int qinq_rcv(struct sk_buff *skb, struct net_device *dev, -+ struct packet_type *pt, struct net_device *orig_dev) -+{ -+ struct dsa_switch_tree *dst; -+ struct dsa_switch *ds; -+ struct vlan_hdr *vhdr; -+ int source_port; -+ -+ dst = dev->dsa_ptr; -+ if (unlikely(dst == NULL)) -+ goto out_drop; -+ ds = dst->ds[0]; -+ -+ skb = skb_unshare(skb, GFP_ATOMIC); -+ if (skb == NULL) -+ goto out; -+ -+ if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) -+ goto out_drop; -+ -+ vhdr = (struct vlan_hdr *)skb->data; -+ source_port = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; -+ if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL) -+ goto out_drop; -+ -+ /* Remove the outermost VLAN tag and update checksum. */ -+ skb_pull_rcsum(skb, VLAN_HLEN); -+ memmove(skb->data - ETH_HLEN, -+ skb->data - ETH_HLEN - VLAN_HLEN, -+ 2 * ETH_ALEN); -+ -+ skb->dev = ds->ports[source_port]; -+ skb_push(skb, ETH_HLEN); -+ skb->pkt_type = PACKET_HOST; -+ skb->protocol = eth_type_trans(skb, skb->dev); -+ -+ skb->dev->stats.rx_packets++; -+ skb->dev->stats.rx_bytes += skb->len; -+ -+ netif_receive_skb(skb); -+ -+ return 0; -+ -+ out_drop: -+ kfree_skb(skb); -+ out: -+ return 0; -+} -+ -+static struct packet_type qinq_packet_type __read_mostly = { -+ .type = cpu_to_be16(ETH_P_QINQ), -+ .func = qinq_rcv, -+}; -+ -+static int __init qinq_init_module(void) -+{ -+ dev_add_pack(&qinq_packet_type); -+ return 0; -+} -+module_init(qinq_init_module); -+ -+static void __exit qinq_cleanup_module(void) -+{ -+ dev_remove_pack(&qinq_packet_type); -+} -+module_exit(qinq_cleanup_module); +diff -Nur linux-2.6.39.orig/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c linux-2.6.39/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +--- linux-2.6.39.orig/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 2011-08-24 05:53:21.549229118 +0200 +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -44,8 +45,8 @@ + if (ap == NULL) + return false; + +- tuple->src.u3.ip = ap[0]; +- tuple->dst.u3.ip = ap[1]; ++ tuple->src.u3.ip = __get_unaligned_cpu32(ap++); ++ tuple->dst.u3.ip = __get_unaligned_cpu32(ap); + + return true; + } diff --git a/target/mips/Makefile b/target/mips/Makefile index 5d606046f..00a3e8bdc 100644 --- a/target/mips/Makefile +++ b/target/mips/Makefile @@ -51,11 +51,7 @@ ifeq ($(ADK_TARGET_SYSTEM_MIKROTIK_RB532),y) kernel-install: $(TARGET_CROSS)objcopy $(OSTRIP) -S $(KERNEL) $(BUILD_DIR)/$(TARGET_KERNEL) endif -ifeq ($(ADK_TARGET_SYSTEM_MIKROTIK_RB411),y) -kernel-install: - $(TARGET_CROSS)objcopy $(OSTRIP) -S $(KERNEL) $(BUILD_DIR)/$(TARGET_KERNEL) -endif -ifeq ($(ADK_TARGET_SYSTEM_MIKROTIK_RB433),y) +ifeq ($(ADK_TARGET_SYSTEM_MIKROTIK_RB4XX),y) kernel-install: $(TARGET_CROSS)objcopy $(OSTRIP) -S $(KERNEL) $(BUILD_DIR)/$(TARGET_KERNEL) endif diff --git a/target/mips/kernel.config b/target/mips/kernel.config index bdf5beb9f..4bc717861 100644 --- a/target/mips/kernel.config +++ b/target/mips/kernel.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux/mips 2.6.37 Kernel Configuration -# Sat Apr 23 20:38:50 2011 +# Linux/mips 2.6.39 Kernel Configuration +# Mon Aug 22 22:28:08 2011 # CONFIG_MIPS=y @@ -10,6 +10,7 @@ CONFIG_MIPS=y # # CONFIG_MIPS_ALCHEMY is not set # CONFIG_AR7 is not set +# CONFIG_ATH79 is not set # CONFIG_ATHEROS_AR71XX is not set # CONFIG_BCM47XX is not set # CONFIG_BCM63XX is not set @@ -52,11 +53,11 @@ CONFIG_MACH_LOONGSON=y # CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set # CONFIG_ALCHEMY_GPIO_INDIRECT is not set CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_CAVIUM_OCTEON_HELPER=y # CONFIG_LEMOTE_FULOONG2E is not set CONFIG_LEMOTE_MACH2F=y CONFIG_CS5536=y # CONFIG_CS5536_MFGPT is not set +CONFIG_LOONGSON_SUSPEND=y CONFIG_LOONGSON_UART_BASE=y CONFIG_LOONGSON_MC146818=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -64,16 +65,17 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_SUPPORTS_OPROFILE=y CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_FIND_BIT_LE=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_SCHED_OMIT_FRAME_POINTER=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_CEVT_R4K_LIB=y CONFIG_CEVT_R4K=y CONFIG_CSRC_R4K_LIB=y CONFIG_CSRC_R4K=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_DMA_NONCOHERENT=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_SYS_HAS_EARLY_PRINTK=y @@ -98,7 +100,6 @@ CONFIG_CPU_NOP_WORKAROUNDS=y CONFIG_CPU_JUMP_WORKAROUNDS=y CONFIG_CPU_LOONGSON2F_WORKAROUNDS=y CONFIG_SYS_SUPPORTS_ZBOOT=y -CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y CONFIG_CPU_LOONGSON2=y CONFIG_SYS_HAS_CPU_LOONGSON2F=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y @@ -132,6 +133,7 @@ CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_STATIC=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y @@ -141,7 +143,6 @@ CONFIG_NEED_PER_CPU_KM=y # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK=y # CONFIG_HZ_48 is not set CONFIG_HZ_100=y # CONFIG_HZ_128 is not set @@ -161,6 +162,7 @@ CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y +CONFIG_HAVE_IRQ_WORK=y # # General setup @@ -184,6 +186,7 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_FHANDLE is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set CONFIG_HAVE_GENERIC_HARDIRQS=y @@ -192,31 +195,28 @@ CONFIG_HAVE_GENERIC_HARDIRQS=y # IRQ subsystem # CONFIG_GENERIC_HARDIRQS=y -# CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED is not set -# CONFIG_HAVE_SPARSE_IRQ is not set CONFIG_GENERIC_IRQ_PROBE=y -# CONFIG_GENERIC_PENDING_IRQ is not set -# CONFIG_AUTO_IRQ_AFFINITY is not set -# CONFIG_IRQ_PER_CPU is not set -# CONFIG_HARDIRQS_SW_RESEND is not set +CONFIG_GENERIC_IRQ_SHOW=y # # RCU Subsystem # CONFIG_TINY_RCU=y # CONFIG_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set # CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set # CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y -CONFIG_EMBEDDED=y +CONFIG_EXPERT=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -233,6 +233,7 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_EMBEDDED=y CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_USE_VMALLOC=y @@ -250,11 +251,13 @@ CONFIG_SLAB=y # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set +# CONFIG_JUMP_LABEL is not set CONFIG_HAVE_SYSCALL_WRAPPERS=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y # # GCOV-based kernel profiling @@ -299,7 +302,7 @@ CONFIG_INLINE_WRITE_UNLOCK=y CONFIG_INLINE_WRITE_UNLOCK_IRQ=y # CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set # CONFIG_MUTEX_SPIN_ON_OWNER is not set -# CONFIG_FREEZER is not set +CONFIG_FREEZER=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) @@ -314,6 +317,7 @@ CONFIG_ISA=y CONFIG_MMU=y # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set +# CONFIG_RAPIDIO is not set # # Executable file formats @@ -333,7 +337,12 @@ CONFIG_BINFMT_ELF32=y # CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y -# CONFIG_PM is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_PM_SLEEP=y +# CONFIG_PM_RUNTIME is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set CONFIG_NET=y # @@ -345,7 +354,6 @@ CONFIG_UNIX=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE_DEMUX is not set @@ -376,6 +384,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ATM is not set # CONFIG_L2TP is not set # CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set @@ -389,6 +398,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set # CONFIG_DCB is not set +# CONFIG_BATMAN_ADV is not set # # Network testing @@ -399,7 +409,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -441,7 +457,110 @@ CONFIG_SCSI_MOD=y # CONFIG_FIREWIRE is not set # CONFIG_FIREWIRE_NOSY is not set # CONFIG_I2O is not set -# CONFIG_NETDEVICES is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +# CONFIG_MII is not set +CONFIG_PHYLIB=y +CONFIG_SWCONFIG=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM63XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_NET_ETHERNET is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_JME is not set +# CONFIG_STMMAC_ETH is not set +# CONFIG_PCH_GBE is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +# CONFIG_ENIC is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_EN is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_BNA is not set +# CONFIG_SFC is not set +# CONFIG_BE2NET is not set +# CONFIG_TR is not set +CONFIG_WLAN=y +# CONFIG_AIRO is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set + +# +# CAIF transport drivers +# +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -460,10 +579,13 @@ CONFIG_SCSI_MOD=y # Character devices # # CONFIG_VT is not set -# CONFIG_DEVKMEM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_N_GSM is not set # CONFIG_NOZOMI is not set +# CONFIG_N_GSM is not set +# CONFIG_DEVKMEM is not set # # Serial drivers @@ -485,9 +607,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set # CONFIG_SERIAL_ALTERA_UART is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_PCH_UART is not set # CONFIG_TTY_PRINTK is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set @@ -495,7 +615,6 @@ CONFIG_UNIX98_PTYS=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_GPIO_DEVICE is not set # CONFIG_TCG_TPM is not set CONFIG_DEVPORT=y # CONFIG_RAMOOPS is not set @@ -506,6 +625,10 @@ CONFIG_DEVPORT=y # PPS support # # CONFIG_PPS is not set + +# +# PPS generators support +# CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_GPIO_SYSFS is not set @@ -515,8 +638,6 @@ CONFIG_GPIOLIB=y # # CONFIG_GPIO_BASIC_MMIO is not set # CONFIG_GPIO_IT8761E is not set -# CONFIG_GPIO_SCH is not set -# CONFIG_GPIO_VX855 is not set # # I2C GPIO expanders: @@ -525,10 +646,8 @@ CONFIG_GPIOLIB=y # # PCI GPIO expanders: # -# CONFIG_GPIO_CS5535 is not set # CONFIG_GPIO_BT8XX is not set -# CONFIG_GPIO_LANGWELL is not set -# CONFIG_GPIO_PCH is not set +# CONFIG_GPIO_ML_IOH is not set # CONFIG_GPIO_RDC321X is not set # @@ -578,6 +697,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_NFC_DEVICES is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set # CONFIG_RTC_CLASS is not set @@ -586,33 +706,37 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_UIO is not set CONFIG_STAGING=y # CONFIG_STAGING_EXCLUDE_BUILD is not set +# CONFIG_ET131X is not set # CONFIG_ECHO is not set +# CONFIG_BRCM80211 is not set # CONFIG_COMEDI is not set +# CONFIG_R8187SE is not set +# CONFIG_RTL8192E is not set # CONFIG_POHMELFS is not set -# CONFIG_AUTOFS_FS is not set +# CONFIG_VT6655 is not set # CONFIG_VME_BUS is not set +# CONFIG_DX_SEP is not set # CONFIG_IIO is not set -# CONFIG_BATMAN_ADV is not set +# CONFIG_XVMALLOC is not set # CONFIG_CRYSTALHD is not set - -# -# Texas Instruments shared transport line discipline -# -# CONFIG_SMB_FS is not set CONFIG_MACH_NO_WESTBRIDGE=y # CONFIG_FT1000 is not set # # Speakup console speech # -CONFIG_MIPS_PLATFORM_DEVICES=y -# CONFIG_LEMOTE_LYNLOONG2F is not set + +# +# Altera FPGA firmware download module +# # # File systems # +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y -# CONFIG_FSNOTIFY is not set +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set # CONFIG_FANOTIFY is not set @@ -641,13 +765,13 @@ CONFIG_TMPFS=y # CONFIG_MISC_FILESYSTEMS is not set # CONFIG_NETWORK_FILESYSTEMS is not set # CONFIG_NLS is not set -# CONFIG_DLM is not set # # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=1024 @@ -656,9 +780,9 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_HARDLOCKUP_DETECTOR is not set -CONFIG_BKL=y # CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set @@ -674,6 +798,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_TEST_KSTRTOX is not set CONFIG_EARLY_PRINTK=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="init=/init" @@ -694,6 +819,7 @@ CONFIG_DEFAULT_SECURITY="" # OCF Configuration # # CONFIG_OCF_OCF is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # @@ -708,8 +834,10 @@ CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC32=y # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set -CONFIG_DECOMPRESS_LZMA=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y CONFIG_NLATTR=y +# CONFIG_AVERAGE is not set diff --git a/target/mips/sys-available/mikrotik-rb411 b/target/mips/sys-available/mikrotik-rb411 deleted file mode 100644 index 6e1f597b1..000000000 --- a/target/mips/sys-available/mikrotik-rb411 +++ /dev/null @@ -1,13 +0,0 @@ -config ADK_TARGET_SYSTEM_MIKROTIK_RB411 - bool "Mikrotik Routerboard 411" - select ADK_mips - select ADK_big - select ADK_mikrotik_rb411 - select ADK_KERNEL_ATHEROS_AR71XX - select ADK_KERNEL_ATHEROS_MACH_RB4XX - select ADK_TARGET_WITH_MINIPCI - select ADK_TARGET_WITH_WATCHDOG - select ADK_TARGET_WITH_NAND - help - Support for Mikrotik RB411. - diff --git a/target/mips/sys-available/mikrotik-rb433 b/target/mips/sys-available/mikrotik-rb433 deleted file mode 100644 index 107f317a6..000000000 --- a/target/mips/sys-available/mikrotik-rb433 +++ /dev/null @@ -1,13 +0,0 @@ -config ADK_TARGET_SYSTEM_MIKROTIK_RB433 - bool "Mikrotik Routerboard 433" - select ADK_mips - select ADK_big - select ADK_mikrotik_rb433 - select ADK_KERNEL_ATHEROS_AR71XX - select ADK_KERNEL_ATHEROS_MACH_RB4XX - select ADK_TARGET_WITH_MINIPCI - select ADK_TARGET_WITH_WATCHDOG - select ADK_TARGET_WITH_NAND - help - Support for Mikrotik RB433. - diff --git a/target/mips/sys-available/mikrotik-rb4xx b/target/mips/sys-available/mikrotik-rb4xx new file mode 100644 index 000000000..421f4abb7 --- /dev/null +++ b/target/mips/sys-available/mikrotik-rb4xx @@ -0,0 +1,15 @@ +config ADK_TARGET_SYSTEM_MIKROTIK_RB4XX + bool "Mikrotik Routerboard 4xx" + select ADK_mips + select ADK_big + select ADK_mikrotik_rb4xx + select ADK_KERNEL_ATHEROS_AR71XX + select ADK_KERNEL_AR71XX_MACH_RB4XX + select ADK_KERNEL_SPI_RB4XX + select ADK_KERNEL_SPI_RB4XX_CPLD + select ADK_TARGET_WITH_MINIPCI + select ADK_TARGET_WITH_WATCHDOG + select ADK_TARGET_WITH_NAND + help + Support for Mikrotik RB411/RB433. + -- cgit v1.2.3 From 52229f5bf2fe45d139c6a692415fe1ffb8ea4041 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 24 Aug 2011 12:19:48 +0200 Subject: add qemu sparc64, but it segfaults --- target/sparc64/Makefile | 2 +- target/sparc64/sys-available/qemu-sparc64 | 13 +++++++++++ toolchain/gcc/patches/no-lib64.patch | 36 +++++++++++++++++++++++++------ 3 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 target/sparc64/sys-available/qemu-sparc64 diff --git a/target/sparc64/Makefile b/target/sparc64/Makefile index 9f2a152f9..39212d52e 100644 --- a/target/sparc64/Makefile +++ b/target/sparc64/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/mk/modules.mk include $(TOPDIR)/mk/kernel-build.mk include $(TOPDIR)/mk/image.mk -KERNEL:=$(LINUX_DIR)/arch/sparc64/boot/zImage +KERNEL:=$(LINUX_DIR)/arch/sparc/boot/zImage ifeq ($(ADK_TARGET_FS),archive) imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) diff --git a/target/sparc64/sys-available/qemu-sparc64 b/target/sparc64/sys-available/qemu-sparc64 new file mode 100644 index 000000000..06f493ba7 --- /dev/null +++ b/target/sparc64/sys-available/qemu-sparc64 @@ -0,0 +1,13 @@ +config ADK_TARGET_SYSTEM_QEMU_SPARC64 + bool "Qemu Emulator" + select ADK_sparc64 + select ADK_qemu_sparc64 + select ADK_CPU_SPARC_V9 + select ADK_HARDWARE_QEMU + select ADK_TARGET_WITH_VGA + select ADK_TARGET_WITH_INPUT + select ADK_TARGET_WITH_PCI + select ADK_TARGET_WITH_HDD + help + Support for Qemu Emulator (SPARC64). + diff --git a/toolchain/gcc/patches/no-lib64.patch b/toolchain/gcc/patches/no-lib64.patch index 5fc1225e1..5c6e0b045 100644 --- a/toolchain/gcc/patches/no-lib64.patch +++ b/toolchain/gcc/patches/no-lib64.patch @@ -1,6 +1,6 @@ diff -Nur gcc-4.5.3.orig/gcc/config/i386/linux64.h gcc-4.5.3/gcc/config/i386/linux64.h --- gcc-4.5.3.orig/gcc/config/i386/linux64.h 2010-03-24 21:44:48.000000000 +0100 -+++ gcc-4.5.3/gcc/config/i386/linux64.h 2011-08-24 01:58:27.000000000 +0200 ++++ gcc-4.5.3/gcc/config/i386/linux64.h 2011-08-24 06:35:30.000000000 +0200 @@ -59,7 +59,7 @@ done. */ @@ -12,7 +12,7 @@ diff -Nur gcc-4.5.3.orig/gcc/config/i386/linux64.h gcc-4.5.3/gcc/config/i386/lin #define SPEC_32 "m32" diff -Nur gcc-4.5.3.orig/gcc/config/i386/t-linux64 gcc-4.5.3/gcc/config/i386/t-linux64 --- gcc-4.5.3.orig/gcc/config/i386/t-linux64 2009-04-21 21:03:23.000000000 +0200 -+++ gcc-4.5.3/gcc/config/i386/t-linux64 2011-08-24 01:58:27.000000000 +0200 ++++ gcc-4.5.3/gcc/config/i386/t-linux64 2011-08-24 06:35:30.000000000 +0200 @@ -25,7 +25,7 @@ MULTILIB_OPTIONS = m64/m32 @@ -24,7 +24,7 @@ diff -Nur gcc-4.5.3.orig/gcc/config/i386/t-linux64 gcc-4.5.3/gcc/config/i386/t-l INSTALL_LIBGCC = install-multilib diff -Nur gcc-4.5.3.orig/gcc/config/mips/linux64.h gcc-4.5.3/gcc/config/mips/linux64.h --- gcc-4.5.3.orig/gcc/config/mips/linux64.h 2009-02-20 16:20:38.000000000 +0100 -+++ gcc-4.5.3/gcc/config/mips/linux64.h 2011-08-24 01:58:27.000000000 +0200 ++++ gcc-4.5.3/gcc/config/mips/linux64.h 2011-08-24 06:35:30.000000000 +0200 @@ -36,9 +36,9 @@ %{profile:-lc_p} %{!profile:-lc}}" @@ -40,7 +40,7 @@ diff -Nur gcc-4.5.3.orig/gcc/config/mips/linux64.h gcc-4.5.3/gcc/config/mips/lin diff -Nur gcc-4.5.3.orig/gcc/config/mips/t-linux64 gcc-4.5.3/gcc/config/mips/t-linux64 --- gcc-4.5.3.orig/gcc/config/mips/t-linux64 2009-04-21 21:03:23.000000000 +0200 -+++ gcc-4.5.3/gcc/config/mips/t-linux64 2011-08-24 01:58:27.000000000 +0200 ++++ gcc-4.5.3/gcc/config/mips/t-linux64 2011-08-24 06:35:30.000000000 +0200 @@ -18,7 +18,7 @@ MULTILIB_OPTIONS = mabi=n32/mabi=32/mabi=64 @@ -52,7 +52,7 @@ diff -Nur gcc-4.5.3.orig/gcc/config/mips/t-linux64 gcc-4.5.3/gcc/config/mips/t-l diff -Nur gcc-4.5.3.orig/gcc/config/rs6000/linux64.h gcc-4.5.3/gcc/config/rs6000/linux64.h --- gcc-4.5.3.orig/gcc/config/rs6000/linux64.h 2010-11-17 07:09:53.000000000 +0100 -+++ gcc-4.5.3/gcc/config/rs6000/linux64.h 2011-08-24 02:01:35.000000000 +0200 ++++ gcc-4.5.3/gcc/config/rs6000/linux64.h 2011-08-24 06:35:30.000000000 +0200 @@ -341,7 +341,7 @@ #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" @@ -64,7 +64,7 @@ diff -Nur gcc-4.5.3.orig/gcc/config/rs6000/linux64.h gcc-4.5.3/gcc/config/rs6000 #if UCLIBC_DEFAULT diff -Nur gcc-4.5.3.orig/gcc/config/rs6000/t-linux64 gcc-4.5.3/gcc/config/rs6000/t-linux64 --- gcc-4.5.3.orig/gcc/config/rs6000/t-linux64 2009-04-21 21:03:23.000000000 +0200 -+++ gcc-4.5.3/gcc/config/rs6000/t-linux64 2011-08-24 02:00:50.000000000 +0200 ++++ gcc-4.5.3/gcc/config/rs6000/t-linux64 2011-08-24 06:35:30.000000000 +0200 @@ -36,7 +36,7 @@ MULTILIB_EXTRA_OPTS = fPIC mstrict-align MULTILIB_EXCEPTIONS = m64/msoft-float @@ -74,3 +74,27 @@ diff -Nur gcc-4.5.3.orig/gcc/config/rs6000/t-linux64 gcc-4.5.3/gcc/config/rs6000 MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT) softfp_wrap_start := '\#ifndef __powerpc64__' +diff -Nur gcc-4.5.3.orig/gcc/config/sparc/linux64.h gcc-4.5.3/gcc/config/sparc/linux64.h +--- gcc-4.5.3.orig/gcc/config/sparc/linux64.h 2010-09-22 23:15:37.000000000 +0200 ++++ gcc-4.5.3/gcc/config/sparc/linux64.h 2011-08-24 06:36:52.000000000 +0200 +@@ -110,7 +110,7 @@ + /* If ELF is the default format, we should not use /lib/elf. */ + + #define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2" +-#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux.so.2" ++#define GLIBC_DYNAMIC_LINKER64 "/lib/ld-linux.so.2" + + #ifdef SPARC_BI_ARCH + +diff -Nur gcc-4.5.3.orig/gcc/config/sparc/t-linux64 gcc-4.5.3/gcc/config/sparc/t-linux64 +--- gcc-4.5.3.orig/gcc/config/sparc/t-linux64 2010-10-04 18:54:26.000000000 +0200 ++++ gcc-4.5.3/gcc/config/sparc/t-linux64 2011-08-24 06:37:15.000000000 +0200 +@@ -26,7 +26,7 @@ + + MULTILIB_OPTIONS = m64/m32 + MULTILIB_DIRNAMES = 64 32 +-MULTILIB_OSDIRNAMES = ../lib64 $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib) ++MULTILIB_OSDIRNAMES = ../lib $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib) + + LIBGCC = stmp-multilib + INSTALL_LIBGCC = install-multilib -- cgit v1.2.3 From a90eb09d8eb3f03d96c5624af558710d6bbe54b5 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 24 Aug 2011 14:05:31 +0200 Subject: ppc64 works with latest qemu, fix kernel config --- target/ppc64/kernel.config | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/target/ppc64/kernel.config b/target/ppc64/kernel.config index 0095cb373..64152ccf6 100644 --- a/target/ppc64/kernel.config +++ b/target/ppc64/kernel.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux/powerpc 2.6.39 Kernel Configuration -# Wed Aug 24 03:57:23 2011 +# Wed Aug 24 13:58:26 2011 # CONFIG_PPC64=y @@ -546,12 +546,7 @@ CONFIG_UNIX98_PTYS=y # # Serial drivers # -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250 is not set # # Non-8250 serial port support @@ -563,7 +558,6 @@ CONFIG_SERIAL_PMACZILOG=y CONFIG_SERIAL_PMACZILOG_TTYS=y CONFIG_SERIAL_PMACZILOG_CONSOLE=y # CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_OF_PLATFORM is not set # CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set # CONFIG_SERIAL_ALTERA_UART is not set -- cgit v1.2.3 From dba3e49a84a07bb1c248d2da9edd0b5d1c502ee8 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 24 Aug 2011 15:37:54 +0200 Subject: now only userland segfaults --- target/sparc64/Makefile | 10 +- target/sparc64/kernel.config | 313 +++++++++++++++++++++++++++++++++---------- 2 files changed, 254 insertions(+), 69 deletions(-) diff --git a/target/sparc64/Makefile b/target/sparc64/Makefile index 39212d52e..3e7240621 100644 --- a/target/sparc64/Makefile +++ b/target/sparc64/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/mk/modules.mk include $(TOPDIR)/mk/kernel-build.mk include $(TOPDIR)/mk/image.mk -KERNEL:=$(LINUX_DIR)/arch/sparc/boot/zImage +KERNEL:=$(LINUX_DIR)/vmlinux ifeq ($(ADK_TARGET_FS),archive) imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) @@ -20,9 +20,17 @@ imageinstall: $(BIN_DIR)/$(INITRAMFS) @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_SPARC64),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-sparc64 -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' +endif endif ifeq ($(ADK_TARGET_FS),initramfs-piggyback) imageinstall: ${BUILD_DIR}/${INITRAMFS_PIGGYBACK} createinitramfs @cp $(KERNEL) $(BIN_DIR)/${TARGET_KERNEL} @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_SPARC64),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-sparc64 -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' +endif endif diff --git a/target/sparc64/kernel.config b/target/sparc64/kernel.config index 494b9c2ea..5c6b6b7f9 100644 --- a/target/sparc64/kernel.config +++ b/target/sparc64/kernel.config @@ -1,26 +1,33 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.36 -# Fri Nov 19 00:15:14 2010 +# Linux/sparc 2.6.39 Kernel Configuration +# Wed Aug 24 15:35:30 2011 # -# CONFIG_64BIT is not set +CONFIG_64BIT=y CONFIG_SPARC=y -CONFIG_SPARC32=y -# CONFIG_SPARC64 is not set -CONFIG_ARCH_DEFCONFIG="arch/sparc/configs/sparc32_defconfig" -CONFIG_BITS=32 -CONFIG_ARCH_USES_GETTIMEOFFSET=y +# CONFIG_SPARC32 is not set +CONFIG_SPARC64=y +CONFIG_ARCH_DEFCONFIG="arch/sparc/configs/sparc64_defconfig" +CONFIG_BITS=64 CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_IOMMU_HELPER=y +CONFIG_QUICKLIST=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_AUDIT_ARCH=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_MMU=y -CONFIG_HIGHMEM=y -CONFIG_ZONE_DMA=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_GENERIC_ISA_DMA=y CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y +CONFIG_HAVE_IRQ_WORK=y # # General setup @@ -37,30 +44,38 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_FHANDLE is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_IRQ_PREFLOW_FASTEOI=y # # RCU Subsystem # -CONFIG_TREE_RCU=y -# CONFIG_TINY_RCU is not set +CONFIG_TINY_RCU=y +# CONFIG_PREEMPT_RCU is not set # CONFIG_RCU_TRACE is not set -CONFIG_RCU_FANOUT=32 -# CONFIG_RCU_FANOUT_EXACT is not set # CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=15 # CONFIG_CGROUPS is not set -# CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set # CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y -CONFIG_EMBEDDED=y +CONFIG_EXPERT=y CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y # CONFIG_KALLSYMS is not set @@ -76,6 +91,7 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_EMBEDDED=y CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_USE_VMALLOC=y @@ -92,9 +108,15 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +# CONFIG_JUMP_LABEL is not set +CONFIG_HAVE_SYSCALL_WRAPPERS=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y # # GCOV-based kernel profiling @@ -110,9 +132,9 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y -# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLOCK_COMPAT=y # # IO Schedulers @@ -164,48 +186,74 @@ CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set CONFIG_HZ=250 # CONFIG_SCHED_HRTICK is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_FIND_BIT_LE=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_EMULATED_CMPXCHG=y +CONFIG_EARLYFB=y +CONFIG_SPARC64_PAGE_SIZE_8KB=y +# CONFIG_SPARC64_PAGE_SIZE_64KB is not set +# CONFIG_SECCOMP is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_CPU_FREQ is not set +# CONFIG_US3_MC is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +# CONFIG_SPARSEMEM_VMEMMAP is not set +CONFIG_HAVE_MEMBLOCK=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y +# CONFIG_COMPACTION is not set +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_SUN_PM=y -# CONFIG_SPARC_LED is not set -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SPARC_LEON is not set +CONFIG_NEED_PER_CPU_KM=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyS0,9600" # # Bus options (PCI etc.) # CONFIG_SBUS=y CONFIG_SBUSCHAR=y +# CONFIG_SUN_LDOMS is not set CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y CONFIG_PCI_SYSCALL=y -# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set # CONFIG_PCCARD is not set -# CONFIG_SUN_OPENPROMFS is not set -CONFIG_SPARC32_PCI=y +CONFIG_SUN_OPENPROMFS=y +CONFIG_SPARC64_PCI=y # # Executable file formats # CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y # CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y CONFIG_NET=y # @@ -217,10 +265,9 @@ CONFIG_UNIX=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set +# CONFIG_NET_IPGRE_DEMUX is not set # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set @@ -248,6 +295,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ATM is not set # CONFIG_L2TP is not set # CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set @@ -261,6 +309,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set # CONFIG_DCB is not set +# CONFIG_BATMAN_ADV is not set # # Network testing @@ -276,6 +325,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set # # Device Drivers @@ -296,11 +346,14 @@ CONFIG_DEVTMPFS_MOUNT=y CONFIG_OF=y # -# Flattened Device Tree and Open Firmware support +# Device Tree and Open Firmware support # +CONFIG_OF_PROMTREE=y CONFIG_OF_DEVICE=y +CONFIG_OF_NET=y # CONFIG_PARPORT is not set # CONFIG_BLK_DEV is not set +# CONFIG_SENSORS_LIS3LV02D is not set # CONFIG_MISC_DEVICES is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -320,19 +373,111 @@ CONFIG_SCSI_MOD=y # # IEEE 1394 (FireWire) support # - -# -# You can enable one or both FireWire driver stacks. -# - -# -# The newer stack is recommended. -# # CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set # CONFIG_FIREWIRE_NOSY is not set # CONFIG_I2O is not set -# CONFIG_NETDEVICES is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +# CONFIG_MII is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_SUNLANCE=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_ETHOC is not set +# CONFIG_GRETH is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_ATL2 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_JME is not set +# CONFIG_STMMAC_ETH is not set +# CONFIG_PCH_GBE is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +# CONFIG_ENIC is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_EN is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_BNA is not set +# CONFIG_SFC is not set +# CONFIG_BE2NET is not set +# CONFIG_TR is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set + +# +# CAIF transport drivers +# +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -376,20 +521,18 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set -# CONFIG_DEVKMEM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_N_GSM is not set # CONFIG_NOZOMI is not set +# CONFIG_N_GSM is not set +# CONFIG_DEVKMEM is not set # # Serial drivers # -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250 is not set # # Non-8250 serial port support @@ -397,8 +540,10 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_MFD_HSU is not set CONFIG_SERIAL_SUNCORE=y # CONFIG_SERIAL_SUNZILOG is not set -# CONFIG_SERIAL_SUNSU is not set +CONFIG_SERIAL_SUNSU=y +CONFIG_SERIAL_SUNSU_CONSOLE=y # CONFIG_SERIAL_SUNSAB is not set +# CONFIG_SERIAL_SUNHV is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set @@ -406,9 +551,8 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set # CONFIG_SERIAL_ALTERA_UART is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_PCH_UART is not set +# CONFIG_TTY_PRINTK is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -424,6 +568,10 @@ CONFIG_DEVPORT=y # PPS support # # CONFIG_PPS is not set + +# +# PPS generators support +# CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_GPIOLIB is not set # CONFIG_W1 is not set @@ -445,6 +593,8 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # # CONFIG_VGA_ARB is not set +# CONFIG_DRM is not set +# CONFIG_STUB_POULSBO is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set # CONFIG_FB is not set @@ -466,6 +616,7 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_NFC_DEVICES is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set CONFIG_RTC_LIB=y @@ -490,6 +641,7 @@ CONFIG_RTC_INTF_DEV=y # # Platform RTC drivers # +CONFIG_RTC_DRV_CMOS=y # CONFIG_RTC_DRV_DS1286 is not set # CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set @@ -499,13 +651,15 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T35 is not set CONFIG_RTC_DRV_M48T59=y # CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set +CONFIG_RTC_DRV_BQ4802=y # CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # # on-CPU RTC drivers # +CONFIG_RTC_DRV_SUN4V=y +CONFIG_RTC_DRV_STARFIRE=y # CONFIG_DMADEVICES is not set # CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set @@ -514,9 +668,12 @@ CONFIG_RTC_DRV_M48T59=y # # Misc Linux/SPARC drivers # -# CONFIG_SUN_OPENPROMIO is not set +CONFIG_SUN_OPENPROMIO=y +# CONFIG_OBP_FLASH is not set # CONFIG_TADPOLE_TS102_UCTRL is not set -# CONFIG_SUN_JSFLASH is not set +# CONFIG_BBC_I2C is not set +# CONFIG_ENVCTRL is not set +# CONFIG_DISPLAY7SEG is not set # # File systems @@ -526,17 +683,19 @@ CONFIG_RTC_DRV_M48T59=y # CONFIG_EXT4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_BTRFS_FS is not set # CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y -# CONFIG_FSNOTIFY is not set +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set +# CONFIG_FANOTIFY is not set # CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set +# CONFIG_QUOTACTL is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -568,6 +727,7 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set # CONFIG_MISC_FILESYSTEMS is not set @@ -580,13 +740,13 @@ CONFIG_TMPFS=y CONFIG_MSDOS_PARTITION=y CONFIG_SUN_PARTITION=y # CONFIG_NLS is not set -# CONFIG_DLM is not set # # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=1024 @@ -595,21 +755,33 @@ CONFIG_FRAME_WARN=1024 # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_SPARSE_RCU_POINTER is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set # CONFIG_DMA_API_DEBUG is not set # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_TEST_KSTRTOX is not set # # Security options # # CONFIG_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set CONFIG_DEFAULT_SECURITY_DAC=y @@ -700,6 +872,8 @@ CONFIG_CRYPTO=y # Random Number Generation # # CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set # CONFIG_CRYPTO_HW is not set # @@ -720,7 +894,10 @@ CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC32=y # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y CONFIG_NLATTR=y +# CONFIG_AVERAGE is not set -- cgit v1.2.3 From a32d9bd883df3ed4ee3fabeca3fcc2e3ba768602 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 24 Aug 2011 15:37:37 +0200 Subject: add Tobias to the list of contributors --- THANKS | 1 + 1 file changed, 1 insertion(+) diff --git a/THANKS b/THANKS index 10b3d1767..1c2fc9d53 100644 --- a/THANKS +++ b/THANKS @@ -4,3 +4,4 @@ reports, patches or good suggestions: Thorsten Glaser Joerg Seitter Phil Sutter +Tobias Breckle -- cgit v1.2.3 From 15ea15f2cff68851af19b0e74a7646eb0ce74002 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 24 Aug 2011 19:04:44 +0200 Subject: remove *.orig files from patch --- target/linux/patches/2.6.39/rb4xx.patch | 33577 ++++++++++++++---------------- 1 file changed, 15268 insertions(+), 18309 deletions(-) diff --git a/target/linux/patches/2.6.39/rb4xx.patch b/target/linux/patches/2.6.39/rb4xx.patch index 49fd204d7..4f2e1cd84 100644 --- a/target/linux/patches/2.6.39/rb4xx.patch +++ b/target/linux/patches/2.6.39/rb4xx.patch @@ -1,681 +1,810 @@ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.39/arch/mips/ar71xx/ar71xx.c ---- linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/ar71xx.c 2011-08-24 02:41:55.227990426 +0200 -@@ -0,0 +1,230 @@ -+/* -+ * AR71xx SoC routines -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include +diff -Nur linux-2.6.39.orig/arch/mips/Kconfig linux-2.6.39/arch/mips/Kconfig +--- linux-2.6.39.orig/arch/mips/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/Kconfig 2011-08-24 18:17:24.000000000 +0200 +@@ -84,6 +84,23 @@ + help + Support for the Atheros AR71XX/AR724X/AR913X SoCs. + ++config ATHEROS_AR71XX ++ bool "Atheros AR71xx based boards" ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select ARCH_REQUIRE_GPIOLIB ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_CPU_MIPS32_R2 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_HAS_EARLY_PRINTK ++ select MIPS_MACHINE ++ help ++ Support for Atheros AR71xx based boards. + -+#include + config BCM47XX + bool "Broadcom BCM47XX based boards" + select CEVT_R4K +@@ -739,6 +756,7 @@ + endchoice + + source "arch/mips/alchemy/Kconfig" ++source "arch/mips/ar71xx/Kconfig" + source "arch/mips/ath79/Kconfig" + source "arch/mips/bcm63xx/Kconfig" + source "arch/mips/jazz/Kconfig" +@@ -907,6 +925,9 @@ + config MIPS_DISABLE_OBSOLETE_IDE + bool + ++config MYLOADER ++ bool + -+static DEFINE_MUTEX(ar71xx_flash_mutex); -+static DEFINE_SPINLOCK(ar71xx_device_lock); + config SYNC_R4K + bool + +diff -Nur linux-2.6.39.orig/arch/mips/Makefile linux-2.6.39/arch/mips/Makefile +--- linux-2.6.39.orig/arch/mips/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/Makefile 2011-08-24 18:17:24.000000000 +0200 +@@ -158,6 +158,13 @@ + endif + cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1 + ++# ++# Atheros AR71xx ++# ++core-$(CONFIG_ATHEROS_AR71XX) += arch/mips/ar71xx/ ++cflags-$(CONFIG_ATHEROS_AR71XX) += -I$(srctree)/arch/mips/include/asm/mach-ar71xx ++load-$(CONFIG_ATHEROS_AR71XX) += 0xffffffff80060000 + -+void __iomem *ar71xx_ddr_base; -+EXPORT_SYMBOL_GPL(ar71xx_ddr_base); + cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,) + cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,) + cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,) +@@ -174,6 +181,7 @@ + # + libs-$(CONFIG_ARC) += arch/mips/fw/arc/ + libs-$(CONFIG_CFE) += arch/mips/fw/cfe/ ++libs-$(CONFIG_MYLOADER) += arch/mips/fw/myloader/ + libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/ + libs-y += arch/mips/fw/lib/ + +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Kconfig linux-2.6.39/arch/mips/ar71xx/Kconfig +--- linux-2.6.39.orig/arch/mips/ar71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/Kconfig 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,420 @@ ++if ATHEROS_AR71XX + -+void __iomem *ar71xx_pll_base; -+EXPORT_SYMBOL_GPL(ar71xx_pll_base); ++menu "Atheros AR71xx machine selection" + -+void __iomem *ar71xx_reset_base; -+EXPORT_SYMBOL_GPL(ar71xx_reset_base); ++config AR71XX_MACH_AP81 ++ bool "Atheros AP81 board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+void __iomem *ar71xx_gpio_base; -+EXPORT_SYMBOL_GPL(ar71xx_gpio_base); ++config AR71XX_MACH_AP83 ++ bool "Atheros AP83 board support" ++ select SOC_AR913X ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+void __iomem *ar71xx_usb_ctrl_base; -+EXPORT_SYMBOL_GPL(ar71xx_usb_ctrl_base); ++config AR71XX_MACH_AP96 ++ bool "Atheros AP96 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP94_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+void ar71xx_device_stop(u32 mask) -+{ -+ unsigned long flags; -+ u32 mask_inv; -+ u32 t; ++config AR71XX_MACH_AP121 ++ bool "Atheros AP121 board support" ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ select AR71XX_DEV_AR9XXX_WMAC ++ select SOC_AR933X ++ default n + -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | mask); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_DB120 ++ bool "Atheros DB120 board support" ++ select SOC_AR934X ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_DB120_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240; -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); -+ t |= mask; -+ t &= ~mask_inv; -+ ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_DIR_600_A1 ++ bool "D-Link DIR-600 rev. A1 support" ++ select SOC_AR724X ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_NVRAM ++ default n + -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t | mask); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_DIR_615_C1 ++ bool "D-Link DIR-615 rev. C1 support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_NVRAM ++ default n + -+ case AR71XX_SOC_AR9330: -+ case AR71XX_SOC_AR9331: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR933X_RESET_REG_RESET_MODULE, t | mask); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_DIR_825_B1 ++ bool "D-Link DIR-825 rev. B1 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP94_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ case AR71XX_SOC_AR9341: -+ case AR71XX_SOC_AR9342: -+ case AR71XX_SOC_AR9344: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR934X_RESET_REG_RESET_MODULE, t | mask); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_JA76PF ++ bool "jjPlus JA76PF board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ default: -+ BUG(); -+ } -+} -+EXPORT_SYMBOL_GPL(ar71xx_device_stop); ++config AR71XX_MACH_JWAP003 ++ bool "jjPlus JWAP003 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_USB ++ default n + -+void ar71xx_device_start(u32 mask) -+{ -+ unsigned long flags; -+ u32 mask_inv; -+ u32 t; ++config AR71XX_MACH_PB42 ++ bool "Atheros PB42 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ default n + -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t & ~mask); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_PB44 ++ bool "Atheros PB44 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240; -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); -+ t &= ~mask; -+ t |= mask_inv; -+ ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_PB92 ++ bool "Atheros PB92 board support" ++ select SOC_AR724X ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB9X_PCI if PCI ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t & ~mask); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_AW_NR580 ++ bool "AzureWave AW-NR580 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+ case AR71XX_SOC_AR9330: -+ case AR71XX_SOC_AR9331: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR933X_RESET_REG_RESET_MODULE, t & ~mask); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_WZR_HP_AG300H ++ bool "Buffalo WZR-HP-AG300H board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ case AR71XX_SOC_AR9341: -+ case AR71XX_SOC_AR9342: -+ case AR71XX_SOC_AR9344: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE); -+ ar71xx_reset_wr(AR934X_RESET_REG_RESET_MODULE, t & ~mask); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_WZR_HP_G300NH ++ bool "Buffalo WZR-HP-G300NH board support" ++ select SOC_AR913X ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ select RTL8366_SMI ++ default n + -+ default: -+ BUG(); -+ } -+} -+EXPORT_SYMBOL_GPL(ar71xx_device_start); ++config AR71XX_MACH_WP543 ++ bool "Compex WP543/WPJ543 board support" ++ select SOC_AR71XX ++ select MYLOADER ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+int ar71xx_device_stopped(u32 mask) -+{ -+ unsigned long flags; -+ u32 t; ++config AR71XX_MACH_WRT160NL ++ bool "Linksys WRT160NL board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ select AR71XX_NVRAM ++ default n + -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_WRT400N ++ bool "Linksys WRT400N board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_AP94_PCI if PCI ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_RB4XX ++ bool "MikroTik RouterBOARD 4xx series support" ++ select SOC_AR71XX ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_RB750 ++ bool "MikroTik RouterBOARD 750 support" ++ select SOC_AR724X ++ default n + -+ case AR71XX_SOC_AR9330: -+ case AR71XX_SOC_AR9331: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_WNDR3700 ++ bool "NETGEAR WNDR3700 board support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP94_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ case AR71XX_SOC_AR9341: -+ case AR71XX_SOC_AR9342: -+ case AR71XX_SOC_AR9344: -+ spin_lock_irqsave(&ar71xx_device_lock, flags); -+ t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE); -+ spin_unlock_irqrestore(&ar71xx_device_lock, flags); -+ break; ++config AR71XX_MACH_WNR2000 ++ bool "NETGEAR WNR2000 board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+ default: -+ BUG(); -+ } ++config AR71XX_MACH_MZK_W04NU ++ bool "Planex MZK-W04NU board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+ return ((t & mask) == mask); -+} -+EXPORT_SYMBOL_GPL(ar71xx_device_stopped); ++config AR71XX_MACH_MZK_W300NH ++ bool "Planex MZK-W300NH board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+void ar71xx_ddr_flush(u32 reg) -+{ -+ ar71xx_ddr_wr(reg, 1); -+ while ((ar71xx_ddr_rr(reg) & 0x1)) -+ ; ++config AR71XX_MACH_NBG460N ++ bool "Zyxel NBG460N/550N/550NH board support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+ ar71xx_ddr_wr(reg, 1); -+ while ((ar71xx_ddr_rr(reg) & 0x1)) -+ ; -+} -+EXPORT_SYMBOL_GPL(ar71xx_ddr_flush); ++config AR71XX_MACH_TL_MR3X20 ++ bool "TP-LINK TL-MR3220/3420 support" ++ select SOC_AR724X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+void ar71xx_flash_acquire(void) -+{ -+ mutex_lock(&ar71xx_flash_mutex); -+} -+EXPORT_SYMBOL_GPL(ar71xx_flash_acquire); ++config AR71XX_MACH_TL_WA901ND ++ bool "TP-LINK TL-WA901ND support" ++ select SOC_AR724X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+void ar71xx_flash_release(void) -+{ -+ mutex_unlock(&ar71xx_flash_mutex); -+} -+EXPORT_SYMBOL_GPL(ar71xx_flash_release); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.c 2011-08-24 02:41:55.277990824 +0200 -@@ -0,0 +1,71 @@ -+/* -+ * Atheros AP91 reference board PCI initialization -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++config AR71XX_MACH_TL_WA901ND_V2 ++ bool "TP-LINK TL-WA901ND v2 support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+#include -+#include -+#include ++config AR71XX_MACH_TL_WR741ND ++ bool "TP-LINK TL-WR741ND support" ++ select SOC_AR724X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+#include -+#include ++config AR71XX_MACH_TL_WR841N_V1 ++ bool "TP-LINK TL-WR841N v1 support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_DSA ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+#include "dev-ap91-pci.h" -+#include "pci-ath9k-fixup.h" ++config AR71XX_MACH_TL_WR941ND ++ bool "TP-LINK TL-WR941ND support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_DSA ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+static struct ath9k_platform_data ap91_wmac_data = { -+ .led_pin = -1, -+}; -+static char ap91_wmac_mac[6]; ++config AR71XX_MACH_TL_WR1043ND ++ bool "TP-LINK TL-WR1043ND support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_USB ++ default n + -+static struct ar71xx_pci_irq ap91_pci_irqs[] __initdata = { -+ { -+ .slot = 0, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV0, -+ } -+}; ++config AR71XX_MACH_TEW_632BRP ++ bool "TRENDnet TEW-632BRP support" ++ select SOC_AR913X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AR9XXX_WMAC ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_NVRAM ++ default n + -+static int ap91_pci_plat_dev_init(struct pci_dev *dev) -+{ -+ switch (PCI_SLOT(dev->devfn)) { -+ case 0: -+ dev->dev.platform_data = &ap91_wmac_data; -+ break; -+ } ++config AR71XX_MACH_UBNT ++ bool "Ubiquiti AR71xx based boards support" ++ select SOC_AR71XX ++ select SOC_AR724X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ select AR71XX_DEV_PB42_PCI if PCI ++ select AR71XX_DEV_USB ++ default n + -+ return 0; -+} ++config AR71XX_MACH_EAP7660D ++ bool "Senao EAP7660D support" ++ select SOC_AR71XX ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+__init void ap91_pci_setup_wmac_led_pin(int pin) -+{ -+ ap91_wmac_data.led_pin = pin; -+} ++config AR71XX_MACH_ZCN_1523H ++ bool "Zcomax ZCN-1523H support" ++ select SOC_AR724X ++ select AR71XX_DEV_M25P80 ++ select AR71XX_DEV_AP91_PCI if PCI ++ select AR71XX_DEV_GPIO_BUTTONS ++ select AR71XX_DEV_LEDS_GPIO ++ default n + -+__init void ap91_pci_setup_wmac_gpio(u32 mask, u32 val) -+{ -+ ap91_wmac_data.gpio_mask = mask; -+ ap91_wmac_data.gpio_val = val; -+} ++endmenu + -+void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr) -+{ -+ if (cal_data) -+ memcpy(ap91_wmac_data.eeprom_data, cal_data, -+ sizeof(ap91_wmac_data.eeprom_data)); ++config SOC_AR71XX ++ bool ++ select USB_ARCH_HAS_EHCI ++ select USB_ARCH_HAS_OHCI + -+ if (mac_addr) { -+ memcpy(ap91_wmac_mac, mac_addr, sizeof(ap91_wmac_mac)); -+ ap91_wmac_data.macaddr = ap91_wmac_mac; -+ } ++config SOC_AR724X ++ bool ++ select USB_ARCH_HAS_EHCI ++ select USB_ARCH_HAS_OHCI + -+ ar71xx_pci_plat_dev_init = ap91_pci_plat_dev_init; -+ ar71xx_pci_init(ARRAY_SIZE(ap91_pci_irqs), ap91_pci_irqs); ++config SOC_AR913X ++ bool ++ select USB_ARCH_HAS_EHCI + -+ pci_enable_ath9k_fixup(0, ap91_wmac_data.eeprom_data); -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.h linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.h 2011-08-24 02:41:55.287981779 +0200 -@@ -0,0 +1,25 @@ -+/* -+ * Atheros AP91 reference board PCI initialization -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++config SOC_AR934X ++ bool ++ select USB_ARCH_HAS_EHCI + -+#ifndef _AR71XX_DEV_AP91_PCI_H -+#define _AR71XX_DEV_AP91_PCI_H ++config AR71XX_DEV_M25P80 ++ def_bool n + -+#if defined(CONFIG_AR71XX_DEV_AP91_PCI) -+void ap91_pci_init(u8 *cal_data, u8 *mac_addr) __init; -+void ap91_pci_setup_wmac_led_pin(int pin) __init; -+void ap91_pci_setup_wmac_gpio(u32 mask, u32 val) __init; -+#else -+static inline void ap91_pci_init(u8 *cal_data, u8 *mac_addr) { } -+static inline void ap91_pci_setup_wmac_led_pin(int pin) { } -+static inline void ap91_pci_setup_wmac_gpio(u32 mask, u32 gpio) { } -+#endif ++config AR71XX_DEV_AP91_PCI ++ select AR71XX_PCI_ATH9K_FIXUP ++ def_bool n + -+#endif /* _AR71XX_DEV_AP91_PCI_H */ ++config AR71XX_DEV_AP94_PCI ++ select AR71XX_PCI_ATH9K_FIXUP ++ def_bool n + -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.c 2011-08-24 02:41:55.287981779 +0200 -@@ -0,0 +1,109 @@ -+/* -+ * Atheros AP94 reference board PCI initialization -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++config AR71XX_DEV_AR9XXX_WMAC ++ def_bool n + -+#include -+#include -+#include ++config AR71XX_DEV_DB120_PCI ++ select AR71XX_PCI_ATH9K_FIXUP ++ def_bool n + -+#include -+#include ++config AR71XX_DEV_DSA ++ def_bool n + -+#include "dev-ap94-pci.h" -+#include "pci-ath9k-fixup.h" ++config AR71XX_DEV_GPIO_BUTTONS ++ def_bool n + -+static struct ath9k_platform_data ap94_wmac0_data = { -+ .led_pin = -1, -+}; -+static struct ath9k_platform_data ap94_wmac1_data = { -+ .led_pin = -1, -+}; -+static char ap94_wmac0_mac[6]; -+static char ap94_wmac1_mac[6]; ++config AR71XX_DEV_LEDS_GPIO ++ def_bool n + -+static struct ar71xx_pci_irq ap94_pci_irqs[] __initdata = { -+ { -+ .slot = 0, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV0, -+ }, { -+ .slot = 1, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV1, -+ } -+}; ++config AR71XX_DEV_PB42_PCI ++ def_bool n + -+static int ap94_pci_plat_dev_init(struct pci_dev *dev) -+{ -+ switch (PCI_SLOT(dev->devfn)) { -+ case 17: -+ dev->dev.platform_data = &ap94_wmac0_data; -+ break; ++config AR71XX_DEV_PB9X_PCI ++ def_bool n + -+ case 18: -+ dev->dev.platform_data = &ap94_wmac1_data; -+ break; -+ } ++config AR71XX_DEV_USB ++ def_bool n + -+ return 0; -+} ++config AR71XX_NVRAM ++ def_bool n + -+__init void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin) -+{ -+ switch (wmac) { -+ case 0: -+ ap94_wmac0_data.led_pin = pin; -+ break; -+ case 1: -+ ap94_wmac1_data.led_pin = pin; -+ break; -+ } -+} -+ -+__init void ap94_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val) -+{ -+ switch (wmac) { -+ case 0: -+ ap94_wmac0_data.gpio_mask = mask; -+ ap94_wmac0_data.gpio_val = val; -+ break; -+ case 1: -+ ap94_wmac1_data.gpio_mask = mask; -+ ap94_wmac1_data.gpio_val = val; -+ break; -+ } -+} -+ -+void __init ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, -+ u8 *cal_data1, u8 *mac_addr1) -+{ -+ if (cal_data0) -+ memcpy(ap94_wmac0_data.eeprom_data, cal_data0, -+ sizeof(ap94_wmac0_data.eeprom_data)); -+ -+ if (cal_data1) -+ memcpy(ap94_wmac1_data.eeprom_data, cal_data1, -+ sizeof(ap94_wmac1_data.eeprom_data)); -+ -+ if (mac_addr0) { -+ memcpy(ap94_wmac0_mac, mac_addr0, sizeof(ap94_wmac0_mac)); -+ ap94_wmac0_data.macaddr = ap94_wmac0_mac; -+ } -+ -+ if (mac_addr1) { -+ memcpy(ap94_wmac1_mac, mac_addr1, sizeof(ap94_wmac1_mac)); -+ ap94_wmac1_data.macaddr = ap94_wmac1_mac; -+ } -+ -+ ar71xx_pci_plat_dev_init = ap94_pci_plat_dev_init; -+ ar71xx_pci_init(ARRAY_SIZE(ap94_pci_irqs), ap94_pci_irqs); -+ -+ pci_enable_ath9k_fixup(17, ap94_wmac0_data.eeprom_data); -+ pci_enable_ath9k_fixup(18, ap94_wmac1_data.eeprom_data); -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.h linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.h 2011-08-24 02:41:55.287981779 +0200 -@@ -0,0 +1,31 @@ -+/* -+ * Atheros AP94 reference board PCI initialization -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++config AR71XX_PCI_ATH9K_FIXUP ++ def_bool n + -+#ifndef _AR71XX_DEV_AP94_PCI_H -+#define _AR71XX_DEV_AP94_PCI_H ++config SOC_AR933X ++ bool ++ select USB_ARCH_HAS_EHCI + -+#if defined(CONFIG_AR71XX_DEV_AP94_PCI) -+void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, -+ u8 *cal_data1, u8 *mac_addr1) __init; ++endif +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Makefile linux-2.6.39/arch/mips/ar71xx/Makefile +--- linux-2.6.39.orig/arch/mips/ar71xx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/Makefile 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,67 @@ ++# ++# Makefile for the Atheros AR71xx SoC specific parts of the kernel ++# ++# Copyright (C) 2008-2009 Gabor Juhos ++# Copyright (C) 2008 Imre Kaloz ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License version 2 as published ++# by the Free Software Foundation. + -+void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin) __init; -+void ap94_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val) __init; ++obj-y := prom.o irq.o setup.o devices.o gpio.o ar71xx.o + -+#else -+static inline void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, -+ u8 *cal_data1, u8 *mac_addr1) {} ++obj-$(CONFIG_EARLY_PRINTK) += early_printk.o ++obj-$(CONFIG_PCI) += pci.o + -+static inline void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin) {} -+static inline void ap94_pci_setup_wmac_gpio(unsigned wmac, -+ u32 mask, u32 val) {} -+#endif ++obj-$(CONFIG_AR71XX_DEV_AP91_PCI) += dev-ap91-pci.o ++obj-$(CONFIG_AR71XX_DEV_AP94_PCI) += dev-ap94-pci.o ++obj-$(CONFIG_AR71XX_DEV_AR9XXX_WMAC) += dev-ar9xxx-wmac.o ++obj-$(CONFIG_AR71XX_DEV_DB120_PCI) += dev-db120-pci.o ++obj-$(CONFIG_AR71XX_DEV_DSA) += dev-dsa.o ++obj-$(CONFIG_AR71XX_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o ++obj-$(CONFIG_AR71XX_DEV_LEDS_GPIO) += dev-leds-gpio.o ++obj-$(CONFIG_AR71XX_DEV_M25P80) += dev-m25p80.o ++obj-$(CONFIG_AR71XX_DEV_PB42_PCI) += dev-pb42-pci.o ++obj-$(CONFIG_AR71XX_DEV_PB9X_PCI) += dev-pb9x-pci.o ++obj-$(CONFIG_AR71XX_DEV_USB) += dev-usb.o + -+#endif /* _AR71XX_DEV_AP94_PCI_H */ ++obj-$(CONFIG_AR71XX_NVRAM) += nvram.o ++obj-$(CONFIG_AR71XX_PCI_ATH9K_FIXUP) += pci-ath9k-fixup.o + -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.c linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.c 2011-08-24 02:41:55.287981779 +0200 -@@ -0,0 +1,154 @@ ++obj-$(CONFIG_AR71XX_MACH_AP121) += mach-ap121.o ++obj-$(CONFIG_AR71XX_MACH_AP81) += mach-ap81.o ++obj-$(CONFIG_AR71XX_MACH_AP83) += mach-ap83.o ++obj-$(CONFIG_AR71XX_MACH_AP96) += mach-ap96.o ++obj-$(CONFIG_AR71XX_MACH_AW_NR580) += mach-aw-nr580.o ++obj-$(CONFIG_AR71XX_MACH_DB120) += mach-db120.o ++obj-$(CONFIG_AR71XX_MACH_DIR_600_A1) += mach-dir-600-a1.o ++obj-$(CONFIG_AR71XX_MACH_DIR_615_C1) += mach-dir-615-c1.o ++obj-$(CONFIG_AR71XX_MACH_DIR_825_B1) += mach-dir-825-b1.o ++obj-$(CONFIG_AR71XX_MACH_EAP7660D) += mach-eap7660d.o ++obj-$(CONFIG_AR71XX_MACH_JA76PF) += mach-ja76pf.o ++obj-$(CONFIG_AR71XX_MACH_JWAP003) += mach-jwap003.o ++obj-$(CONFIG_AR71XX_MACH_MZK_W04NU) += mach-mzk-w04nu.o ++obj-$(CONFIG_AR71XX_MACH_MZK_W300NH) += mach-mzk-w300nh.o ++obj-$(CONFIG_AR71XX_MACH_NBG460N) += mach-nbg460n.o ++obj-$(CONFIG_AR71XX_MACH_PB42) += mach-pb42.o ++obj-$(CONFIG_AR71XX_MACH_PB44) += mach-pb44.o ++obj-$(CONFIG_AR71XX_MACH_PB92) += mach-pb92.o ++obj-$(CONFIG_AR71XX_MACH_RB4XX) += mach-rb4xx.o ++obj-$(CONFIG_AR71XX_MACH_RB750) += mach-rb750.o ++obj-$(CONFIG_AR71XX_MACH_TEW_632BRP) += mach-tew-632brp.o ++obj-$(CONFIG_AR71XX_MACH_TL_MR3X20) += mach-tl-mr3x20.o ++obj-$(CONFIG_AR71XX_MACH_TL_WA901ND) += mach-tl-wa901nd.o ++obj-$(CONFIG_AR71XX_MACH_TL_WA901ND_V2) += mach-tl-wa901nd-v2.o ++obj-$(CONFIG_AR71XX_MACH_TL_WR741ND) += mach-tl-wr741nd.o ++obj-$(CONFIG_AR71XX_MACH_TL_WR841N_V1) += mach-tl-wr841n.o ++obj-$(CONFIG_AR71XX_MACH_TL_WR941ND) += mach-tl-wr941nd.o ++obj-$(CONFIG_AR71XX_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o ++obj-$(CONFIG_AR71XX_MACH_UBNT) += mach-ubnt.o ++obj-$(CONFIG_AR71XX_MACH_WNDR3700) += mach-wndr3700.o ++obj-$(CONFIG_AR71XX_MACH_WNR2000) += mach-wnr2000.o ++obj-$(CONFIG_AR71XX_MACH_WP543) += mach-wp543.o ++obj-$(CONFIG_AR71XX_MACH_WRT160NL) += mach-wrt160nl.o ++obj-$(CONFIG_AR71XX_MACH_WRT400N) += mach-wrt400n.o ++obj-$(CONFIG_AR71XX_MACH_WZR_HP_G300NH) += mach-wzr-hp-g300nh.o ++obj-$(CONFIG_AR71XX_MACH_WZR_HP_AG300H) += mach-wzr-hp-ag300h.o ++obj-$(CONFIG_AR71XX_MACH_ZCN_1523H) += mach-zcn-1523h.o +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.39/arch/mips/ar71xx/ar71xx.c +--- linux-2.6.39.orig/arch/mips/ar71xx/ar71xx.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/ar71xx.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,230 @@ +/* -+ * Atheros AR9XXX SoCs built-in WMAC device support ++ * AR71xx SoC routines + * -+ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * -+ * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP -+ * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include -+#include -+#include -+#include -+#include -+#include ++#include ++#include ++#include ++#include + +#include + -+#include "dev-ar9xxx-wmac.h" -+ -+#define MHZ_25 (25 * 1000 * 1000) -+ -+static struct ath9k_platform_data ar9xxx_wmac_data = { -+ .led_pin = -1, -+}; -+static char ar9xxx_wmac_mac[6]; -+ -+static struct resource ar9xxx_wmac_resources[] = { -+ { -+ /* .start and .end fields are filled dynamically */ -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = AR71XX_CPU_IRQ_IP2, -+ .end = AR71XX_CPU_IRQ_IP2, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; ++static DEFINE_MUTEX(ar71xx_flash_mutex); ++static DEFINE_SPINLOCK(ar71xx_device_lock); + -+static struct platform_device ar9xxx_wmac_device = { -+ .name = "ath9k", -+ .id = -1, -+ .resource = ar9xxx_wmac_resources, -+ .num_resources = ARRAY_SIZE(ar9xxx_wmac_resources), -+ .dev = { -+ .platform_data = &ar9xxx_wmac_data, -+ }, -+}; ++void __iomem *ar71xx_ddr_base; ++EXPORT_SYMBOL_GPL(ar71xx_ddr_base); + -+static void ar913x_wmac_init(void) -+{ -+ ar71xx_device_stop(RESET_MODULE_AMBA2WMAC); -+ mdelay(10); ++void __iomem *ar71xx_pll_base; ++EXPORT_SYMBOL_GPL(ar71xx_pll_base); + -+ ar71xx_device_start(RESET_MODULE_AMBA2WMAC); -+ mdelay(10); ++void __iomem *ar71xx_reset_base; ++EXPORT_SYMBOL_GPL(ar71xx_reset_base); + -+ ar9xxx_wmac_resources[0].start = AR91XX_WMAC_BASE; -+ ar9xxx_wmac_resources[0].end = AR91XX_WMAC_BASE + AR91XX_WMAC_SIZE - 1; -+} ++void __iomem *ar71xx_gpio_base; ++EXPORT_SYMBOL_GPL(ar71xx_gpio_base); + -+static int ar933x_r1_get_wmac_revision(void) -+{ -+ return ar71xx_soc_rev; -+} ++void __iomem *ar71xx_usb_ctrl_base; ++EXPORT_SYMBOL_GPL(ar71xx_usb_ctrl_base); + -+static int ar933x_wmac_reset(void) ++void ar71xx_device_stop(u32 mask) +{ -+ unsigned retries = 0; ++ unsigned long flags; ++ u32 mask_inv; ++ u32 t; + -+ ar71xx_device_stop(AR933X_RESET_WMAC); -+ ar71xx_device_start(AR933X_RESET_WMAC); ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+ while (1) { -+ u32 bootstrap; ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240; ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); ++ t |= mask; ++ t &= ~mask_inv; ++ ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+ bootstrap = ar71xx_reset_rr(AR933X_RESET_REG_BOOTSTRAP); -+ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0) -+ return 0; ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t | mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+ if (retries > 20) -+ break; ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR933X_RESET_REG_RESET_MODULE, t | mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+ udelay(10000); -+ retries++; -+ } ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR934X_RESET_REG_RESET_MODULE, t | mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+ pr_err("ar93xx: WMAC reset timed out"); -+ return -ETIMEDOUT; ++ default: ++ BUG(); ++ } +} ++EXPORT_SYMBOL_GPL(ar71xx_device_stop); + -+static void ar933x_wmac_init(void) ++void ar71xx_device_start(u32 mask) +{ -+ ar9xxx_wmac_device.name = "ar933x_wmac"; -+ ar9xxx_wmac_resources[0].start = AR933X_WMAC_BASE; -+ ar9xxx_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; -+ if (ar71xx_ref_freq == MHZ_25) -+ ar9xxx_wmac_data.is_clk_25mhz = true; ++ unsigned long flags; ++ u32 mask_inv; ++ u32 t; + -+ if (ar71xx_soc_rev == 1) -+ ar9xxx_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision; ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t & ~mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+ ar9xxx_wmac_data.external_reset = ar933x_wmac_reset; ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240; ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); ++ t &= ~mask; ++ t |= mask_inv; ++ ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+ ar933x_wmac_reset(); -+} ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t & ~mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; + -+static void ar934x_wmac_init(void) -+{ -+ ar9xxx_wmac_device.name = "ar934x_wmac"; -+ ar9xxx_wmac_resources[0].start = AR934X_WMAC_BASE; -+ ar9xxx_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1; -+ if (ar71xx_ref_freq == MHZ_25) -+ ar9xxx_wmac_data.is_clk_25mhz = true; ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR933X_RESET_REG_RESET_MODULE, t & ~mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; ++ ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE); ++ ar71xx_reset_wr(AR934X_RESET_REG_RESET_MODULE, t & ~mask); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; ++ ++ default: ++ BUG(); ++ } +} ++EXPORT_SYMBOL_GPL(ar71xx_device_start); + -+void __init ar9xxx_add_device_wmac(u8 *cal_data, u8 *mac_addr) ++int ar71xx_device_stopped(u32 mask) +{ ++ unsigned long flags; ++ u32 t; ++ + switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; ++ ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); ++ break; ++ + case AR71XX_SOC_AR9130: + case AR71XX_SOC_AR9132: -+ ar913x_wmac_init(); ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); + break; + + case AR71XX_SOC_AR9330: + case AR71XX_SOC_AR9331: -+ ar933x_wmac_init(); ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR933X_RESET_REG_RESET_MODULE); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); + break; + + case AR71XX_SOC_AR9341: + case AR71XX_SOC_AR9342: + case AR71XX_SOC_AR9344: -+ ar934x_wmac_init(); ++ spin_lock_irqsave(&ar71xx_device_lock, flags); ++ t = ar71xx_reset_rr(AR934X_RESET_REG_RESET_MODULE); ++ spin_unlock_irqrestore(&ar71xx_device_lock, flags); + break; + + default: + BUG(); + } + -+ if (cal_data) -+ memcpy(ar9xxx_wmac_data.eeprom_data, cal_data, -+ sizeof(ar9xxx_wmac_data.eeprom_data)); ++ return ((t & mask) == mask); ++} ++EXPORT_SYMBOL_GPL(ar71xx_device_stopped); + -+ if (mac_addr) { -+ memcpy(ar9xxx_wmac_mac, mac_addr, sizeof(ar9xxx_wmac_mac)); -+ ar9xxx_wmac_data.macaddr = ar9xxx_wmac_mac; -+ } ++void ar71xx_ddr_flush(u32 reg) ++{ ++ ar71xx_ddr_wr(reg, 1); ++ while ((ar71xx_ddr_rr(reg) & 0x1)) ++ ; + -+ platform_device_register(&ar9xxx_wmac_device); ++ ar71xx_ddr_wr(reg, 1); ++ while ((ar71xx_ddr_rr(reg) & 0x1)) ++ ; +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.h linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.h 2011-08-24 02:41:55.297981663 +0200 -@@ -0,0 +1,20 @@ -+/* -+ * Atheros AR9XXX SoCs built-in WMAC device support -+ * -+ * Copyright (C) 2010-2011 Jaiganesh Narayanan -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _AR71XX_DEV_AR9XXX_WMAC_H -+#define _AR71XX_DEV_AR9XXX_WMAC_H ++EXPORT_SYMBOL_GPL(ar71xx_ddr_flush); + -+void ar9xxx_add_device_wmac(u8 *cal_data, u8 *mac_addr) __init; ++void ar71xx_flash_acquire(void) ++{ ++ mutex_lock(&ar71xx_flash_mutex); ++} ++EXPORT_SYMBOL_GPL(ar71xx_flash_acquire); + -+#endif /* _AR71XX_DEV_AR9XXX_WMAC_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.c linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.c 2011-08-24 02:41:55.317990461 +0200 -@@ -0,0 +1,31 @@ ++void ar71xx_flash_release(void) ++{ ++ mutex_unlock(&ar71xx_flash_mutex); ++} ++EXPORT_SYMBOL_GPL(ar71xx_flash_release); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,71 @@ +/* -+ * Atheros db120 reference board PCI initialization -+ * -+ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Atheros AP91 reference board PCI initialization + * -+ * Parts of this file are based on Atheros linux 2.6.31 BSP ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -683,13 +812,21 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.c linux-2.6.39/arch/m + */ + +#include ++#include ++#include + +#include +#include + -+#include "dev-db120-pci.h" ++#include "dev-ap91-pci.h" ++#include "pci-ath9k-fixup.h" + -+static struct ar71xx_pci_irq db120_pci_irqs[] __initdata = { ++static struct ath9k_platform_data ap91_wmac_data = { ++ .led_pin = -1, ++}; ++static char ap91_wmac_mac[6]; ++ ++static struct ar71xx_pci_irq ap91_pci_irqs[] __initdata = { + { + .slot = 0, + .pin = 1, @@ -697,216 +834,233 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.c linux-2.6.39/arch/m + } +}; + -+void __init db120_pci_init(void) ++static int ap91_pci_plat_dev_init(struct pci_dev *dev) +{ -+ ar71xx_pci_init(ARRAY_SIZE(db120_pci_irqs), db120_pci_irqs); ++ switch (PCI_SLOT(dev->devfn)) { ++ case 0: ++ dev->dev.platform_data = &ap91_wmac_data; ++ break; ++ } ++ ++ return 0; +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.h linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.h 2011-08-24 02:41:55.327990934 +0200 -@@ -0,0 +1,22 @@ ++ ++__init void ap91_pci_setup_wmac_led_pin(int pin) ++{ ++ ap91_wmac_data.led_pin = pin; ++} ++ ++__init void ap91_pci_setup_wmac_gpio(u32 mask, u32 val) ++{ ++ ap91_wmac_data.gpio_mask = mask; ++ ap91_wmac_data.gpio_val = val; ++} ++ ++void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr) ++{ ++ if (cal_data) ++ memcpy(ap91_wmac_data.eeprom_data, cal_data, ++ sizeof(ap91_wmac_data.eeprom_data)); ++ ++ if (mac_addr) { ++ memcpy(ap91_wmac_mac, mac_addr, sizeof(ap91_wmac_mac)); ++ ap91_wmac_data.macaddr = ap91_wmac_mac; ++ } ++ ++ ar71xx_pci_plat_dev_init = ap91_pci_plat_dev_init; ++ ar71xx_pci_init(ARRAY_SIZE(ap91_pci_irqs), ap91_pci_irqs); ++ ++ pci_enable_ath9k_fixup(0, ap91_wmac_data.eeprom_data); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.h linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap91-pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-ap91-pci.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,25 @@ +/* -+ * Atheros DB120 reference board PCI initialization -+ * -+ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Atheros AP91 reference board PCI initialization + * -+ * Parts of this file are based on Atheros linux 2.6.31 BSP ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#ifndef _AR71XX_DEV_DB120_PCI_H -+#define _AR71XX_DEV_DB120_PCI_H -+ -+#if defined(CONFIG_AR71XX_DEV_DB120_PCI) -+void db120_pci_init(void); ++#ifndef _AR71XX_DEV_AP91_PCI_H ++#define _AR71XX_DEV_AP91_PCI_H ++ ++#if defined(CONFIG_AR71XX_DEV_AP91_PCI) ++void ap91_pci_init(u8 *cal_data, u8 *mac_addr) __init; ++void ap91_pci_setup_wmac_led_pin(int pin) __init; ++void ap91_pci_setup_wmac_gpio(u32 mask, u32 val) __init; +#else -+static inline void db120_pci_init(void) { } ++static inline void ap91_pci_init(u8 *cal_data, u8 *mac_addr) { } ++static inline void ap91_pci_setup_wmac_led_pin(int pin) { } ++static inline void ap91_pci_setup_wmac_gpio(u32 mask, u32 gpio) { } +#endif + -+#endif /* _AR71XX_DEV_DB120_PCI_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c linux-2.6.39/arch/mips/ar71xx/dev-dsa.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.c 2011-08-24 02:41:55.337990441 +0200 -@@ -0,0 +1,50 @@ ++#endif /* _AR71XX_DEV_AP91_PCI_H */ ++ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,109 @@ +/* -+ * Atheros AR71xx DSA switch device support ++ * Atheros AP94 reference board PCI initialization + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009-2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include ++#include ++#include ++#include + +#include ++#include + -+#include "devices.h" -+#include "dev-dsa.h" ++#include "dev-ap94-pci.h" ++#include "pci-ath9k-fixup.h" + -+static struct platform_device ar71xx_dsa_switch_device = { -+ .name = "dsa", -+ .id = 0, ++static struct ath9k_platform_data ap94_wmac0_data = { ++ .led_pin = -1, ++}; ++static struct ath9k_platform_data ap94_wmac1_data = { ++ .led_pin = -1, +}; ++static char ap94_wmac0_mac[6]; ++static char ap94_wmac1_mac[6]; + -+void __init ar71xx_add_device_dsa(unsigned int id, -+ struct dsa_platform_data *d) ++static struct ar71xx_pci_irq ap94_pci_irqs[] __initdata = { ++ { ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, ++ }, { ++ .slot = 1, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV1, ++ } ++}; ++ ++static int ap94_pci_plat_dev_init(struct pci_dev *dev) +{ -+ int i; ++ switch (PCI_SLOT(dev->devfn)) { ++ case 17: ++ dev->dev.platform_data = &ap94_wmac0_data; ++ break; + -+ switch (id) { ++ case 18: ++ dev->dev.platform_data = &ap94_wmac1_data; ++ break; ++ } ++ ++ return 0; ++} ++ ++__init void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin) ++{ ++ switch (wmac) { + case 0: -+ d->netdev = &ar71xx_eth0_device.dev; ++ ap94_wmac0_data.led_pin = pin; + break; + case 1: -+ d->netdev = &ar71xx_eth1_device.dev; ++ ap94_wmac1_data.led_pin = pin; + break; -+ default: -+ printk(KERN_ERR -+ "ar71xx: invalid ethernet id %d for DSA switch\n", -+ id); -+ return; + } -+ -+ for (i = 0; i < d->nr_chips; i++) -+ d->chip[i].mii_bus = &ar71xx_mdio_device.dev; -+ -+ ar71xx_dsa_switch_device.dev.platform_data = d; -+ -+ platform_device_register(&ar71xx_dsa_switch_device); +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.h linux-2.6.39/arch/mips/ar71xx/dev-dsa.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.h 2011-08-24 02:41:55.347990727 +0200 -@@ -0,0 +1,20 @@ -+/* -+ * Atheros AR71xx DSA switch device support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _AR71XX_DEV_DSA_H -+#define _AR71XX_DEV_DSA_H -+ -+#include -+ -+void ar71xx_add_device_dsa(unsigned int id, -+ struct dsa_platform_data *d) __init; -+ -+#endif /* _AR71XX_DEV_DSA_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.c 2011-08-24 02:41:55.347990727 +0200 -@@ -0,0 +1,58 @@ -+/* -+ * Atheros AR71xx GPIO button support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "linux/init.h" -+#include "linux/slab.h" -+#include -+ -+#include "dev-gpio-buttons.h" + -+void __init ar71xx_register_gpio_keys_polled(int id, -+ unsigned poll_interval, -+ unsigned nbuttons, -+ struct gpio_keys_button *buttons) ++__init void ap94_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val) +{ -+ struct platform_device *pdev; -+ struct gpio_keys_platform_data pdata; -+ struct gpio_keys_button *p; -+ int err; -+ -+ p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL); -+ if (!p) -+ return; -+ -+ memcpy(p, buttons, nbuttons * sizeof(*p)); -+ -+ pdev = platform_device_alloc("gpio-keys-polled", id); -+ if (!pdev) -+ goto err_free_buttons; ++ switch (wmac) { ++ case 0: ++ ap94_wmac0_data.gpio_mask = mask; ++ ap94_wmac0_data.gpio_val = val; ++ break; ++ case 1: ++ ap94_wmac1_data.gpio_mask = mask; ++ ap94_wmac1_data.gpio_val = val; ++ break; ++ } ++} + -+ memset(&pdata, 0, sizeof(pdata)); -+ pdata.poll_interval = poll_interval; -+ pdata.nbuttons = nbuttons; -+ pdata.buttons = p; ++void __init ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, ++ u8 *cal_data1, u8 *mac_addr1) ++{ ++ if (cal_data0) ++ memcpy(ap94_wmac0_data.eeprom_data, cal_data0, ++ sizeof(ap94_wmac0_data.eeprom_data)); + -+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); -+ if (err) -+ goto err_put_pdev; ++ if (cal_data1) ++ memcpy(ap94_wmac1_data.eeprom_data, cal_data1, ++ sizeof(ap94_wmac1_data.eeprom_data)); + -+ err = platform_device_add(pdev); -+ if (err) -+ goto err_put_pdev; ++ if (mac_addr0) { ++ memcpy(ap94_wmac0_mac, mac_addr0, sizeof(ap94_wmac0_mac)); ++ ap94_wmac0_data.macaddr = ap94_wmac0_mac; ++ } + -+ return; ++ if (mac_addr1) { ++ memcpy(ap94_wmac1_mac, mac_addr1, sizeof(ap94_wmac1_mac)); ++ ap94_wmac1_data.macaddr = ap94_wmac1_mac; ++ } + -+err_put_pdev: -+ platform_device_put(pdev); ++ ar71xx_pci_plat_dev_init = ap94_pci_plat_dev_init; ++ ar71xx_pci_init(ARRAY_SIZE(ap94_pci_irqs), ap94_pci_irqs); + -+err_free_buttons: -+ kfree(p); ++ pci_enable_ath9k_fixup(17, ap94_wmac0_data.eeprom_data); ++ pci_enable_ath9k_fixup(18, ap94_wmac1_data.eeprom_data); +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.h linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.h 2011-08-24 02:41:55.347990727 +0200 -@@ -0,0 +1,23 @@ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.h linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-ap94-pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-ap94-pci.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,31 @@ +/* -+ * Atheros AR71xx GPIO button support ++ * Atheros AP94 reference board PCI initialization + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009-2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#ifndef _AR71XX_DEV_GPIO_BUTTONS_H -+#define _AR71XX_DEV_GPIO_BUTTONS_H ++#ifndef _AR71XX_DEV_AP94_PCI_H ++#define _AR71XX_DEV_AP94_PCI_H + -+#include -+#include ++#if defined(CONFIG_AR71XX_DEV_AP94_PCI) ++void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, ++ u8 *cal_data1, u8 *mac_addr1) __init; + -+void ar71xx_register_gpio_keys_polled(int id, -+ unsigned poll_interval, -+ unsigned nbuttons, -+ struct gpio_keys_button *buttons); ++void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin) __init; ++void ap94_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val) __init; + -+#endif /* _AR71XX_DEV_GPIO_BUTTONS_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.c linux-2.6.39/arch/mips/ar71xx/devices.c ---- linux-2.6.39.orig/arch/mips/ar71xx/devices.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/devices.c 2011-08-24 02:41:55.347990727 +0200 -@@ -0,0 +1,765 @@ ++#else ++static inline void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, ++ u8 *cal_data1, u8 *mac_addr1) {} ++ ++static inline void ap94_pci_setup_wmac_led_pin(unsigned wmac, int pin) {} ++static inline void ap94_pci_setup_wmac_gpio(unsigned wmac, ++ u32 mask, u32 val) {} ++#endif ++ ++#endif /* _AR71XX_DEV_AP94_PCI_H */ ++ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.c linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,154 @@ +/* -+ * Atheros AR71xx SoC platform devices ++ * Atheros AR9XXX SoCs built-in WMAC device support + * + * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * -+ * Parts of this file are based on Atheros 2.6.15 BSP -+ * Parts of this file are based on Atheros 2.6.31 BSP ++ * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -918,1144 +1072,732 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.c linux-2.6.39/arch/mips/ar +#include +#include +#include -+#include ++#include + +#include -+#include + -+#include "devices.h" ++#include "dev-ar9xxx-wmac.h" + -+unsigned char ar71xx_mac_base[ETH_ALEN] __initdata; ++#define MHZ_25 (25 * 1000 * 1000) + -+static struct resource ar71xx_uart_resources[] = { -+ { -+ .start = AR71XX_UART_BASE, -+ .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, ++static struct ath9k_platform_data ar9xxx_wmac_data = { ++ .led_pin = -1, +}; ++static char ar9xxx_wmac_mac[6]; + -+#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) -+static struct plat_serial8250_port ar71xx_uart_data[] = { ++static struct resource ar9xxx_wmac_resources[] = { + { -+ .mapbase = AR71XX_UART_BASE, -+ .irq = AR71XX_MISC_IRQ_UART, -+ .flags = AR71XX_UART_FLAGS, -+ .iotype = UPIO_MEM32, -+ .regshift = 2, ++ /* .start and .end fields are filled dynamically */ ++ .flags = IORESOURCE_MEM, + }, { -+ /* terminating entry */ -+ } -+}; -+ -+static struct platform_device ar71xx_uart_device = { -+ .name = "serial8250", -+ .id = PLAT8250_DEV_PLATFORM, -+ .resource = ar71xx_uart_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_uart_resources), -+ .dev = { -+ .platform_data = ar71xx_uart_data -+ }, -+}; -+ -+static struct resource ar933x_uart_resources[] = { -+ { -+ .start = AR933X_UART_BASE, -+ .end = AR933X_UART_BASE + AR71XX_UART_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .start = AR71XX_MISC_IRQ_UART, -+ .end = AR71XX_MISC_IRQ_UART, -+ .flags = IORESOURCE_IRQ, ++ .start = AR71XX_CPU_IRQ_IP2, ++ .end = AR71XX_CPU_IRQ_IP2, ++ .flags = IORESOURCE_IRQ, + }, +}; + -+static struct ar933x_uart_platform_data ar933x_uart_data; -+static struct platform_device ar933x_uart_device = { -+ .name = "ar933x-uart", -+ .id = -1, -+ .resource = ar933x_uart_resources, -+ .num_resources = ARRAY_SIZE(ar933x_uart_resources), ++static struct platform_device ar9xxx_wmac_device = { ++ .name = "ath9k", ++ .id = -1, ++ .resource = ar9xxx_wmac_resources, ++ .num_resources = ARRAY_SIZE(ar9xxx_wmac_resources), + .dev = { -+ .platform_data = &ar933x_uart_data, ++ .platform_data = &ar9xxx_wmac_data, + }, +}; + -+void __init ar71xx_add_device_uart(void) ++static void ar913x_wmac_init(void) +{ -+ struct platform_device *pdev; -+ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ pdev = &ar71xx_uart_device; -+ ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq; -+ break; -+ -+ case AR71XX_SOC_AR9330: -+ case AR71XX_SOC_AR9331: -+ pdev = &ar933x_uart_device; -+ ar933x_uart_data.uartclk = ar71xx_ref_freq; -+ break; ++ ar71xx_device_stop(RESET_MODULE_AMBA2WMAC); ++ mdelay(10); + -+ case AR71XX_SOC_AR9341: -+ case AR71XX_SOC_AR9342: -+ case AR71XX_SOC_AR9344: -+ pdev = &ar71xx_uart_device; -+ ar71xx_uart_data[0].uartclk = ar71xx_ref_freq; -+ break; ++ ar71xx_device_start(RESET_MODULE_AMBA2WMAC); ++ mdelay(10); + -+ default: -+ BUG(); -+ } ++ ar9xxx_wmac_resources[0].start = AR91XX_WMAC_BASE; ++ ar9xxx_wmac_resources[0].end = AR91XX_WMAC_BASE + AR91XX_WMAC_SIZE - 1; ++} + -+ platform_device_register(pdev); ++static int ar933x_r1_get_wmac_revision(void) ++{ ++ return ar71xx_soc_rev; +} + -+static struct resource ar71xx_mdio_resources[] = { -+ { -+ .name = "mdio_base", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_GE0_BASE, -+ .end = AR71XX_GE0_BASE + 0x200 - 1, -+ } -+}; ++static int ar933x_wmac_reset(void) ++{ ++ unsigned retries = 0; + -+static struct ag71xx_mdio_platform_data ar71xx_mdio_data; ++ ar71xx_device_stop(AR933X_RESET_WMAC); ++ ar71xx_device_start(AR933X_RESET_WMAC); + -+struct platform_device ar71xx_mdio_device = { -+ .name = "ag71xx-mdio", -+ .id = -1, -+ .resource = ar71xx_mdio_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_mdio_resources), -+ .dev = { -+ .platform_data = &ar71xx_mdio_data, -+ }, -+}; ++ while (1) { ++ u32 bootstrap; + -+static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift) -+{ -+ void __iomem *base; -+ u32 t; ++ bootstrap = ar71xx_reset_rr(AR933X_RESET_REG_BOOTSTRAP); ++ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0) ++ return 0; + -+ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); ++ if (retries > 20) ++ break; + -+ t = __raw_readl(base + cfg_reg); -+ t &= ~(3 << shift); -+ t |= (2 << shift); -+ __raw_writel(t, base + cfg_reg); -+ udelay(100); ++ udelay(10000); ++ retries++; ++ } + -+ __raw_writel(pll_val, base + pll_reg); ++ pr_err("ar93xx: WMAC reset timed out"); ++ return -ETIMEDOUT; ++} + -+ t |= (3 << shift); -+ __raw_writel(t, base + cfg_reg); -+ udelay(100); ++static void ar933x_wmac_init(void) ++{ ++ ar9xxx_wmac_device.name = "ar933x_wmac"; ++ ar9xxx_wmac_resources[0].start = AR933X_WMAC_BASE; ++ ar9xxx_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; ++ if (ar71xx_ref_freq == MHZ_25) ++ ar9xxx_wmac_data.is_clk_25mhz = true; + -+ t &= ~(3 << shift); -+ __raw_writel(t, base + cfg_reg); -+ udelay(100); ++ if (ar71xx_soc_rev == 1) ++ ar9xxx_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision; + -+ printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n", -+ (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg)); ++ ar9xxx_wmac_data.external_reset = ar933x_wmac_reset; + -+ iounmap(base); ++ ar933x_wmac_reset(); +} + -+void __init ar71xx_add_device_mdio(u32 phy_mask) ++static void ar934x_wmac_init(void) ++{ ++ ar9xxx_wmac_device.name = "ar934x_wmac"; ++ ar9xxx_wmac_resources[0].start = AR934X_WMAC_BASE; ++ ar9xxx_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1; ++ if (ar71xx_ref_freq == MHZ_25) ++ ar9xxx_wmac_data.is_clk_25mhz = true; ++} ++ ++void __init ar9xxx_add_device_wmac(u8 *cal_data, u8 *mac_addr) +{ + switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7240: -+ ar71xx_mdio_data.is_ar7240 = 1; -+ break; -+ case AR71XX_SOC_AR7241: -+ ar71xx_mdio_data.is_ar7240 = 1; -+ ar71xx_mdio_resources[0].start = AR71XX_GE1_BASE; -+ ar71xx_mdio_resources[0].end = AR71XX_GE1_BASE + 0x200 - 1; -+ break; -+ case AR71XX_SOC_AR7242: -+ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, -+ AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000, -+ AR71XX_ETH0_PLL_SHIFT); ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ ar913x_wmac_init(); + break; ++ + case AR71XX_SOC_AR9330: + case AR71XX_SOC_AR9331: -+ ar71xx_mdio_data.is_ar7240 = 1; -+ ar71xx_mdio_resources[0].start = AR71XX_GE1_BASE; -+ ar71xx_mdio_resources[0].end = AR71XX_GE1_BASE + 0x200 - 1; -+ break; -+ default: ++ ar933x_wmac_init(); + break; -+ } -+ -+ ar71xx_mdio_data.phy_mask = phy_mask; -+ -+ platform_device_register(&ar71xx_mdio_device); -+} -+ -+struct ar71xx_eth_pll_data ar71xx_eth0_pll_data; -+struct ar71xx_eth_pll_data ar71xx_eth1_pll_data; -+ -+static u32 ar71xx_get_eth_pll(unsigned int mac, int speed) -+{ -+ struct ar71xx_eth_pll_data *pll_data; -+ u32 pll_val; + -+ switch (mac) { -+ case 0: -+ pll_data = &ar71xx_eth0_pll_data; -+ break; -+ case 1: -+ pll_data = &ar71xx_eth1_pll_data; ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ar934x_wmac_init(); + break; -+ default: -+ BUG(); -+ } + -+ switch (speed) { -+ case SPEED_10: -+ pll_val = pll_data->pll_10; -+ break; -+ case SPEED_100: -+ pll_val = pll_data->pll_100; -+ break; -+ case SPEED_1000: -+ pll_val = pll_data->pll_1000; -+ break; + default: + BUG(); + } + -+ return pll_val; -+} ++ if (cal_data) ++ memcpy(ar9xxx_wmac_data.eeprom_data, cal_data, ++ sizeof(ar9xxx_wmac_data.eeprom_data)); + -+static void ar71xx_set_pll_ge0(int speed) -+{ -+ u32 val = ar71xx_get_eth_pll(0, speed); ++ if (mac_addr) { ++ memcpy(ar9xxx_wmac_mac, mac_addr, sizeof(ar9xxx_wmac_mac)); ++ ar9xxx_wmac_data.macaddr = ar9xxx_wmac_mac; ++ } + -+ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK, -+ val, AR71XX_ETH0_PLL_SHIFT); ++ platform_device_register(&ar9xxx_wmac_device); +} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.h linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-ar9xxx-wmac.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-ar9xxx-wmac.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * Atheros AR9XXX SoCs built-in WMAC device support ++ * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+static void ar71xx_set_pll_ge1(int speed) -+{ -+ u32 val = ar71xx_get_eth_pll(1, speed); ++#ifndef _AR71XX_DEV_AR9XXX_WMAC_H ++#define _AR71XX_DEV_AR9XXX_WMAC_H + -+ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK, -+ val, AR71XX_ETH1_PLL_SHIFT); -+} ++void ar9xxx_add_device_wmac(u8 *cal_data, u8 *mac_addr) __init; + -+static void ar724x_set_pll_ge0(int speed) -+{ -+ /* TODO */ -+} ++#endif /* _AR71XX_DEV_AR9XXX_WMAC_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.c linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,31 @@ ++/* ++ * Atheros db120 reference board PCI initialization ++ * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * ++ * Parts of this file are based on Atheros linux 2.6.31 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+static void ar724x_set_pll_ge1(int speed) ++#include ++ ++#include ++#include ++ ++#include "dev-db120-pci.h" ++ ++static struct ar71xx_pci_irq db120_pci_irqs[] __initdata = { ++ { ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, ++ } ++}; ++ ++void __init db120_pci_init(void) +{ -+ /* TODO */ ++ ar71xx_pci_init(ARRAY_SIZE(db120_pci_irqs), db120_pci_irqs); +} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.h linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-db120-pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-db120-pci.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,22 @@ ++/* ++ * Atheros DB120 reference board PCI initialization ++ * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * ++ * Parts of this file are based on Atheros linux 2.6.31 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+static void ar7242_set_pll_ge0(int speed) -+{ -+ u32 val = ar71xx_get_eth_pll(0, speed); ++#ifndef _AR71XX_DEV_DB120_PCI_H ++#define _AR71XX_DEV_DB120_PCI_H + -+ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR7242_PLL_REG_ETH0_INT_CLOCK, -+ val, AR71XX_ETH0_PLL_SHIFT); -+} ++#if defined(CONFIG_AR71XX_DEV_DB120_PCI) ++void db120_pci_init(void); ++#else ++static inline void db120_pci_init(void) { } ++#endif + -+static void ar91xx_set_pll_ge0(int speed) -+{ -+ u32 val = ar71xx_get_eth_pll(0, speed); ++#endif /* _AR71XX_DEV_DB120_PCI_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c linux-2.6.39/arch/mips/ar71xx/dev-dsa.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,50 @@ ++/* ++ * Atheros AR71xx DSA switch device support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK, -+ val, AR91XX_ETH0_PLL_SHIFT); -+} ++#include ++#include + -+static void ar91xx_set_pll_ge1(int speed) -+{ -+ u32 val = ar71xx_get_eth_pll(1, speed); ++#include + -+ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK, -+ val, AR91XX_ETH1_PLL_SHIFT); -+} ++#include "devices.h" ++#include "dev-dsa.h" + -+static void ar933x_set_pll_ge0(int speed) -+{ -+ /* TODO */ -+} ++static struct platform_device ar71xx_dsa_switch_device = { ++ .name = "dsa", ++ .id = 0, ++}; + -+static void ar933x_set_pll_ge1(int speed) ++void __init ar71xx_add_device_dsa(unsigned int id, ++ struct dsa_platform_data *d) +{ -+ /* TODO */ -+} ++ int i; + -+static void ar71xx_ddr_flush_ge0(void) -+{ -+ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0); -+} ++ switch (id) { ++ case 0: ++ d->netdev = &ar71xx_eth0_device.dev; ++ break; ++ case 1: ++ d->netdev = &ar71xx_eth1_device.dev; ++ break; ++ default: ++ printk(KERN_ERR ++ "ar71xx: invalid ethernet id %d for DSA switch\n", ++ id); ++ return; ++ } + -+static void ar71xx_ddr_flush_ge1(void) -+{ -+ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1); -+} ++ for (i = 0; i < d->nr_chips; i++) ++ d->chip[i].mii_bus = &ar71xx_mdio_device.dev; + -+static void ar724x_ddr_flush_ge0(void) -+{ -+ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0); -+} ++ ar71xx_dsa_switch_device.dev.platform_data = d; + -+static void ar724x_ddr_flush_ge1(void) -+{ -+ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE1); ++ platform_device_register(&ar71xx_dsa_switch_device); +} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.h linux-2.6.39/arch/mips/ar71xx/dev-dsa.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-dsa.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-dsa.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * Atheros AR71xx DSA switch device support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+static void ar91xx_ddr_flush_ge0(void) -+{ -+ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0); -+} ++#ifndef _AR71XX_DEV_DSA_H ++#define _AR71XX_DEV_DSA_H + -+static void ar91xx_ddr_flush_ge1(void) -+{ -+ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1); -+} ++#include + -+static void ar933x_ddr_flush_ge0(void) -+{ -+ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE0); -+} ++void ar71xx_add_device_dsa(unsigned int id, ++ struct dsa_platform_data *d) __init; + -+static void ar933x_ddr_flush_ge1(void) ++#endif /* _AR71XX_DEV_DSA_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,58 @@ ++/* ++ * Atheros AR71xx GPIO button support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include "linux/init.h" ++#include "linux/slab.h" ++#include ++ ++#include "dev-gpio-buttons.h" ++ ++void __init ar71xx_register_gpio_keys_polled(int id, ++ unsigned poll_interval, ++ unsigned nbuttons, ++ struct gpio_keys_button *buttons) +{ -+ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE1); -+} ++ struct platform_device *pdev; ++ struct gpio_keys_platform_data pdata; ++ struct gpio_keys_button *p; ++ int err; + -+static struct resource ar71xx_eth0_resources[] = { -+ { -+ .name = "mac_base", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_GE0_BASE, -+ .end = AR71XX_GE0_BASE + 0x200 - 1, -+ }, { -+ .name = "mii_ctrl", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_MII_BASE + MII_REG_MII0_CTRL, -+ .end = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3, -+ }, { -+ .name = "mac_irq", -+ .flags = IORESOURCE_IRQ, -+ .start = AR71XX_CPU_IRQ_GE0, -+ .end = AR71XX_CPU_IRQ_GE0, -+ }, -+}; ++ p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL); ++ if (!p) ++ return; + -+struct ag71xx_platform_data ar71xx_eth0_data = { -+ .reset_bit = RESET_MODULE_GE0_MAC, -+}; ++ memcpy(p, buttons, nbuttons * sizeof(*p)); + -+struct platform_device ar71xx_eth0_device = { -+ .name = "ag71xx", -+ .id = 0, -+ .resource = ar71xx_eth0_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_eth0_resources), -+ .dev = { -+ .platform_data = &ar71xx_eth0_data, -+ }, -+}; ++ pdev = platform_device_alloc("gpio-keys-polled", id); ++ if (!pdev) ++ goto err_free_buttons; + -+static struct resource ar71xx_eth1_resources[] = { -+ { -+ .name = "mac_base", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_GE1_BASE, -+ .end = AR71XX_GE1_BASE + 0x200 - 1, -+ }, { -+ .name = "mii_ctrl", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_MII_BASE + MII_REG_MII1_CTRL, -+ .end = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3, -+ }, { -+ .name = "mac_irq", -+ .flags = IORESOURCE_IRQ, -+ .start = AR71XX_CPU_IRQ_GE1, -+ .end = AR71XX_CPU_IRQ_GE1, -+ }, -+}; ++ memset(&pdata, 0, sizeof(pdata)); ++ pdata.poll_interval = poll_interval; ++ pdata.nbuttons = nbuttons; ++ pdata.buttons = p; + -+struct ag71xx_platform_data ar71xx_eth1_data = { -+ .reset_bit = RESET_MODULE_GE1_MAC, -+}; ++ err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); ++ if (err) ++ goto err_put_pdev; + -+struct platform_device ar71xx_eth1_device = { -+ .name = "ag71xx", -+ .id = 1, -+ .resource = ar71xx_eth1_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_eth1_resources), -+ .dev = { -+ .platform_data = &ar71xx_eth1_data, -+ }, -+}; ++ err = platform_device_add(pdev); ++ if (err) ++ goto err_put_pdev; + -+#define AR71XX_PLL_VAL_1000 0x00110000 -+#define AR71XX_PLL_VAL_100 0x00001099 -+#define AR71XX_PLL_VAL_10 0x00991099 ++ return; + -+#define AR724X_PLL_VAL_1000 0x00110000 -+#define AR724X_PLL_VAL_100 0x00001099 -+#define AR724X_PLL_VAL_10 0x00991099 ++err_put_pdev: ++ platform_device_put(pdev); + -+#define AR7242_PLL_VAL_1000 0x1c000000 -+#define AR7242_PLL_VAL_100 0x00000101 -+#define AR7242_PLL_VAL_10 0x00001616 ++err_free_buttons: ++ kfree(p); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.h linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-gpio-buttons.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-gpio-buttons.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,23 @@ ++/* ++ * Atheros AR71xx GPIO button support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+#define AR91XX_PLL_VAL_1000 0x1a000000 -+#define AR91XX_PLL_VAL_100 0x13000a44 -+#define AR91XX_PLL_VAL_10 0x00441099 ++#ifndef _AR71XX_DEV_GPIO_BUTTONS_H ++#define _AR71XX_DEV_GPIO_BUTTONS_H + -+#define AR933X_PLL_VAL_1000 0x00110000 -+#define AR933X_PLL_VAL_100 0x00001099 -+#define AR933X_PLL_VAL_10 0x00991099 ++#include ++#include + -+static void __init ar71xx_init_eth_pll_data(unsigned int id) -+{ -+ struct ar71xx_eth_pll_data *pll_data; -+ u32 pll_10, pll_100, pll_1000; ++void ar71xx_register_gpio_keys_polled(int id, ++ unsigned poll_interval, ++ unsigned nbuttons, ++ struct gpio_keys_button *buttons); + -+ switch (id) { -+ case 0: -+ pll_data = &ar71xx_eth0_pll_data; -+ break; -+ case 1: -+ pll_data = &ar71xx_eth1_pll_data; -+ break; -+ default: -+ BUG(); -+ } ++#endif /* _AR71XX_DEV_GPIO_BUTTONS_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,57 @@ ++/* ++ * Atheros AR71xx GPIO LED device support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ pll_10 = AR71XX_PLL_VAL_10; -+ pll_100 = AR71XX_PLL_VAL_100; -+ pll_1000 = AR71XX_PLL_VAL_1000; -+ break; ++#include ++#include ++#include + -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ pll_10 = AR724X_PLL_VAL_10; -+ pll_100 = AR724X_PLL_VAL_100; -+ pll_1000 = AR724X_PLL_VAL_1000; -+ break; ++#include "dev-leds-gpio.h" + -+ case AR71XX_SOC_AR7242: -+ pll_10 = AR7242_PLL_VAL_10; -+ pll_100 = AR7242_PLL_VAL_100; -+ pll_1000 = AR7242_PLL_VAL_1000; -+ break; ++void __init ar71xx_add_device_leds_gpio(int id, unsigned num_leds, ++ struct gpio_led *leds) ++{ ++ struct platform_device *pdev; ++ struct gpio_led_platform_data pdata; ++ struct gpio_led *p; ++ int err; + -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ pll_10 = AR91XX_PLL_VAL_10; -+ pll_100 = AR91XX_PLL_VAL_100; -+ pll_1000 = AR91XX_PLL_VAL_1000; -+ break; ++ p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL); ++ if (!p) ++ return; + -+ case AR71XX_SOC_AR9330: -+ case AR71XX_SOC_AR9331: -+ pll_10 = AR933X_PLL_VAL_10; -+ pll_100 = AR933X_PLL_VAL_100; -+ pll_1000 = AR933X_PLL_VAL_1000; -+ break; ++ memcpy(p, leds, num_leds * sizeof(*p)); + -+ default: -+ BUG(); -+ } ++ pdev = platform_device_alloc("leds-gpio", id); ++ if (!pdev) ++ goto err_free_leds; + -+ if (!pll_data->pll_10) -+ pll_data->pll_10 = pll_10; ++ memset(&pdata, 0, sizeof(pdata)); ++ pdata.num_leds = num_leds; ++ pdata.leds = p; + -+ if (!pll_data->pll_100) -+ pll_data->pll_100 = pll_100; ++ err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); ++ if (err) ++ goto err_put_pdev; + -+ if (!pll_data->pll_1000) -+ pll_data->pll_1000 = pll_1000; -+} ++ err = platform_device_add(pdev); ++ if (err) ++ goto err_put_pdev; + -+static int ar71xx_eth_instance __initdata; -+void __init ar71xx_add_device_eth(unsigned int id) -+{ -+ struct platform_device *pdev; -+ struct ag71xx_platform_data *pdata; ++ return; + -+ ar71xx_init_eth_pll_data(id); ++err_put_pdev: ++ platform_device_put(pdev); + -+ switch (id) { -+ case 0: -+ switch (ar71xx_eth0_data.phy_if_mode) { -+ case PHY_INTERFACE_MODE_MII: -+ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII; -+ break; -+ case PHY_INTERFACE_MODE_GMII: -+ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII; -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII; -+ break; -+ case PHY_INTERFACE_MODE_RMII: -+ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII; -+ break; -+ default: -+ printk(KERN_ERR "ar71xx: invalid PHY interface mode " -+ "for eth0\n"); -+ return; -+ } -+ pdev = &ar71xx_eth0_device; -+ break; -+ case 1: -+ switch (ar71xx_eth1_data.phy_if_mode) { -+ case PHY_INTERFACE_MODE_RMII: -+ ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII; -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII; -+ break; -+ default: -+ printk(KERN_ERR "ar71xx: invalid PHY interface mode " -+ "for eth1\n"); -+ return; -+ } -+ pdev = &ar71xx_eth1_device; -+ break; -+ default: -+ printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id); -+ return; -+ } ++err_free_leds: ++ kfree(p); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,21 @@ ++/* ++ * Atheros AR71xx GPIO LED device support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ pdata = pdev->dev.platform_data; -+ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1 -+ : ar71xx_ddr_flush_ge0; -+ pdata->set_pll = id ? ar71xx_set_pll_ge1 -+ : ar71xx_set_pll_ge0; -+ break; -+ -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1 -+ : ar71xx_ddr_flush_ge0; -+ pdata->set_pll = id ? ar71xx_set_pll_ge1 -+ : ar71xx_set_pll_ge0; -+ pdata->has_gbit = 1; -+ break; -+ -+ case AR71XX_SOC_AR7242: -+ ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO | -+ RESET_MODULE_GE0_PHY; -+ ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO | -+ RESET_MODULE_GE1_PHY; -+ pdata->ddr_flush = id ? ar724x_ddr_flush_ge1 -+ : ar724x_ddr_flush_ge0; -+ pdata->set_pll = id ? ar724x_set_pll_ge1 -+ : ar7242_set_pll_ge0; -+ pdata->has_gbit = 1; -+ pdata->is_ar724x = 1; -+ -+ if (!pdata->fifo_cfg1) -+ pdata->fifo_cfg1 = 0x0010ffff; -+ if (!pdata->fifo_cfg2) -+ pdata->fifo_cfg2 = 0x015500aa; -+ if (!pdata->fifo_cfg3) -+ pdata->fifo_cfg3 = 0x01f00140; -+ break; -+ -+ case AR71XX_SOC_AR7241: -+ ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO; -+ ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO; -+ /* fall through */ -+ case AR71XX_SOC_AR7240: -+ ar71xx_eth0_data.reset_bit |= RESET_MODULE_GE0_PHY; -+ ar71xx_eth1_data.reset_bit |= RESET_MODULE_GE1_PHY; -+ pdata->ddr_flush = id ? ar724x_ddr_flush_ge1 -+ : ar724x_ddr_flush_ge0; -+ pdata->set_pll = id ? ar724x_set_pll_ge1 -+ : ar724x_set_pll_ge0; -+ pdata->is_ar724x = 1; -+ if (ar71xx_soc == AR71XX_SOC_AR7240) -+ pdata->is_ar7240 = 1; ++#ifndef _AR71XX_DEV_LEDS_GPIO_H ++#define _AR71XX_DEV_LEDS_GPIO_H + -+ if (!pdata->fifo_cfg1) -+ pdata->fifo_cfg1 = 0x0010ffff; -+ if (!pdata->fifo_cfg2) -+ pdata->fifo_cfg2 = 0x015500aa; -+ if (!pdata->fifo_cfg3) -+ pdata->fifo_cfg3 = 0x01f00140; -+ break; ++#include + -+ case AR71XX_SOC_AR9130: -+ pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1 -+ : ar91xx_ddr_flush_ge0; -+ pdata->set_pll = id ? ar91xx_set_pll_ge1 -+ : ar91xx_set_pll_ge0; -+ pdata->is_ar91xx = 1; -+ break; ++void ar71xx_add_device_leds_gpio(int id, ++ unsigned num_leds, ++ struct gpio_led *leds) __init; + -+ case AR71XX_SOC_AR9132: -+ pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1 -+ : ar91xx_ddr_flush_ge0; -+ pdata->set_pll = id ? ar91xx_set_pll_ge1 -+ : ar91xx_set_pll_ge0; -+ pdata->is_ar91xx = 1; -+ pdata->has_gbit = 1; -+ break; ++#endif /* _AR71XX_DEV_LEDS_GPIO_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ case AR71XX_SOC_AR9330: -+ case AR71XX_SOC_AR9331: -+ ar71xx_eth0_data.reset_bit = AR933X_RESET_GE0_MAC | -+ AR933X_RESET_GE0_MDIO; -+ ar71xx_eth1_data.reset_bit = AR933X_RESET_GE1_MAC | -+ AR933X_RESET_GE1_MDIO; -+ pdata->ddr_flush = id ? ar933x_ddr_flush_ge1 -+ : ar933x_ddr_flush_ge0; -+ pdata->set_pll = id ? ar933x_set_pll_ge1 -+ : ar933x_set_pll_ge0; -+ pdata->has_gbit = 1; -+ pdata->is_ar724x = 1; ++#include ++#include ++#include + -+ if (!pdata->fifo_cfg1) -+ pdata->fifo_cfg1 = 0x0010ffff; -+ if (!pdata->fifo_cfg2) -+ pdata->fifo_cfg2 = 0x015500aa; -+ if (!pdata->fifo_cfg3) -+ pdata->fifo_cfg3 = 0x01f00140; -+ break; ++#include "devices.h" ++#include "dev-m25p80.h" + -+ default: -+ BUG(); ++static struct spi_board_info ar71xx_spi_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "m25p80", + } ++}; + -+ switch (pdata->phy_if_mode) { -+ case PHY_INTERFACE_MODE_GMII: -+ case PHY_INTERFACE_MODE_RGMII: -+ if (!pdata->has_gbit) { -+ printk(KERN_ERR "ar71xx: no gbit available on eth%d\n", -+ id); -+ return; -+ } -+ /* fallthrough */ -+ default: -+ break; -+ } ++void __init ar71xx_add_device_m25p80(struct flash_platform_data *pdata) ++{ ++ ar71xx_spi_info[0].platform_data = pdata; ++ ar71xx_add_device_spi(NULL, ar71xx_spi_info, ++ ARRAY_SIZE(ar71xx_spi_info)); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,16 @@ ++/* ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ if (!is_valid_ether_addr(pdata->mac_addr)) { -+ random_ether_addr(pdata->mac_addr); -+ printk(KERN_DEBUG -+ "ar71xx: using random MAC address for eth%d\n", -+ ar71xx_eth_instance); -+ } ++#ifndef _AR71XX_DEV_M25P80_H ++#define _AR71XX_DEV_M25P80_H + -+ if (pdata->mii_bus_dev == NULL) -+ pdata->mii_bus_dev = &ar71xx_mdio_device.dev; ++#include + -+ /* Reset the device */ -+ ar71xx_device_stop(pdata->reset_bit); -+ mdelay(100); ++void ar71xx_add_device_m25p80(struct flash_platform_data *pdata) __init; + -+ ar71xx_device_start(pdata->reset_bit); -+ mdelay(100); ++#endif /* _AR71XX_DEV_M25P80_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* ++ * Atheros PB42 reference board PCI initialization ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ platform_device_register(pdev); -+ ar71xx_eth_instance++; -+} ++#include + -+static struct resource ar71xx_spi_resources[] = { -+ [0] = { -+ .start = AR71XX_SPI_BASE, -+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; ++#include ++#include + -+static struct platform_device ar71xx_spi_device = { -+ .name = "ar71xx-spi", -+ .id = -1, -+ .resource = ar71xx_spi_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_spi_resources), ++#include "dev-pb42-pci.h" ++ ++static struct ar71xx_pci_irq pb42_pci_irqs[] __initdata = { ++ { ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, ++ }, { ++ .slot = 1, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV1, ++ }, { ++ .slot = 2, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV2, ++ } +}; + -+void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata, -+ struct spi_board_info const *info, -+ unsigned n) ++void __init pb42_pci_init(void) +{ -+ spi_register_board_info(info, n); -+ ar71xx_spi_device.dev.platform_data = pdata; -+ platform_device_register(&ar71xx_spi_device); ++ ar71xx_pci_init(ARRAY_SIZE(pb42_pci_irqs), pb42_pci_irqs); +} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,21 @@ ++/* ++ * Atheros PB42 reference board PCI initialization ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+void __init ar71xx_add_device_wdt(void) -+{ -+ platform_device_register_simple("ar71xx-wdt", -1, NULL, 0); -+} ++#ifndef _AR71XX_DEV_PB42_PCI_H ++#define _AR71XX_DEV_PB42_PCI_H + -+void __init ar71xx_set_mac_base(unsigned char *mac) -+{ -+ memcpy(ar71xx_mac_base, mac, ETH_ALEN); -+} ++#if defined(CONFIG_AR71XX_DEV_PB42_PCI) ++void pb42_pci_init(void) __init; ++#else ++static inline void pb42_pci_init(void) { } ++#endif + -+void __init ar71xx_parse_mac_addr(char *mac_str) -+{ -+ u8 tmp[ETH_ALEN]; -+ int t; -+ -+ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", -+ &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); -+ -+ if (t != ETH_ALEN) -+ t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx", -+ &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); -+ -+ if (t == ETH_ALEN) -+ ar71xx_set_mac_base(tmp); -+ else -+ printk(KERN_DEBUG "ar71xx: failed to parse mac address " -+ "\"%s\"\n", mac_str); -+} -+ -+static int __init ar71xx_ethaddr_setup(char *str) -+{ -+ ar71xx_parse_mac_addr(str); -+ return 1; -+} -+__setup("ethaddr=", ar71xx_ethaddr_setup); -+ -+static int __init ar71xx_kmac_setup(char *str) -+{ -+ ar71xx_parse_mac_addr(str); -+ return 1; -+} -+__setup("kmac=", ar71xx_kmac_setup); -+ -+void __init ar71xx_init_mac(unsigned char *dst, const unsigned char *src, -+ unsigned offset) -+{ -+ u32 t; -+ -+ if (!is_valid_ether_addr(src)) { -+ memset(dst, '\0', ETH_ALEN); -+ return; -+ } -+ -+ t = (((u32) src[3]) << 16) + (((u32) src[4]) << 8) + ((u32) src[5]); -+ t += offset; -+ -+ dst[0] = src[0]; -+ dst[1] = src[1]; -+ dst[2] = src[2]; -+ dst[3] = (t >> 16) & 0xff; -+ dst[4] = (t >> 8) & 0xff; -+ dst[5] = t & 0xff; -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.h linux-2.6.39/arch/mips/ar71xx/devices.h ---- linux-2.6.39.orig/arch/mips/ar71xx/devices.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/devices.h 2011-08-24 02:41:55.347990727 +0200 -@@ -0,0 +1,50 @@ ++#endif /* _AR71XX_DEV_PB42_PCI_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,33 @@ +/* -+ * Atheros AR71xx SoC device definitions ++ * Atheros PB9x reference board PCI initialization + * ++ * Copyright (C) 2010 Felix Fietkau + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#ifndef __AR71XX_DEVICES_H -+#define __AR71XX_DEVICES_H -+ -+#include -+ -+struct platform_device; ++#include + -+void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata, -+ struct spi_board_info const *info, -+ unsigned n) __init; ++#include ++#include + -+extern unsigned char ar71xx_mac_base[] __initdata; -+void ar71xx_parse_mac_addr(char *mac_str) __init; -+void ar71xx_init_mac(unsigned char *dst, const unsigned char *src, -+ unsigned offset) __init; ++#include "dev-pb9x-pci.h" + -+struct ar71xx_eth_pll_data { -+ u32 pll_10; -+ u32 pll_100; -+ u32 pll_1000; ++static struct ar71xx_pci_irq pb9x_pci_irqs[] __initdata = { ++ { ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, ++ } +}; + -+extern struct ar71xx_eth_pll_data ar71xx_eth0_pll_data; -+extern struct ar71xx_eth_pll_data ar71xx_eth1_pll_data; -+ -+extern struct ag71xx_platform_data ar71xx_eth0_data; -+extern struct ag71xx_platform_data ar71xx_eth1_data; -+extern struct platform_device ar71xx_eth0_device; -+extern struct platform_device ar71xx_eth1_device; -+void ar71xx_add_device_eth(unsigned int id) __init; -+ -+extern struct platform_device ar71xx_mdio_device; -+void ar71xx_add_device_mdio(u32 phy_mask) __init; -+ -+void ar71xx_add_device_uart(void) __init; -+ -+void ar71xx_add_device_wdt(void) __init; -+ -+#endif /* __AR71XX_DEVICES_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.c 2011-08-24 02:41:55.347990727 +0200 -@@ -0,0 +1,57 @@ ++void __init pb9x_pci_init(void) ++{ ++ ar71xx_pci_init(ARRAY_SIZE(pb9x_pci_irqs), pb9x_pci_irqs); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,22 @@ +/* -+ * Atheros AR71xx GPIO LED device support ++ * Atheros PB9x reference board PCI initialization + * ++ * Copyright (C) 2010 Felix Fietkau + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+ -+#include "dev-leds-gpio.h" -+ -+void __init ar71xx_add_device_leds_gpio(int id, unsigned num_leds, -+ struct gpio_led *leds) -+{ -+ struct platform_device *pdev; -+ struct gpio_led_platform_data pdata; -+ struct gpio_led *p; -+ int err; -+ -+ p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL); -+ if (!p) -+ return; -+ -+ memcpy(p, leds, num_leds * sizeof(*p)); -+ -+ pdev = platform_device_alloc("leds-gpio", id); -+ if (!pdev) -+ goto err_free_leds; -+ -+ memset(&pdata, 0, sizeof(pdata)); -+ pdata.num_leds = num_leds; -+ pdata.leds = p; -+ -+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); -+ if (err) -+ goto err_put_pdev; -+ -+ err = platform_device_add(pdev); -+ if (err) -+ goto err_put_pdev; -+ -+ return; ++#ifndef _AR71XX_DEV_PB9X_PCI_H ++#define _AR71XX_DEV_PB9X_PCI_H + -+err_put_pdev: -+ platform_device_put(pdev); ++#if defined(CONFIG_AR71XX_DEV_PB9X_PCI) ++void pb9x_pci_init(void) __init; ++#else ++static inline void pb9x_pci_init(void) { } ++#endif + -+err_free_leds: -+ kfree(p); -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-leds-gpio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-leds-gpio.h 2011-08-24 02:41:55.367990903 +0200 -@@ -0,0 +1,21 @@ ++#endif /* _AR71XX_DEV_PB9X_PCI_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c linux-2.6.39/arch/mips/ar71xx/dev-usb.c +--- linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/dev-usb.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,199 @@ +/* -+ * Atheros AR71xx GPIO LED device support ++ * Atheros AR71xx USB host device support + * + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#ifndef _AR71XX_DEV_LEDS_GPIO_H -+#define _AR71XX_DEV_LEDS_GPIO_H ++#include ++#include ++#include ++#include ++#include + -+#include ++#include ++#include + -+void ar71xx_add_device_leds_gpio(int id, -+ unsigned num_leds, -+ struct gpio_led *leds) __init; ++#include "dev-usb.h" + -+#endif /* _AR71XX_DEV_LEDS_GPIO_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.c 2011-08-24 02:41:55.367990903 +0200 -@@ -0,0 +1,30 @@ +/* -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. ++ * OHCI (USB full speed host controller) + */ ++static struct resource ar71xx_ohci_resources[] = { ++ [0] = { ++ .start = AR71XX_OHCI_BASE, ++ .end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = AR71XX_MISC_IRQ_OHCI, ++ .end = AR71XX_MISC_IRQ_OHCI, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; + -+#include -+#include -+#include -+ -+#include "devices.h" -+#include "dev-m25p80.h" ++static struct resource ar7240_ohci_resources[] = { ++ [0] = { ++ .start = AR7240_OHCI_BASE, ++ .end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = AR71XX_CPU_IRQ_USB, ++ .end = AR71XX_CPU_IRQ_USB, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; + -+static struct spi_board_info ar71xx_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ } -+}; -+ -+void __init ar71xx_add_device_m25p80(struct flash_platform_data *pdata) -+{ -+ ar71xx_spi_info[0].platform_data = pdata; -+ ar71xx_add_device_spi(NULL, ar71xx_spi_info, -+ ARRAY_SIZE(ar71xx_spi_info)); -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-m25p80.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-m25p80.h 2011-08-24 02:41:55.377990515 +0200 -@@ -0,0 +1,16 @@ -+/* -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _AR71XX_DEV_M25P80_H -+#define _AR71XX_DEV_M25P80_H -+ -+#include -+ -+void ar71xx_add_device_m25p80(struct flash_platform_data *pdata) __init; -+ -+#endif /* _AR71XX_DEV_M25P80_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.c 2011-08-24 02:41:55.377990515 +0200 -@@ -0,0 +1,40 @@ -+/* -+ * Atheros PB42 reference board PCI initialization -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "dev-pb42-pci.h" -+ -+static struct ar71xx_pci_irq pb42_pci_irqs[] __initdata = { -+ { -+ .slot = 0, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV0, -+ }, { -+ .slot = 1, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV1, -+ }, { -+ .slot = 2, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV2, -+ } -+}; -+ -+void __init pb42_pci_init(void) -+{ -+ ar71xx_pci_init(ARRAY_SIZE(pb42_pci_irqs), pb42_pci_irqs); -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb42-pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-pb42-pci.h 2011-08-24 02:41:55.387991243 +0200 -@@ -0,0 +1,21 @@ -+/* -+ * Atheros PB42 reference board PCI initialization -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _AR71XX_DEV_PB42_PCI_H -+#define _AR71XX_DEV_PB42_PCI_H -+ -+#if defined(CONFIG_AR71XX_DEV_PB42_PCI) -+void pb42_pci_init(void) __init; -+#else -+static inline void pb42_pci_init(void) { } -+#endif -+ -+#endif /* _AR71XX_DEV_PB42_PCI_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.c 2011-08-24 02:41:55.387991243 +0200 -@@ -0,0 +1,33 @@ -+/* -+ * Atheros PB9x reference board PCI initialization -+ * -+ * Copyright (C) 2010 Felix Fietkau -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "dev-pb9x-pci.h" -+ -+static struct ar71xx_pci_irq pb9x_pci_irqs[] __initdata = { -+ { -+ .slot = 0, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV0, -+ } -+}; -+ -+void __init pb9x_pci_init(void) -+{ -+ ar71xx_pci_init(ARRAY_SIZE(pb9x_pci_irqs), pb9x_pci_irqs); -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-pb9x-pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-pb9x-pci.h 2011-08-24 02:41:55.387991243 +0200 -@@ -0,0 +1,22 @@ -+/* -+ * Atheros PB9x reference board PCI initialization -+ * -+ * Copyright (C) 2010 Felix Fietkau -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _AR71XX_DEV_PB9X_PCI_H -+#define _AR71XX_DEV_PB9X_PCI_H -+ -+#if defined(CONFIG_AR71XX_DEV_PB9X_PCI) -+void pb9x_pci_init(void) __init; -+#else -+static inline void pb9x_pci_init(void) { } -+#endif -+ -+#endif /* _AR71XX_DEV_PB9X_PCI_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c linux-2.6.39/arch/mips/ar71xx/dev-usb.c ---- linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-usb.c 2011-08-24 02:41:55.417990329 +0200 -@@ -0,0 +1,199 @@ -+/* -+ * Atheros AR71xx USB host device support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "dev-usb.h" -+ -+/* -+ * OHCI (USB full speed host controller) -+ */ -+static struct resource ar71xx_ohci_resources[] = { -+ [0] = { -+ .start = AR71XX_OHCI_BASE, -+ .end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = AR71XX_MISC_IRQ_OHCI, -+ .end = AR71XX_MISC_IRQ_OHCI, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct resource ar7240_ohci_resources[] = { -+ [0] = { -+ .start = AR7240_OHCI_BASE, -+ .end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = AR71XX_CPU_IRQ_USB, -+ .end = AR71XX_CPU_IRQ_USB, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32); -+static struct platform_device ar71xx_ohci_device = { -+ .name = "ar71xx-ohci", -+ .id = -1, -+ .resource = ar71xx_ohci_resources, -+ .num_resources = ARRAY_SIZE(ar71xx_ohci_resources), -+ .dev = { -+ .dma_mask = &ar71xx_ohci_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), -+ }, ++static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32); ++static struct platform_device ar71xx_ohci_device = { ++ .name = "ar71xx-ohci", ++ .id = -1, ++ .resource = ar71xx_ohci_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_ohci_resources), ++ .dev = { ++ .dma_mask = &ar71xx_ohci_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(32), ++ }, +}; + +/* @@ -2194,7 +1936,7 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.c linux-2.6.39/arch/mips/ar +} diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.h linux-2.6.39/arch/mips/ar71xx/dev-usb.h --- linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/dev-usb.h 2011-08-24 02:41:55.427989786 +0200 ++++ linux-2.6.39/arch/mips/ar71xx/dev-usb.h 2011-08-24 18:17:23.000000000 +0200 @@ -0,0 +1,17 @@ +/* + * Atheros AR71xx USB host device support @@ -2213,2072 +1955,1765 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/dev-usb.h linux-2.6.39/arch/mips/ar +void ar71xx_add_device_usb(void) __init; + +#endif /* _AR71XX_DEV_USB_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c linux-2.6.39/arch/mips/ar71xx/early_printk.c ---- linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/early_printk.c 2011-08-24 02:41:55.427989786 +0200 -@@ -0,0 +1,96 @@ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.c linux-2.6.39/arch/mips/ar71xx/devices.c +--- linux-2.6.39.orig/arch/mips/ar71xx/devices.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/devices.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,765 @@ +/* -+ * Atheros AR7xxx/AR9xxx SoC early printk support ++ * Atheros AR71xx SoC platform devices + * -+ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * ++ * Parts of this file are based on Atheros 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.31 BSP ++ * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+#include ++#include ++#include ++#include ++#include ++#include ++#include + +#include -+#include ++#include + -+static void (*_prom_putchar) (unsigned char); ++#include "devices.h" + -+static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val) -+{ -+ u32 t; ++unsigned char ar71xx_mac_base[ETH_ALEN] __initdata; + -+ do { -+ t = __raw_readl(reg); -+ if ((t & mask) == val) -+ break; -+ } while (1); -+} -+ -+static void prom_putchar_ar71xx(unsigned char ch) -+{ -+ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); ++static struct resource ar71xx_uart_resources[] = { ++ { ++ .start = AR71XX_UART_BASE, ++ .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; + -+ prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); -+ __raw_writel(ch, base + UART_TX * 4); -+ prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); -+} ++#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) ++static struct plat_serial8250_port ar71xx_uart_data[] = { ++ { ++ .mapbase = AR71XX_UART_BASE, ++ .irq = AR71XX_MISC_IRQ_UART, ++ .flags = AR71XX_UART_FLAGS, ++ .iotype = UPIO_MEM32, ++ .regshift = 2, ++ }, { ++ /* terminating entry */ ++ } ++}; + -+static void prom_putchar_ar933x(unsigned char ch) -+{ -+ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE)); ++static struct platform_device ar71xx_uart_device = { ++ .name = "serial8250", ++ .id = PLAT8250_DEV_PLATFORM, ++ .resource = ar71xx_uart_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_uart_resources), ++ .dev = { ++ .platform_data = ar71xx_uart_data ++ }, ++}; + -+ prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, -+ AR933X_UART_DATA_TX_CSR); -+ __raw_writel(AR933X_UART_DATA_TX_CSR | ch, base + AR933X_UART_DATA_REG); -+ prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, -+ AR933X_UART_DATA_TX_CSR); -+} ++static struct resource ar933x_uart_resources[] = { ++ { ++ .start = AR933X_UART_BASE, ++ .end = AR933X_UART_BASE + AR71XX_UART_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = AR71XX_MISC_IRQ_UART, ++ .end = AR71XX_MISC_IRQ_UART, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; + -+static void prom_putchar_dummy(unsigned char ch) -+{ -+ /* nothing to do */ -+} ++static struct ar933x_uart_platform_data ar933x_uart_data; ++static struct platform_device ar933x_uart_device = { ++ .name = "ar933x-uart", ++ .id = -1, ++ .resource = ar933x_uart_resources, ++ .num_resources = ARRAY_SIZE(ar933x_uart_resources), ++ .dev = { ++ .platform_data = &ar933x_uart_data, ++ }, ++}; + -+static void prom_putchar_init(void) ++void __init ar71xx_add_device_uart(void) +{ -+ void __iomem *base; -+ u32 id; ++ struct platform_device *pdev; + -+ base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE)); -+ id = __raw_readl(base + AR71XX_RESET_REG_REV_ID); -+ id &= REV_ID_MAJOR_MASK; ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ pdev = &ar71xx_uart_device; ++ ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq; ++ break; + -+ switch (id) { -+ case REV_ID_MAJOR_AR71XX: -+ case REV_ID_MAJOR_AR7240: -+ case REV_ID_MAJOR_AR7241: -+ case REV_ID_MAJOR_AR7242: -+ case REV_ID_MAJOR_AR913X: -+ case REV_ID_MAJOR_AR9341: -+ case REV_ID_MAJOR_AR9342: -+ case REV_ID_MAJOR_AR9344: -+ _prom_putchar = prom_putchar_ar71xx; ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ pdev = &ar933x_uart_device; ++ ar933x_uart_data.uartclk = ar71xx_ref_freq; + break; + -+ case REV_ID_MAJOR_AR9330: -+ case REV_ID_MAJOR_AR9331: -+ _prom_putchar = prom_putchar_ar933x; ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ pdev = &ar71xx_uart_device; ++ ar71xx_uart_data[0].uartclk = ar71xx_ref_freq; + break; + + default: -+ _prom_putchar = prom_putchar_dummy; -+ break; ++ BUG(); + } ++ ++ platform_device_register(pdev); +} + -+void prom_putchar(unsigned char ch) -+{ -+ if (!_prom_putchar) -+ prom_putchar_init(); ++static struct resource ar71xx_mdio_resources[] = { ++ { ++ .name = "mdio_base", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_GE0_BASE, ++ .end = AR71XX_GE0_BASE + 0x200 - 1, ++ } ++}; + -+ _prom_putchar(ch); -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/gpio.c linux-2.6.39/arch/mips/ar71xx/gpio.c ---- linux-2.6.39.orig/arch/mips/ar71xx/gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/gpio.c 2011-08-24 02:41:55.457989607 +0200 -@@ -0,0 +1,193 @@ -+/* -+ * Atheros AR7XXX/AR9XXX SoC GPIO API support -+ * -+ * Copyright (C) 2008-2011 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++static struct ag71xx_mdio_platform_data ar71xx_mdio_data; + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++struct platform_device ar71xx_mdio_device = { ++ .name = "ag71xx-mdio", ++ .id = -1, ++ .resource = ar71xx_mdio_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_mdio_resources), ++ .dev = { ++ .platform_data = &ar71xx_mdio_data, ++ }, ++}; + -+#include ++static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift) ++{ ++ void __iomem *base; ++ u32 t; + -+static DEFINE_SPINLOCK(ar71xx_gpio_lock); ++ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); + -+unsigned long ar71xx_gpio_count; -+EXPORT_SYMBOL(ar71xx_gpio_count); ++ t = __raw_readl(base + cfg_reg); ++ t &= ~(3 << shift); ++ t |= (2 << shift); ++ __raw_writel(t, base + cfg_reg); ++ udelay(100); + -+void __ar71xx_gpio_set_value(unsigned gpio, int value) -+{ -+ void __iomem *base = ar71xx_gpio_base; ++ __raw_writel(pll_val, base + pll_reg); + -+ if (value) -+ __raw_writel(1 << gpio, base + GPIO_REG_SET); -+ else -+ __raw_writel(1 << gpio, base + GPIO_REG_CLEAR); -+} -+EXPORT_SYMBOL(__ar71xx_gpio_set_value); ++ t |= (3 << shift); ++ __raw_writel(t, base + cfg_reg); ++ udelay(100); + -+int __ar71xx_gpio_get_value(unsigned gpio) -+{ -+ return (__raw_readl(ar71xx_gpio_base + GPIO_REG_IN) >> gpio) & 1; -+} -+EXPORT_SYMBOL(__ar71xx_gpio_get_value); ++ t &= ~(3 << shift); ++ __raw_writel(t, base + cfg_reg); ++ udelay(100); + -+static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset) -+{ -+ return __ar71xx_gpio_get_value(offset); -+} ++ printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n", ++ (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg)); + -+static void ar71xx_gpio_set_value(struct gpio_chip *chip, -+ unsigned offset, int value) -+{ -+ __ar71xx_gpio_set_value(offset, value); ++ iounmap(base); +} + -+static int ar71xx_gpio_direction_input(struct gpio_chip *chip, -+ unsigned offset) ++void __init ar71xx_add_device_mdio(u32 phy_mask) +{ -+ void __iomem *base = ar71xx_gpio_base; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ar71xx_gpio_lock, flags); -+ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(1 << offset), -+ base + GPIO_REG_OE); ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7240: ++ ar71xx_mdio_data.is_ar7240 = 1; ++ break; ++ case AR71XX_SOC_AR7241: ++ ar71xx_mdio_data.is_ar7240 = 1; ++ ar71xx_mdio_resources[0].start = AR71XX_GE1_BASE; ++ ar71xx_mdio_resources[0].end = AR71XX_GE1_BASE + 0x200 - 1; ++ break; ++ case AR71XX_SOC_AR7242: ++ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, ++ AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000, ++ AR71XX_ETH0_PLL_SHIFT); ++ break; ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ ar71xx_mdio_data.is_ar7240 = 1; ++ ar71xx_mdio_resources[0].start = AR71XX_GE1_BASE; ++ ar71xx_mdio_resources[0].end = AR71XX_GE1_BASE + 0x200 - 1; ++ break; ++ default: ++ break; ++ } + -+ spin_unlock_irqrestore(&ar71xx_gpio_lock, flags); ++ ar71xx_mdio_data.phy_mask = phy_mask; + -+ return 0; ++ platform_device_register(&ar71xx_mdio_device); +} + -+static int ar71xx_gpio_direction_output(struct gpio_chip *chip, -+ unsigned offset, int value) -+{ -+ void __iomem *base = ar71xx_gpio_base; -+ unsigned long flags; ++struct ar71xx_eth_pll_data ar71xx_eth0_pll_data; ++struct ar71xx_eth_pll_data ar71xx_eth1_pll_data; + -+ spin_lock_irqsave(&ar71xx_gpio_lock, flags); -+ -+ if (value) -+ __raw_writel(1 << offset, base + GPIO_REG_SET); -+ else -+ __raw_writel(1 << offset, base + GPIO_REG_CLEAR); ++static u32 ar71xx_get_eth_pll(unsigned int mac, int speed) ++{ ++ struct ar71xx_eth_pll_data *pll_data; ++ u32 pll_val; + -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) | (1 << offset), -+ base + GPIO_REG_OE); ++ switch (mac) { ++ case 0: ++ pll_data = &ar71xx_eth0_pll_data; ++ break; ++ case 1: ++ pll_data = &ar71xx_eth1_pll_data; ++ break; ++ default: ++ BUG(); ++ } + -+ spin_unlock_irqrestore(&ar71xx_gpio_lock, flags); ++ switch (speed) { ++ case SPEED_10: ++ pll_val = pll_data->pll_10; ++ break; ++ case SPEED_100: ++ pll_val = pll_data->pll_100; ++ break; ++ case SPEED_1000: ++ pll_val = pll_data->pll_1000; ++ break; ++ default: ++ BUG(); ++ } + -+ return 0; ++ return pll_val; +} + -+static struct gpio_chip ar71xx_gpio_chip = { -+ .label = "ar71xx", -+ .get = ar71xx_gpio_get_value, -+ .set = ar71xx_gpio_set_value, -+ .direction_input = ar71xx_gpio_direction_input, -+ .direction_output = ar71xx_gpio_direction_output, -+ .base = 0, -+ .ngpio = AR71XX_GPIO_COUNT, -+}; -+ -+void ar71xx_gpio_function_enable(u32 mask) ++static void ar71xx_set_pll_ge0(int speed) +{ -+ void __iomem *base = ar71xx_gpio_base; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ar71xx_gpio_lock, flags); -+ -+ __raw_writel(__raw_readl(base + GPIO_REG_FUNC) | mask, -+ base + GPIO_REG_FUNC); -+ /* flush write */ -+ (void) __raw_readl(base + GPIO_REG_FUNC); ++ u32 val = ar71xx_get_eth_pll(0, speed); + -+ spin_unlock_irqrestore(&ar71xx_gpio_lock, flags); ++ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK, ++ val, AR71XX_ETH0_PLL_SHIFT); +} + -+void ar71xx_gpio_function_disable(u32 mask) ++static void ar71xx_set_pll_ge1(int speed) +{ -+ void __iomem *base = ar71xx_gpio_base; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ar71xx_gpio_lock, flags); -+ -+ __raw_writel(__raw_readl(base + GPIO_REG_FUNC) & ~mask, -+ base + GPIO_REG_FUNC); -+ /* flush write */ -+ (void) __raw_readl(base + GPIO_REG_FUNC); ++ u32 val = ar71xx_get_eth_pll(1, speed); + -+ spin_unlock_irqrestore(&ar71xx_gpio_lock, flags); ++ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK, ++ val, AR71XX_ETH1_PLL_SHIFT); +} + -+void ar71xx_gpio_function_setup(u32 set, u32 clear) ++static void ar724x_set_pll_ge0(int speed) +{ -+ void __iomem *base = ar71xx_gpio_base; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ar71xx_gpio_lock, flags); -+ -+ __raw_writel((__raw_readl(base + GPIO_REG_FUNC) & ~clear) | set, -+ base + GPIO_REG_FUNC); -+ /* flush write */ -+ (void) __raw_readl(base + GPIO_REG_FUNC); -+ -+ spin_unlock_irqrestore(&ar71xx_gpio_lock, flags); ++ /* TODO */ +} -+EXPORT_SYMBOL(ar71xx_gpio_function_setup); + -+void __init ar71xx_gpio_init(void) ++static void ar724x_set_pll_ge1(int speed) +{ -+ int err; -+ -+ if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE, -+ "AR71xx GPIO controller")) -+ panic("cannot allocate AR71xx GPIO registers page"); -+ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ ar71xx_gpio_chip.ngpio = AR71XX_GPIO_COUNT; -+ break; -+ -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ ar71xx_gpio_chip.ngpio = AR724X_GPIO_COUNT; -+ break; -+ -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT; -+ break; ++ /* TODO */ ++} + -+ case AR71XX_SOC_AR9330: -+ case AR71XX_SOC_AR9331: -+ ar71xx_gpio_chip.ngpio = AR933X_GPIO_COUNT; -+ break; ++static void ar7242_set_pll_ge0(int speed) ++{ ++ u32 val = ar71xx_get_eth_pll(0, speed); + -+ case AR71XX_SOC_AR9341: -+ case AR71XX_SOC_AR9342: -+ case AR71XX_SOC_AR9344: -+ ar71xx_gpio_chip.ngpio = AR934X_GPIO_COUNT; -+ break; ++ ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR7242_PLL_REG_ETH0_INT_CLOCK, ++ val, AR71XX_ETH0_PLL_SHIFT); ++} + -+ default: -+ BUG(); -+ } ++static void ar91xx_set_pll_ge0(int speed) ++{ ++ u32 val = ar71xx_get_eth_pll(0, speed); + -+ err = gpiochip_add(&ar71xx_gpio_chip); -+ if (err) -+ panic("cannot add AR71xx GPIO chip, error=%d", err); ++ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK, ++ val, AR91XX_ETH0_PLL_SHIFT); +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx/irq.c ---- linux-2.6.39.orig/arch/mips/ar71xx/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/irq.c 2011-08-24 02:41:55.457989607 +0200 -@@ -0,0 +1,377 @@ -+/* -+ * Atheros AR71xx SoC specific interrupt handling -+ * -+ * Copyright (C) 2010-2011 Jaiganesh Narayanan -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros 2.6.15 BSP -+ * Parts of this file are based on Atheros 2.6.31 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ + -+#include -+#include -+#include -+#include ++static void ar91xx_set_pll_ge1(int speed) ++{ ++ u32 val = ar71xx_get_eth_pll(1, speed); + -+#include -+#include ++ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK, ++ val, AR91XX_ETH1_PLL_SHIFT); ++} + -+#include ++static void ar933x_set_pll_ge0(int speed) ++{ ++ /* TODO */ ++} + -+static void ar71xx_gpio_irq_dispatch(void) ++static void ar933x_set_pll_ge1(int speed) +{ -+ void __iomem *base = ar71xx_gpio_base; -+ u32 pending; ++ /* TODO */ ++} + -+ pending = __raw_readl(base + GPIO_REG_INT_PENDING) & -+ __raw_readl(base + GPIO_REG_INT_ENABLE); ++static void ar71xx_ddr_flush_ge0(void) ++{ ++ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0); ++} + -+ if (pending) -+ do_IRQ(AR71XX_GPIO_IRQ_BASE + fls(pending) - 1); -+ else -+ spurious_interrupt(); ++static void ar71xx_ddr_flush_ge1(void) ++{ ++ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1); +} + -+static void ar71xx_gpio_irq_unmask(struct irq_data *d) ++static void ar724x_ddr_flush_ge0(void) +{ -+ unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE; -+ void __iomem *base = ar71xx_gpio_base; -+ u32 t; ++ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0); ++} + -+ t = __raw_readl(base + GPIO_REG_INT_ENABLE); -+ __raw_writel(t | (1 << irq), base + GPIO_REG_INT_ENABLE); ++static void ar724x_ddr_flush_ge1(void) ++{ ++ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE1); ++} + -+ /* flush write */ -+ (void) __raw_readl(base + GPIO_REG_INT_ENABLE); ++static void ar91xx_ddr_flush_ge0(void) ++{ ++ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0); +} + -+static void ar71xx_gpio_irq_mask(struct irq_data *d) ++static void ar91xx_ddr_flush_ge1(void) +{ -+ unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE; -+ void __iomem *base = ar71xx_gpio_base; -+ u32 t; ++ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1); ++} + -+ t = __raw_readl(base + GPIO_REG_INT_ENABLE); -+ __raw_writel(t & ~(1 << irq), base + GPIO_REG_INT_ENABLE); ++static void ar933x_ddr_flush_ge0(void) ++{ ++ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE0); ++} + -+ /* flush write */ -+ (void) __raw_readl(base + GPIO_REG_INT_ENABLE); ++static void ar933x_ddr_flush_ge1(void) ++{ ++ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE1); +} + -+static struct irq_chip ar71xx_gpio_irq_chip = { -+ .name = "AR71XX GPIO", -+ .irq_unmask = ar71xx_gpio_irq_unmask, -+ .irq_mask = ar71xx_gpio_irq_mask, -+ .irq_mask_ack = ar71xx_gpio_irq_mask, ++static struct resource ar71xx_eth0_resources[] = { ++ { ++ .name = "mac_base", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_GE0_BASE, ++ .end = AR71XX_GE0_BASE + 0x200 - 1, ++ }, { ++ .name = "mii_ctrl", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_MII_BASE + MII_REG_MII0_CTRL, ++ .end = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3, ++ }, { ++ .name = "mac_irq", ++ .flags = IORESOURCE_IRQ, ++ .start = AR71XX_CPU_IRQ_GE0, ++ .end = AR71XX_CPU_IRQ_GE0, ++ }, +}; + -+static struct irqaction ar71xx_gpio_irqaction = { -+ .handler = no_action, -+ .name = "cascade [AR71XX GPIO]", ++struct ag71xx_platform_data ar71xx_eth0_data = { ++ .reset_bit = RESET_MODULE_GE0_MAC, +}; + -+#define GPIO_INT_ALL 0xffff -+ -+static void __init ar71xx_gpio_irq_init(void) -+{ -+ void __iomem *base = ar71xx_gpio_base; -+ int i; -+ -+ __raw_writel(0, base + GPIO_REG_INT_ENABLE); -+ __raw_writel(0, base + GPIO_REG_INT_PENDING); -+ -+ /* setup type of all GPIO interrupts to level sensitive */ -+ __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_TYPE); ++struct platform_device ar71xx_eth0_device = { ++ .name = "ag71xx", ++ .id = 0, ++ .resource = ar71xx_eth0_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_eth0_resources), ++ .dev = { ++ .platform_data = &ar71xx_eth0_data, ++ }, ++}; + -+ /* setup polarity of all GPIO interrupts to active high */ -+ __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_POLARITY); ++static struct resource ar71xx_eth1_resources[] = { ++ { ++ .name = "mac_base", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_GE1_BASE, ++ .end = AR71XX_GE1_BASE + 0x200 - 1, ++ }, { ++ .name = "mii_ctrl", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_MII_BASE + MII_REG_MII1_CTRL, ++ .end = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3, ++ }, { ++ .name = "mac_irq", ++ .flags = IORESOURCE_IRQ, ++ .start = AR71XX_CPU_IRQ_GE1, ++ .end = AR71XX_CPU_IRQ_GE1, ++ }, ++}; + -+ for (i = AR71XX_GPIO_IRQ_BASE; -+ i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++) -+ irq_set_chip_and_handler(i, &ar71xx_gpio_irq_chip, -+ handle_level_irq); ++struct ag71xx_platform_data ar71xx_eth1_data = { ++ .reset_bit = RESET_MODULE_GE1_MAC, ++}; + -+ setup_irq(AR71XX_MISC_IRQ_GPIO, &ar71xx_gpio_irqaction); -+} ++struct platform_device ar71xx_eth1_device = { ++ .name = "ag71xx", ++ .id = 1, ++ .resource = ar71xx_eth1_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_eth1_resources), ++ .dev = { ++ .platform_data = &ar71xx_eth1_data, ++ }, ++}; + -+static void ar71xx_misc_irq_dispatch(void) -+{ -+ u32 pending; ++#define AR71XX_PLL_VAL_1000 0x00110000 ++#define AR71XX_PLL_VAL_100 0x00001099 ++#define AR71XX_PLL_VAL_10 0x00991099 + -+ pending = ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_STATUS) -+ & ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE); ++#define AR724X_PLL_VAL_1000 0x00110000 ++#define AR724X_PLL_VAL_100 0x00001099 ++#define AR724X_PLL_VAL_10 0x00991099 + -+ if (pending & MISC_INT_UART) -+ do_IRQ(AR71XX_MISC_IRQ_UART); ++#define AR7242_PLL_VAL_1000 0x1c000000 ++#define AR7242_PLL_VAL_100 0x00000101 ++#define AR7242_PLL_VAL_10 0x00001616 + -+ else if (pending & MISC_INT_DMA) -+ do_IRQ(AR71XX_MISC_IRQ_DMA); ++#define AR91XX_PLL_VAL_1000 0x1a000000 ++#define AR91XX_PLL_VAL_100 0x13000a44 ++#define AR91XX_PLL_VAL_10 0x00441099 + -+ else if (pending & MISC_INT_PERFC) -+ do_IRQ(AR71XX_MISC_IRQ_PERFC); ++#define AR933X_PLL_VAL_1000 0x00110000 ++#define AR933X_PLL_VAL_100 0x00001099 ++#define AR933X_PLL_VAL_10 0x00991099 + -+ else if (pending & MISC_INT_TIMER) -+ do_IRQ(AR71XX_MISC_IRQ_TIMER); ++static void __init ar71xx_init_eth_pll_data(unsigned int id) ++{ ++ struct ar71xx_eth_pll_data *pll_data; ++ u32 pll_10, pll_100, pll_1000; + -+ else if (pending & MISC_INT_OHCI) -+ do_IRQ(AR71XX_MISC_IRQ_OHCI); ++ switch (id) { ++ case 0: ++ pll_data = &ar71xx_eth0_pll_data; ++ break; ++ case 1: ++ pll_data = &ar71xx_eth1_pll_data; ++ break; ++ default: ++ BUG(); ++ } + -+ else if (pending & MISC_INT_ERROR) -+ do_IRQ(AR71XX_MISC_IRQ_ERROR); ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ pll_10 = AR71XX_PLL_VAL_10; ++ pll_100 = AR71XX_PLL_VAL_100; ++ pll_1000 = AR71XX_PLL_VAL_1000; ++ break; + -+ else if (pending & MISC_INT_GPIO) -+ ar71xx_gpio_irq_dispatch(); ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ pll_10 = AR724X_PLL_VAL_10; ++ pll_100 = AR724X_PLL_VAL_100; ++ pll_1000 = AR724X_PLL_VAL_1000; ++ break; + -+ else if (pending & MISC_INT_WDOG) -+ do_IRQ(AR71XX_MISC_IRQ_WDOG); ++ case AR71XX_SOC_AR7242: ++ pll_10 = AR7242_PLL_VAL_10; ++ pll_100 = AR7242_PLL_VAL_100; ++ pll_1000 = AR7242_PLL_VAL_1000; ++ break; + -+ else if (pending & MISC_INT_TIMER2) -+ do_IRQ(AR71XX_MISC_IRQ_TIMER2); ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ pll_10 = AR91XX_PLL_VAL_10; ++ pll_100 = AR91XX_PLL_VAL_100; ++ pll_1000 = AR91XX_PLL_VAL_1000; ++ break; + -+ else if (pending & MISC_INT_TIMER3) -+ do_IRQ(AR71XX_MISC_IRQ_TIMER3); ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ pll_10 = AR933X_PLL_VAL_10; ++ pll_100 = AR933X_PLL_VAL_100; ++ pll_1000 = AR933X_PLL_VAL_1000; ++ break; + -+ else if (pending & MISC_INT_TIMER4) -+ do_IRQ(AR71XX_MISC_IRQ_TIMER4); ++ default: ++ BUG(); ++ } + -+ else if (pending & MISC_INT_DDR_PERF) -+ do_IRQ(AR71XX_MISC_IRQ_DDR_PERF); ++ if (!pll_data->pll_10) ++ pll_data->pll_10 = pll_10; + -+ else if (pending & MISC_INT_ENET_LINK) -+ do_IRQ(AR71XX_MISC_IRQ_ENET_LINK); ++ if (!pll_data->pll_100) ++ pll_data->pll_100 = pll_100; + -+ else -+ spurious_interrupt(); ++ if (!pll_data->pll_1000) ++ pll_data->pll_1000 = pll_1000; +} + -+static void ar71xx_misc_irq_unmask(struct irq_data *d) ++static int ar71xx_eth_instance __initdata; ++void __init ar71xx_add_device_eth(unsigned int id) +{ -+ unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; -+ void __iomem *base = ar71xx_reset_base; -+ u32 t; -+ -+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); -+ __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); -+ -+ /* flush write */ -+ (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); -+} ++ struct platform_device *pdev; ++ struct ag71xx_platform_data *pdata; + -+static void ar71xx_misc_irq_mask(struct irq_data *d) -+{ -+ unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; -+ void __iomem *base = ar71xx_reset_base; -+ u32 t; ++ ar71xx_init_eth_pll_data(id); + -+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); -+ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); ++ switch (id) { ++ case 0: ++ switch (ar71xx_eth0_data.phy_if_mode) { ++ case PHY_INTERFACE_MODE_MII: ++ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII; ++ break; ++ case PHY_INTERFACE_MODE_GMII: ++ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII; ++ break; ++ case PHY_INTERFACE_MODE_RMII: ++ ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII; ++ break; ++ default: ++ printk(KERN_ERR "ar71xx: invalid PHY interface mode " ++ "for eth0\n"); ++ return; ++ } ++ pdev = &ar71xx_eth0_device; ++ break; ++ case 1: ++ switch (ar71xx_eth1_data.phy_if_mode) { ++ case PHY_INTERFACE_MODE_RMII: ++ ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII; ++ break; ++ default: ++ printk(KERN_ERR "ar71xx: invalid PHY interface mode " ++ "for eth1\n"); ++ return; ++ } ++ pdev = &ar71xx_eth1_device; ++ break; ++ default: ++ printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id); ++ return; ++ } + -+ /* flush write */ -+ (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); -+} ++ pdata = pdev->dev.platform_data; + -+static void ar724x_misc_irq_ack(struct irq_data *d) -+{ -+ unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; -+ void __iomem *base = ar71xx_reset_base; -+ u32 t; ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1 ++ : ar71xx_ddr_flush_ge0; ++ pdata->set_pll = id ? ar71xx_set_pll_ge1 ++ : ar71xx_set_pll_ge0; ++ break; + -+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); -+ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS); ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1 ++ : ar71xx_ddr_flush_ge0; ++ pdata->set_pll = id ? ar71xx_set_pll_ge1 ++ : ar71xx_set_pll_ge0; ++ pdata->has_gbit = 1; ++ break; + -+ /* flush write */ -+ (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); -+} ++ case AR71XX_SOC_AR7242: ++ ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO | ++ RESET_MODULE_GE0_PHY; ++ ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO | ++ RESET_MODULE_GE1_PHY; ++ pdata->ddr_flush = id ? ar724x_ddr_flush_ge1 ++ : ar724x_ddr_flush_ge0; ++ pdata->set_pll = id ? ar724x_set_pll_ge1 ++ : ar7242_set_pll_ge0; ++ pdata->has_gbit = 1; ++ pdata->is_ar724x = 1; + -+static struct irq_chip ar71xx_misc_irq_chip = { -+ .name = "AR71XX MISC", -+ .irq_unmask = ar71xx_misc_irq_unmask, -+ .irq_mask = ar71xx_misc_irq_mask, -+}; ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; ++ break; + -+static struct irqaction ar71xx_misc_irqaction = { -+ .handler = no_action, -+ .name = "cascade [AR71XX MISC]", -+}; ++ case AR71XX_SOC_AR7241: ++ ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO; ++ ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO; ++ /* fall through */ ++ case AR71XX_SOC_AR7240: ++ ar71xx_eth0_data.reset_bit |= RESET_MODULE_GE0_PHY; ++ ar71xx_eth1_data.reset_bit |= RESET_MODULE_GE1_PHY; ++ pdata->ddr_flush = id ? ar724x_ddr_flush_ge1 ++ : ar724x_ddr_flush_ge0; ++ pdata->set_pll = id ? ar724x_set_pll_ge1 ++ : ar724x_set_pll_ge0; ++ pdata->is_ar724x = 1; ++ if (ar71xx_soc == AR71XX_SOC_AR7240) ++ pdata->is_ar7240 = 1; + -+static void __init ar71xx_misc_irq_init(void) -+{ -+ void __iomem *base = ar71xx_reset_base; -+ int i; ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; ++ break; + -+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); -+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); ++ case AR71XX_SOC_AR9130: ++ pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1 ++ : ar91xx_ddr_flush_ge0; ++ pdata->set_pll = id ? ar91xx_set_pll_ge1 ++ : ar91xx_set_pll_ge0; ++ pdata->is_ar91xx = 1; ++ break; ++ ++ case AR71XX_SOC_AR9132: ++ pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1 ++ : ar91xx_ddr_flush_ge0; ++ pdata->set_pll = id ? ar91xx_set_pll_ge1 ++ : ar91xx_set_pll_ge0; ++ pdata->is_ar91xx = 1; ++ pdata->has_gbit = 1; ++ break; + -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: + case AR71XX_SOC_AR9330: + case AR71XX_SOC_AR9331: -+ case AR71XX_SOC_AR9341: -+ case AR71XX_SOC_AR9342: -+ case AR71XX_SOC_AR9344: -+ ar71xx_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; ++ ar71xx_eth0_data.reset_bit = AR933X_RESET_GE0_MAC | ++ AR933X_RESET_GE0_MDIO; ++ ar71xx_eth1_data.reset_bit = AR933X_RESET_GE1_MAC | ++ AR933X_RESET_GE1_MDIO; ++ pdata->ddr_flush = id ? ar933x_ddr_flush_ge1 ++ : ar933x_ddr_flush_ge0; ++ pdata->set_pll = id ? ar933x_set_pll_ge1 ++ : ar933x_set_pll_ge0; ++ pdata->has_gbit = 1; ++ pdata->is_ar724x = 1; ++ ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; + break; ++ ++ default: ++ BUG(); ++ } ++ ++ switch (pdata->phy_if_mode) { ++ case PHY_INTERFACE_MODE_GMII: ++ case PHY_INTERFACE_MODE_RGMII: ++ if (!pdata->has_gbit) { ++ printk(KERN_ERR "ar71xx: no gbit available on eth%d\n", ++ id); ++ return; ++ } ++ /* fallthrough */ + default: -+ ar71xx_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; + break; + } + -+ for (i = AR71XX_MISC_IRQ_BASE; -+ i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++) -+ irq_set_chip_and_handler(i, &ar71xx_misc_irq_chip, -+ handle_level_irq); ++ if (!is_valid_ether_addr(pdata->mac_addr)) { ++ random_ether_addr(pdata->mac_addr); ++ printk(KERN_DEBUG ++ "ar71xx: using random MAC address for eth%d\n", ++ ar71xx_eth_instance); ++ } + -+ setup_irq(AR71XX_CPU_IRQ_MISC, &ar71xx_misc_irqaction); -+} ++ if (pdata->mii_bus_dev == NULL) ++ pdata->mii_bus_dev = &ar71xx_mdio_device.dev; + -+/* -+ * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for -+ * these devices typically allocate coherent DMA memory, however the -+ * DMA controller may still have some unsynchronized data in the FIFO. -+ * Issue a flush in the handlers to ensure that the driver sees -+ * the update. -+ */ -+static void ar71xx_ip2_handler(void) -+{ -+ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_PCI); -+ do_IRQ(AR71XX_CPU_IRQ_IP2); -+} ++ /* Reset the device */ ++ ar71xx_device_stop(pdata->reset_bit); ++ mdelay(100); + -+static void ar724x_ip2_handler(void) -+{ -+ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_PCIE); -+ do_IRQ(AR71XX_CPU_IRQ_IP2); -+} ++ ar71xx_device_start(pdata->reset_bit); ++ mdelay(100); + -+static void ar913x_ip2_handler(void) -+{ -+ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_WMAC); -+ do_IRQ(AR71XX_CPU_IRQ_IP2); ++ platform_device_register(pdev); ++ ar71xx_eth_instance++; +} + -+static void ar933x_ip2_handler(void) -+{ -+ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_WMAC); -+ do_IRQ(AR71XX_CPU_IRQ_IP2); -+} ++static struct resource ar71xx_spi_resources[] = { ++ [0] = { ++ .start = AR71XX_SPI_BASE, ++ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; + -+static void ar934x_ip2_handler(void) ++static struct platform_device ar71xx_spi_device = { ++ .name = "ar71xx-spi", ++ .id = -1, ++ .resource = ar71xx_spi_resources, ++ .num_resources = ARRAY_SIZE(ar71xx_spi_resources), ++}; ++ ++void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata, ++ struct spi_board_info const *info, ++ unsigned n) +{ -+ ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_PCIE); -+ do_IRQ(AR71XX_CPU_IRQ_IP2); ++ spi_register_board_info(info, n); ++ ar71xx_spi_device.dev.platform_data = pdata; ++ platform_device_register(&ar71xx_spi_device); +} + -+static void ar71xx_ip3_handler(void) ++void __init ar71xx_add_device_wdt(void) +{ -+ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_USB); -+ do_IRQ(AR71XX_CPU_IRQ_USB); ++ platform_device_register_simple("ar71xx-wdt", -1, NULL, 0); +} + -+static void ar724x_ip3_handler(void) ++void __init ar71xx_set_mac_base(unsigned char *mac) +{ -+ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_USB); -+ do_IRQ(AR71XX_CPU_IRQ_USB); ++ memcpy(ar71xx_mac_base, mac, ETH_ALEN); +} + -+static void ar913x_ip3_handler(void) ++void __init ar71xx_parse_mac_addr(char *mac_str) +{ -+ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_USB); -+ do_IRQ(AR71XX_CPU_IRQ_USB); ++ u8 tmp[ETH_ALEN]; ++ int t; ++ ++ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", ++ &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); ++ ++ if (t != ETH_ALEN) ++ t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx", ++ &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); ++ ++ if (t == ETH_ALEN) ++ ar71xx_set_mac_base(tmp); ++ else ++ printk(KERN_DEBUG "ar71xx: failed to parse mac address " ++ "\"%s\"\n", mac_str); +} + -+static void ar933x_ip3_handler(void) ++static int __init ar71xx_ethaddr_setup(char *str) +{ -+ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_USB); -+ do_IRQ(AR71XX_CPU_IRQ_USB); ++ ar71xx_parse_mac_addr(str); ++ return 1; +} ++__setup("ethaddr=", ar71xx_ethaddr_setup); + -+static void ar934x_ip3_handler(void) ++static int __init ar71xx_kmac_setup(char *str) +{ -+ do_IRQ(AR71XX_CPU_IRQ_USB); ++ ar71xx_parse_mac_addr(str); ++ return 1; +} ++__setup("kmac=", ar71xx_kmac_setup); + -+static void (*ip2_handler)(void); -+static void (*ip3_handler)(void); -+ -+asmlinkage void plat_irq_dispatch(void) ++void __init ar71xx_init_mac(unsigned char *dst, const unsigned char *src, ++ unsigned offset) +{ -+ unsigned long pending; -+ -+ pending = read_c0_status() & read_c0_cause() & ST0_IM; -+ -+ if (pending & STATUSF_IP7) -+ do_IRQ(AR71XX_CPU_IRQ_TIMER); -+ -+ else if (pending & STATUSF_IP2) -+ ip2_handler(); -+ -+ else if (pending & STATUSF_IP4) -+ do_IRQ(AR71XX_CPU_IRQ_GE0); ++ u32 t; + -+ else if (pending & STATUSF_IP5) -+ do_IRQ(AR71XX_CPU_IRQ_GE1); ++ if (!is_valid_ether_addr(src)) { ++ memset(dst, '\0', ETH_ALEN); ++ return; ++ } + -+ else if (pending & STATUSF_IP3) -+ ip3_handler(); ++ t = (((u32) src[3]) << 16) + (((u32) src[4]) << 8) + ((u32) src[5]); ++ t += offset; + -+ else if (pending & STATUSF_IP6) -+ ar71xx_misc_irq_dispatch(); -+ -+ spurious_interrupt(); ++ dst[0] = src[0]; ++ dst[1] = src[1]; ++ dst[2] = src[2]; ++ dst[3] = (t >> 16) & 0xff; ++ dst[4] = (t >> 8) & 0xff; ++ dst[5] = t & 0xff; +} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/devices.h linux-2.6.39/arch/mips/ar71xx/devices.h +--- linux-2.6.39.orig/arch/mips/ar71xx/devices.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/devices.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,50 @@ ++/* ++ * Atheros AR71xx SoC device definitions ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+void __init arch_init_irq(void) -+{ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ ip2_handler = ar71xx_ip2_handler; -+ ip3_handler = ar71xx_ip3_handler; -+ break; ++#ifndef __AR71XX_DEVICES_H ++#define __AR71XX_DEVICES_H + -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ ip2_handler = ar724x_ip2_handler; -+ ip3_handler = ar724x_ip3_handler; -+ break; ++#include + -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ ip2_handler = ar913x_ip2_handler; -+ ip3_handler = ar913x_ip3_handler; -+ break; ++struct platform_device; + -+ case AR71XX_SOC_AR9330: -+ case AR71XX_SOC_AR9331: -+ ip2_handler = ar933x_ip2_handler; -+ ip3_handler = ar933x_ip3_handler; -+ break; ++void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata, ++ struct spi_board_info const *info, ++ unsigned n) __init; + -+ case AR71XX_SOC_AR9341: -+ case AR71XX_SOC_AR9342: -+ case AR71XX_SOC_AR9344: -+ ip2_handler = ar934x_ip2_handler; -+ ip3_handler = ar934x_ip3_handler; -+ break; ++extern unsigned char ar71xx_mac_base[] __initdata; ++void ar71xx_parse_mac_addr(char *mac_str) __init; ++void ar71xx_init_mac(unsigned char *dst, const unsigned char *src, ++ unsigned offset) __init; + -+ default: -+ BUG(); -+ } ++struct ar71xx_eth_pll_data { ++ u32 pll_10; ++ u32 pll_100; ++ u32 pll_1000; ++}; + -+ mips_cpu_irq_init(); ++extern struct ar71xx_eth_pll_data ar71xx_eth0_pll_data; ++extern struct ar71xx_eth_pll_data ar71xx_eth1_pll_data; + -+ ar71xx_misc_irq_init(); ++extern struct ag71xx_platform_data ar71xx_eth0_data; ++extern struct ag71xx_platform_data ar71xx_eth1_data; ++extern struct platform_device ar71xx_eth0_device; ++extern struct platform_device ar71xx_eth1_device; ++void ar71xx_add_device_eth(unsigned int id) __init; + -+ cp0_perfcount_irq = AR71XX_MISC_IRQ_PERFC; ++extern struct platform_device ar71xx_mdio_device; ++void ar71xx_add_device_mdio(u32 phy_mask) __init; + -+ ar71xx_gpio_irq_init(); -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Kconfig linux-2.6.39/arch/mips/ar71xx/Kconfig ---- linux-2.6.39.orig/arch/mips/ar71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/Kconfig 2011-08-24 04:20:27.209240389 +0200 -@@ -0,0 +1,420 @@ -+if ATHEROS_AR71XX ++void ar71xx_add_device_uart(void) __init; + -+menu "Atheros AR71xx machine selection" ++void ar71xx_add_device_wdt(void) __init; + -+config AR71XX_MACH_AP81 -+ bool "Atheros AP81 board support" -+ select SOC_AR913X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++#endif /* __AR71XX_DEVICES_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c linux-2.6.39/arch/mips/ar71xx/early_printk.c +--- linux-2.6.39.orig/arch/mips/ar71xx/early_printk.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/early_printk.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,96 @@ ++/* ++ * Atheros AR7xxx/AR9xxx SoC early printk support ++ * ++ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+config AR71XX_MACH_AP83 -+ bool "Atheros AP83 board support" -+ select SOC_AR913X -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++#include ++#include ++#include ++#include + -+config AR71XX_MACH_AP96 -+ bool "Atheros AP96 board support" -+ select SOC_AR71XX -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP94_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++#include ++#include + -+config AR71XX_MACH_AP121 -+ bool "Atheros AP121 board support" -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ select AR71XX_DEV_AR9XXX_WMAC -+ select SOC_AR933X -+ default n ++static void (*_prom_putchar) (unsigned char); + -+config AR71XX_MACH_DB120 -+ bool "Atheros DB120 board support" -+ select SOC_AR934X -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_DB120_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val) ++{ ++ u32 t; + -+config AR71XX_MACH_DIR_600_A1 -+ bool "D-Link DIR-600 rev. A1 support" -+ select SOC_AR724X -+ select AR71XX_DEV_AP91_PCI if PCI -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_NVRAM -+ default n ++ do { ++ t = __raw_readl(reg); ++ if ((t & mask) == val) ++ break; ++ } while (1); ++} + -+config AR71XX_MACH_DIR_615_C1 -+ bool "D-Link DIR-615 rev. C1 support" -+ select SOC_AR913X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_NVRAM -+ default n ++static void prom_putchar_ar71xx(unsigned char ch) ++{ ++ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); + -+config AR71XX_MACH_DIR_825_B1 -+ bool "D-Link DIR-825 rev. B1 board support" -+ select SOC_AR71XX -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP94_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++ prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); ++ __raw_writel(ch, base + UART_TX * 4); ++ prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); ++} + -+config AR71XX_MACH_JA76PF -+ bool "jjPlus JA76PF board support" -+ select SOC_AR71XX -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++static void prom_putchar_ar933x(unsigned char ch) ++{ ++ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE)); + -+config AR71XX_MACH_JWAP003 -+ bool "jjPlus JWAP003 board support" -+ select SOC_AR71XX -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_USB -+ default n ++ prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, ++ AR933X_UART_DATA_TX_CSR); ++ __raw_writel(AR933X_UART_DATA_TX_CSR | ch, base + AR933X_UART_DATA_REG); ++ prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, ++ AR933X_UART_DATA_TX_CSR); ++} + -+config AR71XX_MACH_PB42 -+ bool "Atheros PB42 board support" -+ select SOC_AR71XX -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB42_PCI if PCI -+ default n ++static void prom_putchar_dummy(unsigned char ch) ++{ ++ /* nothing to do */ ++} + -+config AR71XX_MACH_PB44 -+ bool "Atheros PB44 board support" -+ select SOC_AR71XX -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++static void prom_putchar_init(void) ++{ ++ void __iomem *base; ++ u32 id; + -+config AR71XX_MACH_PB92 -+ bool "Atheros PB92 board support" -+ select SOC_AR724X -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB9X_PCI if PCI -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n -+ -+config AR71XX_MACH_AW_NR580 -+ bool "AzureWave AW-NR580 board support" -+ select SOC_AR71XX -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++ base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE)); ++ id = __raw_readl(base + AR71XX_RESET_REG_REV_ID); ++ id &= REV_ID_MAJOR_MASK; + -+config AR71XX_MACH_WZR_HP_AG300H -+ bool "Buffalo WZR-HP-AG300H board support" -+ select SOC_AR71XX -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++ switch (id) { ++ case REV_ID_MAJOR_AR71XX: ++ case REV_ID_MAJOR_AR7240: ++ case REV_ID_MAJOR_AR7241: ++ case REV_ID_MAJOR_AR7242: ++ case REV_ID_MAJOR_AR913X: ++ case REV_ID_MAJOR_AR9341: ++ case REV_ID_MAJOR_AR9342: ++ case REV_ID_MAJOR_AR9344: ++ _prom_putchar = prom_putchar_ar71xx; ++ break; + -+config AR71XX_MACH_WZR_HP_G300NH -+ bool "Buffalo WZR-HP-G300NH board support" -+ select SOC_AR913X -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ select RTL8366_SMI -+ default n ++ case REV_ID_MAJOR_AR9330: ++ case REV_ID_MAJOR_AR9331: ++ _prom_putchar = prom_putchar_ar933x; ++ break; + -+config AR71XX_MACH_WP543 -+ bool "Compex WP543/WPJ543 board support" -+ select SOC_AR71XX -+ select MYLOADER -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++ default: ++ _prom_putchar = prom_putchar_dummy; ++ break; ++ } ++} + -+config AR71XX_MACH_WRT160NL -+ bool "Linksys WRT160NL board support" -+ select SOC_AR913X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ select AR71XX_NVRAM -+ default n ++void prom_putchar(unsigned char ch) ++{ ++ if (!_prom_putchar) ++ prom_putchar_init(); + -+config AR71XX_MACH_WRT400N -+ bool "Linksys WRT400N board support" -+ select SOC_AR71XX -+ select AR71XX_DEV_AP94_PCI if PCI -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++ _prom_putchar(ch); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/gpio.c linux-2.6.39/arch/mips/ar71xx/gpio.c +--- linux-2.6.39.orig/arch/mips/ar71xx/gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/gpio.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,193 @@ ++/* ++ * Atheros AR7XXX/AR9XXX SoC GPIO API support ++ * ++ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+config AR71XX_MACH_RB4XX -+ bool "MikroTik RouterBOARD 4xx series support" -+ select SOC_AR71XX -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+config AR71XX_MACH_RB750 -+ bool "MikroTik RouterBOARD 750 support" -+ select SOC_AR724X -+ default n ++#include + -+config AR71XX_MACH_WNDR3700 -+ bool "NETGEAR WNDR3700 board support" -+ select SOC_AR71XX -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP94_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++static DEFINE_SPINLOCK(ar71xx_gpio_lock); + -+config AR71XX_MACH_WNR2000 -+ bool "NETGEAR WNR2000 board support" -+ select SOC_AR913X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++unsigned long ar71xx_gpio_count; ++EXPORT_SYMBOL(ar71xx_gpio_count); + -+config AR71XX_MACH_MZK_W04NU -+ bool "Planex MZK-W04NU board support" -+ select SOC_AR913X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++void __ar71xx_gpio_set_value(unsigned gpio, int value) ++{ ++ void __iomem *base = ar71xx_gpio_base; + -+config AR71XX_MACH_MZK_W300NH -+ bool "Planex MZK-W300NH board support" -+ select SOC_AR913X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++ if (value) ++ __raw_writel(1 << gpio, base + GPIO_REG_SET); ++ else ++ __raw_writel(1 << gpio, base + GPIO_REG_CLEAR); ++} ++EXPORT_SYMBOL(__ar71xx_gpio_set_value); + -+config AR71XX_MACH_NBG460N -+ bool "Zyxel NBG460N/550N/550NH board support" -+ select SOC_AR913X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++int __ar71xx_gpio_get_value(unsigned gpio) ++{ ++ return (__raw_readl(ar71xx_gpio_base + GPIO_REG_IN) >> gpio) & 1; ++} ++EXPORT_SYMBOL(__ar71xx_gpio_get_value); + -+config AR71XX_MACH_TL_MR3X20 -+ bool "TP-LINK TL-MR3220/3420 support" -+ select SOC_AR724X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP91_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset) ++{ ++ return __ar71xx_gpio_get_value(offset); ++} + -+config AR71XX_MACH_TL_WA901ND -+ bool "TP-LINK TL-WA901ND support" -+ select SOC_AR724X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP91_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++static void ar71xx_gpio_set_value(struct gpio_chip *chip, ++ unsigned offset, int value) ++{ ++ __ar71xx_gpio_set_value(offset, value); ++} + -+config AR71XX_MACH_TL_WA901ND_V2 -+ bool "TP-LINK TL-WA901ND v2 support" -+ select SOC_AR913X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++static int ar71xx_gpio_direction_input(struct gpio_chip *chip, ++ unsigned offset) ++{ ++ void __iomem *base = ar71xx_gpio_base; ++ unsigned long flags; + -+config AR71XX_MACH_TL_WR741ND -+ bool "TP-LINK TL-WR741ND support" -+ select SOC_AR724X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP91_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++ spin_lock_irqsave(&ar71xx_gpio_lock, flags); + -+config AR71XX_MACH_TL_WR841N_V1 -+ bool "TP-LINK TL-WR841N v1 support" -+ select SOC_AR71XX -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_DSA -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(1 << offset), ++ base + GPIO_REG_OE); + -+config AR71XX_MACH_TL_WR941ND -+ bool "TP-LINK TL-WR941ND support" -+ select SOC_AR913X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_DSA -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++ spin_unlock_irqrestore(&ar71xx_gpio_lock, flags); + -+config AR71XX_MACH_TL_WR1043ND -+ bool "TP-LINK TL-WR1043ND support" -+ select SOC_AR913X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_USB -+ default n ++ return 0; ++} + -+config AR71XX_MACH_TEW_632BRP -+ bool "TRENDnet TEW-632BRP support" -+ select SOC_AR913X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AR9XXX_WMAC -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_NVRAM -+ default n ++static int ar71xx_gpio_direction_output(struct gpio_chip *chip, ++ unsigned offset, int value) ++{ ++ void __iomem *base = ar71xx_gpio_base; ++ unsigned long flags; + -+config AR71XX_MACH_UBNT -+ bool "Ubiquiti AR71xx based boards support" -+ select SOC_AR71XX -+ select SOC_AR724X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP91_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ select AR71XX_DEV_PB42_PCI if PCI -+ select AR71XX_DEV_USB -+ default n ++ spin_lock_irqsave(&ar71xx_gpio_lock, flags); + -+config AR71XX_MACH_EAP7660D -+ bool "Senao EAP7660D support" -+ select SOC_AR71XX -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++ if (value) ++ __raw_writel(1 << offset, base + GPIO_REG_SET); ++ else ++ __raw_writel(1 << offset, base + GPIO_REG_CLEAR); + -+config AR71XX_MACH_ZCN_1523H -+ bool "Zcomax ZCN-1523H support" -+ select SOC_AR724X -+ select AR71XX_DEV_M25P80 -+ select AR71XX_DEV_AP91_PCI if PCI -+ select AR71XX_DEV_GPIO_BUTTONS -+ select AR71XX_DEV_LEDS_GPIO -+ default n ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) | (1 << offset), ++ base + GPIO_REG_OE); + -+endmenu ++ spin_unlock_irqrestore(&ar71xx_gpio_lock, flags); + -+config SOC_AR71XX -+ bool -+ select USB_ARCH_HAS_EHCI -+ select USB_ARCH_HAS_OHCI ++ return 0; ++} + -+config SOC_AR724X -+ bool -+ select USB_ARCH_HAS_EHCI -+ select USB_ARCH_HAS_OHCI ++static struct gpio_chip ar71xx_gpio_chip = { ++ .label = "ar71xx", ++ .get = ar71xx_gpio_get_value, ++ .set = ar71xx_gpio_set_value, ++ .direction_input = ar71xx_gpio_direction_input, ++ .direction_output = ar71xx_gpio_direction_output, ++ .base = 0, ++ .ngpio = AR71XX_GPIO_COUNT, ++}; + -+config SOC_AR913X -+ bool -+ select USB_ARCH_HAS_EHCI ++void ar71xx_gpio_function_enable(u32 mask) ++{ ++ void __iomem *base = ar71xx_gpio_base; ++ unsigned long flags; + -+config SOC_AR934X -+ bool -+ select USB_ARCH_HAS_EHCI ++ spin_lock_irqsave(&ar71xx_gpio_lock, flags); + -+config AR71XX_DEV_M25P80 -+ def_bool n ++ __raw_writel(__raw_readl(base + GPIO_REG_FUNC) | mask, ++ base + GPIO_REG_FUNC); ++ /* flush write */ ++ (void) __raw_readl(base + GPIO_REG_FUNC); + -+config AR71XX_DEV_AP91_PCI -+ select AR71XX_PCI_ATH9K_FIXUP -+ def_bool n ++ spin_unlock_irqrestore(&ar71xx_gpio_lock, flags); ++} + -+config AR71XX_DEV_AP94_PCI -+ select AR71XX_PCI_ATH9K_FIXUP -+ def_bool n ++void ar71xx_gpio_function_disable(u32 mask) ++{ ++ void __iomem *base = ar71xx_gpio_base; ++ unsigned long flags; + -+config AR71XX_DEV_AR9XXX_WMAC -+ def_bool n ++ spin_lock_irqsave(&ar71xx_gpio_lock, flags); + -+config AR71XX_DEV_DB120_PCI -+ select AR71XX_PCI_ATH9K_FIXUP -+ def_bool n ++ __raw_writel(__raw_readl(base + GPIO_REG_FUNC) & ~mask, ++ base + GPIO_REG_FUNC); ++ /* flush write */ ++ (void) __raw_readl(base + GPIO_REG_FUNC); + -+config AR71XX_DEV_DSA -+ def_bool n ++ spin_unlock_irqrestore(&ar71xx_gpio_lock, flags); ++} + -+config AR71XX_DEV_GPIO_BUTTONS -+ def_bool n ++void ar71xx_gpio_function_setup(u32 set, u32 clear) ++{ ++ void __iomem *base = ar71xx_gpio_base; ++ unsigned long flags; + -+config AR71XX_DEV_LEDS_GPIO -+ def_bool n ++ spin_lock_irqsave(&ar71xx_gpio_lock, flags); + -+config AR71XX_DEV_PB42_PCI -+ def_bool n ++ __raw_writel((__raw_readl(base + GPIO_REG_FUNC) & ~clear) | set, ++ base + GPIO_REG_FUNC); ++ /* flush write */ ++ (void) __raw_readl(base + GPIO_REG_FUNC); + -+config AR71XX_DEV_PB9X_PCI -+ def_bool n ++ spin_unlock_irqrestore(&ar71xx_gpio_lock, flags); ++} ++EXPORT_SYMBOL(ar71xx_gpio_function_setup); + -+config AR71XX_DEV_USB -+ def_bool n ++void __init ar71xx_gpio_init(void) ++{ ++ int err; + -+config AR71XX_NVRAM -+ def_bool n ++ if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE, ++ "AR71xx GPIO controller")) ++ panic("cannot allocate AR71xx GPIO registers page"); + -+config AR71XX_PCI_ATH9K_FIXUP -+ def_bool n ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ ar71xx_gpio_chip.ngpio = AR71XX_GPIO_COUNT; ++ break; + -+config SOC_AR933X -+ bool -+ select USB_ARCH_HAS_EHCI ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ ar71xx_gpio_chip.ngpio = AR724X_GPIO_COUNT; ++ break; + -+endif -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap121.c linux-2.6.39/arch/mips/ar71xx/mach-ap121.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap121.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-ap121.c 2011-08-24 02:41:55.477989660 +0200 -@@ -0,0 +1,245 @@ ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT; ++ break; ++ ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ ar71xx_gpio_chip.ngpio = AR933X_GPIO_COUNT; ++ break; ++ ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ar71xx_gpio_chip.ngpio = AR934X_GPIO_COUNT; ++ break; ++ ++ default: ++ BUG(); ++ } ++ ++ err = gpiochip_add(&ar71xx_gpio_chip); ++ if (err) ++ panic("cannot add AR71xx GPIO chip, error=%d", err); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/irq.c linux-2.6.39/arch/mips/ar71xx/irq.c +--- linux-2.6.39.orig/arch/mips/ar71xx/irq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/irq.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,377 @@ +/* -+ * Atheros AP121 board support ++ * Atheros AR71xx SoC specific interrupt handling + * -+ * Copyright (C) 2011 Gabor Juhos ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.31 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include ++#include ++#include ++#include ++#include + -+#include "machtype.h" -+#include "devices.h" -+#include "dev-ar9xxx-wmac.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" ++#include ++#include + -+#define AP121_GPIO_LED_WLAN 0 -+#define AP121_GPIO_LED_USB 1 ++#include + -+#define AP121_GPIO_BTN_JUMPSTART 11 -+#define AP121_GPIO_BTN_RESET 12 ++static void ar71xx_gpio_irq_dispatch(void) ++{ ++ void __iomem *base = ar71xx_gpio_base; ++ u32 pending; + -+#define AP121_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL) ++ pending = __raw_readl(base + GPIO_REG_INT_PENDING) & ++ __raw_readl(base + GPIO_REG_INT_ENABLE); + -+#define AP121_MAC0_OFFSET 0x0000 -+#define AP121_MAC1_OFFSET 0x0006 -+#define AP121_CALDATA_OFFSET 0x1000 -+#define AP121_WMAC_MAC_OFFSET 0x1002 ++ if (pending) ++ do_IRQ(AR71XX_GPIO_IRQ_BASE + fls(pending) - 1); ++ else ++ spurious_interrupt(); ++} + -+#define AP121_MINI_GPIO_LED_WLAN 0 -+#define AP121_MINI_GPIO_BTN_JUMPSTART 12 -+#define AP121_MINI_GPIO_BTN_RESET 11 ++static void ar71xx_gpio_irq_unmask(struct irq_data *d) ++{ ++ unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE; ++ void __iomem *base = ar71xx_gpio_base; ++ u32 t; + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition ap121_parts[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "rootfs", -+ .offset = 0x010000, -+ .size = 0x130000, -+ }, -+ { -+ .name = "uImage", -+ .offset = 0x140000, -+ .size = 0x0a0000, -+ }, -+ { -+ .name = "NVRAM", -+ .offset = 0x1e0000, -+ .size = 0x010000, -+ }, -+ { -+ .name = "ART", -+ .offset = 0x1f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, -+}; -+#define ap121_nr_parts ARRAY_SIZE(ap121_parts) -+ -+static struct mtd_partition ap121_mini_parts[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x040000, -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "u-boot-env", -+ .offset = 0x040000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "rootfs", -+ .offset = 0x050000, -+ .size = 0x2b0000, -+ }, -+ { -+ .name = "uImage", -+ .offset = 0x300000, -+ .size = 0x0e0000, -+ }, -+ { -+ .name = "NVRAM", -+ .offset = 0x3e0000, -+ .size = 0x010000, -+ }, -+ { -+ .name = "ART", -+ .offset = 0x3f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, -+}; ++ t = __raw_readl(base + GPIO_REG_INT_ENABLE); ++ __raw_writel(t | (1 << irq), base + GPIO_REG_INT_ENABLE); + -+#define ap121_mini_nr_parts ARRAY_SIZE(ap121_parts) ++ /* flush write */ ++ (void) __raw_readl(base + GPIO_REG_INT_ENABLE); ++} + -+#else -+#define ap121_parts NULL -+#define ap121_nr_parts 0 -+#define ap121_mini_parts NULL -+#define ap121_mini_nr_parts 0 -+#endif /* CONFIG_MTD_PARTITIONS */ ++static void ar71xx_gpio_irq_mask(struct irq_data *d) ++{ ++ unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE; ++ void __iomem *base = ar71xx_gpio_base; ++ u32 t; + -+static struct flash_platform_data ap121_flash_data = { -+ .parts = ap121_parts, -+ .nr_parts = ap121_nr_parts, -+}; ++ t = __raw_readl(base + GPIO_REG_INT_ENABLE); ++ __raw_writel(t & ~(1 << irq), base + GPIO_REG_INT_ENABLE); + -+static struct gpio_led ap121_leds_gpio[] __initdata = { -+ { -+ .name = "ap121:green:usb", -+ .gpio = AP121_GPIO_LED_USB, -+ .active_low = 0, -+ }, -+ { -+ .name = "ap121:green:wlan", -+ .gpio = AP121_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+}; ++ /* flush write */ ++ (void) __raw_readl(base + GPIO_REG_INT_ENABLE); ++} + -+static struct gpio_keys_button ap121_gpio_keys[] __initdata = { -+ { -+ .desc = "jumpstart button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP121_GPIO_BTN_JUMPSTART, -+ .active_low = 1, -+ }, -+ { -+ .desc = "reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP121_GPIO_BTN_RESET, -+ .active_low = 1, -+ } ++static struct irq_chip ar71xx_gpio_irq_chip = { ++ .name = "AR71XX GPIO", ++ .irq_unmask = ar71xx_gpio_irq_unmask, ++ .irq_mask = ar71xx_gpio_irq_mask, ++ .irq_mask_ack = ar71xx_gpio_irq_mask, +}; + -+static struct gpio_led ap121_mini_leds_gpio[] __initdata = { -+ { -+ .name = "ap121:green:wlan", -+ .gpio = AP121_MINI_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, ++static struct irqaction ar71xx_gpio_irqaction = { ++ .handler = no_action, ++ .name = "cascade [AR71XX GPIO]", +}; + -+static struct gpio_keys_button ap121_mini_gpio_keys[] __initdata = { -+ { -+ .desc = "jumpstart button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP121_MINI_GPIO_BTN_JUMPSTART, -+ .active_low = 1, -+ }, -+ { -+ .desc = "reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP121_MINI_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; ++#define GPIO_INT_ALL 0xffff + -+static void __init ap121_common_setup(void) ++static void __init ar71xx_gpio_irq_init(void) +{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ar71xx_add_device_m25p80(&ap121_flash_data); ++ void __iomem *base = ar71xx_gpio_base; ++ int i; + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, art + AP121_MAC0_OFFSET, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, art + AP121_MAC1_OFFSET, 0); ++ __raw_writel(0, base + GPIO_REG_INT_ENABLE); ++ __raw_writel(0, base + GPIO_REG_INT_PENDING); + -+ /* WAN port */ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.phy_mask = BIT(4); ++ /* setup type of all GPIO interrupts to level sensitive */ ++ __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_TYPE); + -+ /* LAN ports */ -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; -+ ar71xx_eth1_data.has_ar7240_switch = 1; ++ /* setup polarity of all GPIO interrupts to active high */ ++ __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_POLARITY); + -+ ar71xx_add_device_mdio(0x0); -+ ar71xx_add_device_eth(1); -+ ar71xx_add_device_eth(0); ++ for (i = AR71XX_GPIO_IRQ_BASE; ++ i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++) ++ irq_set_chip_and_handler(i, &ar71xx_gpio_irq_chip, ++ handle_level_irq); + -+ ar9xxx_add_device_wmac(art + AP121_CALDATA_OFFSET, -+ art + AP121_WMAC_MAC_OFFSET); ++ setup_irq(AR71XX_MISC_IRQ_GPIO, &ar71xx_gpio_irqaction); +} + -+static void __init ap121_setup(void) ++static void ar71xx_misc_irq_dispatch(void) +{ -+ ap121_flash_data.parts = ap121_parts; -+ ap121_flash_data.nr_parts = ap121_nr_parts; ++ u32 pending; + -+ ap121_common_setup(); ++ pending = ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_STATUS) ++ & ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio), -+ ap121_leds_gpio); -+ ar71xx_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap121_gpio_keys), -+ ap121_gpio_keys); ++ if (pending & MISC_INT_UART) ++ do_IRQ(AR71XX_MISC_IRQ_UART); + -+ ar71xx_add_device_usb(); -+} ++ else if (pending & MISC_INT_DMA) ++ do_IRQ(AR71XX_MISC_IRQ_DMA); + -+static void __init ap121_mini_setup(void) -+{ -+ ap121_flash_data.parts = ap121_mini_parts; -+ ap121_flash_data.nr_parts = ap121_mini_nr_parts; ++ else if (pending & MISC_INT_PERFC) ++ do_IRQ(AR71XX_MISC_IRQ_PERFC); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap121_mini_leds_gpio), -+ ap121_mini_leds_gpio); -+ ar71xx_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap121_mini_gpio_keys), -+ ap121_mini_gpio_keys); ++ else if (pending & MISC_INT_TIMER) ++ do_IRQ(AR71XX_MISC_IRQ_TIMER); + -+ ap121_common_setup(); -+} ++ else if (pending & MISC_INT_OHCI) ++ do_IRQ(AR71XX_MISC_IRQ_OHCI); + -+MIPS_MACHINE(AR71XX_MACH_AP121, "AP121", "Atheros AP121", -+ ap121_setup); ++ else if (pending & MISC_INT_ERROR) ++ do_IRQ(AR71XX_MISC_IRQ_ERROR); + -+MIPS_MACHINE(AR71XX_MACH_AP121_MINI, "AP121-MINI", "Atheros AP121-MINI", -+ ap121_mini_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c linux-2.6.39/arch/mips/ar71xx/mach-ap81.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-ap81.c 2011-08-24 02:41:55.477989660 +0200 -@@ -0,0 +1,142 @@ -+/* -+ * Atheros AP81 board support -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * Copyright (C) 2009 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ else if (pending & MISC_INT_GPIO) ++ ar71xx_gpio_irq_dispatch(); + -+#include -+#include ++ else if (pending & MISC_INT_WDOG) ++ do_IRQ(AR71XX_MISC_IRQ_WDOG); + -+#include ++ else if (pending & MISC_INT_TIMER2) ++ do_IRQ(AR71XX_MISC_IRQ_TIMER2); + -+#include "machtype.h" -+#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ar9xxx-wmac.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-usb.h" ++ else if (pending & MISC_INT_TIMER3) ++ do_IRQ(AR71XX_MISC_IRQ_TIMER3); + -+#define AP81_GPIO_LED_STATUS 1 -+#define AP81_GPIO_LED_AOSS 3 -+#define AP81_GPIO_LED_WLAN 6 -+#define AP81_GPIO_LED_POWER 14 ++ else if (pending & MISC_INT_TIMER4) ++ do_IRQ(AR71XX_MISC_IRQ_TIMER4); + -+#define AP81_GPIO_BTN_SW4 12 -+#define AP81_GPIO_BTN_SW1 21 ++ else if (pending & MISC_INT_DDR_PERF) ++ do_IRQ(AR71XX_MISC_IRQ_DDR_PERF); + -+#define AP81_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL) ++ else if (pending & MISC_INT_ENET_LINK) ++ do_IRQ(AR71XX_MISC_IRQ_ENET_LINK); + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition ap81_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x040000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "u-boot-env", -+ .offset = 0x040000, -+ .size = 0x010000, -+ }, { -+ .name = "rootfs", -+ .offset = 0x050000, -+ .size = 0x500000, -+ }, { -+ .name = "uImage", -+ .offset = 0x550000, -+ .size = 0x100000, -+ }, { -+ .name = "ART", -+ .offset = 0x650000, -+ .size = 0x1b0000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ ++ else ++ spurious_interrupt(); ++} + -+static struct flash_platform_data ap81_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = ap81_partitions, -+ .nr_parts = ARRAY_SIZE(ap81_partitions), -+#endif -+}; ++static void ar71xx_misc_irq_unmask(struct irq_data *d) ++{ ++ unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; ++ void __iomem *base = ar71xx_reset_base; ++ u32 t; + -+static struct gpio_led ap81_leds_gpio[] __initdata = { -+ { -+ .name = "ap81:green:status", -+ .gpio = AP81_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "ap81:amber:aoss", -+ .gpio = AP81_GPIO_LED_AOSS, -+ .active_low = 1, -+ }, { -+ .name = "ap81:green:wlan", -+ .gpio = AP81_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "ap81:green:power", -+ .gpio = AP81_GPIO_LED_POWER, -+ .active_low = 1, -+ } -+}; ++ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); ++ __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); + -+static struct gpio_keys_button ap81_gpio_keys[] __initdata = { -+ { -+ .desc = "sw1", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP81_GPIO_BTN_SW1, -+ .active_low = 1, -+ }, { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP81_GPIO_BTN_SW4, -+ .active_low = 1, -+ } -+}; ++ /* flush write */ ++ (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); ++} + -+static void __init ap81_setup(void) ++static void ar71xx_misc_irq_mask(struct irq_data *d) +{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; ++ void __iomem *base = ar71xx_reset_base; ++ u32 t; + -+ ar71xx_add_device_mdio(0x0); ++ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); ++ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.has_ar8216 = 1; ++ /* flush write */ ++ (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); ++} + -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++static void ar724x_misc_irq_ack(struct irq_data *d) ++{ ++ unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; ++ void __iomem *base = ar71xx_reset_base; ++ u32 t; + -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); ++ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); ++ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS); + -+ ar71xx_add_device_usb(); ++ /* flush write */ ++ (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); ++} + -+ ar71xx_add_device_m25p80(&ap81_flash_data); ++static struct irq_chip ar71xx_misc_irq_chip = { ++ .name = "AR71XX MISC", ++ .irq_unmask = ar71xx_misc_irq_unmask, ++ .irq_mask = ar71xx_misc_irq_mask, ++}; + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio), -+ ap81_leds_gpio); ++static struct irqaction ar71xx_misc_irqaction = { ++ .handler = no_action, ++ .name = "cascade [AR71XX MISC]", ++}; + -+ ar71xx_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap81_gpio_keys), -+ ap81_gpio_keys); ++static void __init ar71xx_misc_irq_init(void) ++{ ++ void __iomem *base = ar71xx_reset_base; ++ int i; + -+ ar9xxx_add_device_wmac(eeprom, NULL); ++ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); ++ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); ++ ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ar71xx_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; ++ break; ++ default: ++ ar71xx_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; ++ break; ++ } ++ ++ for (i = AR71XX_MISC_IRQ_BASE; ++ i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++) ++ irq_set_chip_and_handler(i, &ar71xx_misc_irq_chip, ++ handle_level_irq); ++ ++ setup_irq(AR71XX_CPU_IRQ_MISC, &ar71xx_misc_irqaction); +} + -+MIPS_MACHINE(AR71XX_MACH_AP81, "AP81", "Atheros AP81", ap81_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c linux-2.6.39/arch/mips/ar71xx/mach-ap83.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-ap83.c 2011-08-24 02:41:55.477989660 +0200 -@@ -0,0 +1,267 @@ +/* -+ * Atheros AP83 board support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. ++ * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for ++ * these devices typically allocate coherent DMA memory, however the ++ * DMA controller may still have some unsynchronized data in the FIFO. ++ * Issue a flush in the handlers to ensure that the driver sees ++ * the update. + */ ++static void ar71xx_ip2_handler(void) ++{ ++ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_PCI); ++ do_IRQ(AR71XX_CPU_IRQ_IP2); ++} + -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++static void ar724x_ip2_handler(void) ++{ ++ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_PCIE); ++ do_IRQ(AR71XX_CPU_IRQ_IP2); ++} + -+#include -+#include ++static void ar913x_ip2_handler(void) ++{ ++ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_WMAC); ++ do_IRQ(AR71XX_CPU_IRQ_IP2); ++} + -+#include "machtype.h" -+#include "devices.h" -+#include "dev-ar9xxx-wmac.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-usb.h" ++static void ar933x_ip2_handler(void) ++{ ++ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_WMAC); ++ do_IRQ(AR71XX_CPU_IRQ_IP2); ++} + -+#define AP83_GPIO_LED_WLAN 6 -+#define AP83_GPIO_LED_POWER 14 -+#define AP83_GPIO_LED_JUMPSTART 15 -+#define AP83_GPIO_BTN_JUMPSTART 12 -+#define AP83_GPIO_BTN_RESET 21 ++static void ar934x_ip2_handler(void) ++{ ++ ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_PCIE); ++ do_IRQ(AR71XX_CPU_IRQ_IP2); ++} + -+#define AP83_050_GPIO_VSC7385_CS 1 -+#define AP83_050_GPIO_VSC7385_MISO 3 -+#define AP83_050_GPIO_VSC7385_MOSI 16 -+#define AP83_050_GPIO_VSC7385_SCK 17 ++static void ar71xx_ip3_handler(void) ++{ ++ ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_USB); ++ do_IRQ(AR71XX_CPU_IRQ_USB); ++} + -+#define AP83_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AP83_KEYS_DEBOUNCE_INTERVAL (3 * AP83_KEYS_POLL_INTERVAL) ++static void ar724x_ip3_handler(void) ++{ ++ ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_USB); ++ do_IRQ(AR71XX_CPU_IRQ_USB); ++} + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition ap83_flash_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x040000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "u-boot-env", -+ .offset = 0x040000, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "kernel", -+ .offset = 0x060000, -+ .size = 0x140000, -+ }, { -+ .name = "rootfs", -+ .offset = 0x1a0000, -+ .size = 0x650000, -+ }, { -+ .name = "art", -+ .offset = 0x7f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x060000, -+ .size = 0x790000, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ ++static void ar913x_ip3_handler(void) ++{ ++ ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_USB); ++ do_IRQ(AR71XX_CPU_IRQ_USB); ++} + -+static struct ar91xx_flash_platform_data ap83_flash_data = { -+ .width = 2, -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = ap83_flash_partitions, -+ .nr_parts = ARRAY_SIZE(ap83_flash_partitions), -+#endif -+}; ++static void ar933x_ip3_handler(void) ++{ ++ ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_USB); ++ do_IRQ(AR71XX_CPU_IRQ_USB); ++} + -+static struct resource ap83_flash_resources[] = { -+ [0] = { -+ .start = AR71XX_SPI_BASE, -+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; ++static void ar934x_ip3_handler(void) ++{ ++ do_IRQ(AR71XX_CPU_IRQ_USB); ++} + -+static struct platform_device ap83_flash_device = { -+ .name = "ar91xx-flash", -+ .id = -1, -+ .resource = ap83_flash_resources, -+ .num_resources = ARRAY_SIZE(ap83_flash_resources), -+ .dev = { -+ .platform_data = &ap83_flash_data, -+ } -+}; ++static void (*ip2_handler)(void); ++static void (*ip3_handler)(void); + -+static struct gpio_led ap83_leds_gpio[] __initdata = { -+ { -+ .name = "ap83:green:jumpstart", -+ .gpio = AP83_GPIO_LED_JUMPSTART, -+ .active_low = 0, -+ }, { -+ .name = "ap83:green:power", -+ .gpio = AP83_GPIO_LED_POWER, -+ .active_low = 0, -+ }, { -+ .name = "ap83:green:wlan", -+ .gpio = AP83_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+}; ++asmlinkage void plat_irq_dispatch(void) ++{ ++ unsigned long pending; + -+static struct gpio_keys_button ap83_gpio_keys[] __initdata = { -+ { -+ .desc = "soft_reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP83_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "jumpstart", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP83_GPIO_BTN_JUMPSTART, -+ .active_low = 1, -+ } -+}; ++ pending = read_c0_status() & read_c0_cause() & ST0_IM; + -+static struct resource ap83_040_spi_resources[] = { -+ [0] = { -+ .start = AR71XX_SPI_BASE, -+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; ++ if (pending & STATUSF_IP7) ++ do_IRQ(AR71XX_CPU_IRQ_TIMER); + -+static struct platform_device ap83_040_spi_device = { -+ .name = "ap83-spi", -+ .id = 0, -+ .resource = ap83_040_spi_resources, -+ .num_resources = ARRAY_SIZE(ap83_040_spi_resources), -+}; ++ else if (pending & STATUSF_IP2) ++ ip2_handler(); + -+static struct spi_gpio_platform_data ap83_050_spi_data = { -+ .miso = AP83_050_GPIO_VSC7385_MISO, -+ .mosi = AP83_050_GPIO_VSC7385_MOSI, -+ .sck = AP83_050_GPIO_VSC7385_SCK, -+ .num_chipselect = 1, -+}; ++ else if (pending & STATUSF_IP4) ++ do_IRQ(AR71XX_CPU_IRQ_GE0); + -+static struct platform_device ap83_050_spi_device = { -+ .name = "spi_gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &ap83_050_spi_data, -+ } -+}; ++ else if (pending & STATUSF_IP5) ++ do_IRQ(AR71XX_CPU_IRQ_GE1); + -+static void ap83_vsc7385_reset(void) -+{ -+ ar71xx_device_stop(RESET_MODULE_GE1_PHY); -+ udelay(10); -+ ar71xx_device_start(RESET_MODULE_GE1_PHY); -+ mdelay(50); -+} ++ else if (pending & STATUSF_IP3) ++ ip3_handler(); + -+static struct vsc7385_platform_data ap83_vsc7385_data = { -+ .reset = ap83_vsc7385_reset, -+ .ucode_name = "vsc7385_ucode_ap83.bin", -+ .mac_cfg = { -+ .tx_ipg = 6, -+ .bit2 = 0, -+ .clk_sel = 3, -+ }, -+}; ++ else if (pending & STATUSF_IP6) ++ ar71xx_misc_irq_dispatch(); + -+static struct spi_board_info ap83_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "spi-vsc7385", -+ .platform_data = &ap83_vsc7385_data, -+ .controller_data = (void *) AP83_050_GPIO_VSC7385_CS, -+ } -+}; ++ spurious_interrupt(); ++} + -+static void __init ap83_generic_setup(void) ++void __init arch_init_irq(void) +{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ ip2_handler = ar71xx_ip2_handler; ++ ip3_handler = ar71xx_ip3_handler; ++ break; + -+ ar71xx_add_device_mdio(0xfffffffe); ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ ip2_handler = ar724x_ip2_handler; ++ ip3_handler = ar724x_ip3_handler; ++ break; + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.phy_mask = 0x1; ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ ip2_handler = ar913x_ip2_handler; ++ ip3_handler = ar913x_ip3_handler; ++ break; + -+ ar71xx_add_device_eth(0); ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ ip2_handler = ar933x_ip2_handler; ++ ip3_handler = ar933x_ip3_handler; ++ break; + -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ip2_handler = ar934x_ip2_handler; ++ ip3_handler = ar934x_ip3_handler; ++ break; + -+ ar71xx_eth1_pll_data.pll_1000 = 0x1f000000; ++ default: ++ BUG(); ++ } + -+ ar71xx_add_device_eth(1); ++ mips_cpu_irq_init(); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio), -+ ap83_leds_gpio); ++ ar71xx_misc_irq_init(); + -+ ar71xx_register_gpio_keys_polled(-1, AP83_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap83_gpio_keys), -+ ap83_gpio_keys); ++ cp0_perfcount_irq = AR71XX_MISC_IRQ_PERFC; + -+ ar71xx_add_device_usb(); ++ ar71xx_gpio_irq_init(); ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap121.c linux-2.6.39/arch/mips/ar71xx/mach-ap121.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap121.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ap121.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,245 @@ ++/* ++ * Atheros AP121 board support ++ * ++ * Copyright (C) 2011 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ ar9xxx_add_device_wmac(eeprom, NULL); ++#include ++#include ++#include + -+ platform_device_register(&ap83_flash_device); ++#include "machtype.h" ++#include "devices.h" ++#include "dev-ar9xxx-wmac.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-m25p80.h" ++#include "dev-usb.h" + -+ spi_register_board_info(ap83_spi_info, ARRAY_SIZE(ap83_spi_info)); -+} ++#define AP121_GPIO_LED_WLAN 0 ++#define AP121_GPIO_LED_USB 1 + -+static void __init ap83_040_setup(void) -+{ -+ ap83_flash_data.is_shared = 1; -+ ap83_generic_setup(); -+ platform_device_register(&ap83_040_spi_device); -+} ++#define AP121_GPIO_BTN_JUMPSTART 11 ++#define AP121_GPIO_BTN_RESET 12 + -+static void __init ap83_050_setup(void) -+{ -+ ap83_generic_setup(); -+ platform_device_register(&ap83_050_spi_device); -+} -+ -+static void __init ap83_setup(void) -+{ -+ u8 *board_id = (u8 *) KSEG1ADDR(0x1fff1244); -+ unsigned int board_version; -+ -+ board_version = (unsigned int)(board_id[0] - '0'); -+ board_version += ((unsigned int)(board_id[1] - '0')) * 10; -+ -+ switch (board_version) { -+ case 40: -+ ap83_040_setup(); -+ break; -+ case 50: -+ ap83_050_setup(); -+ break; -+ default: -+ printk(KERN_WARNING "AP83-%03u board is not yet supported\n", -+ board_version); -+ } -+} -+ -+MIPS_MACHINE(AR71XX_MACH_AP83, "AP83", "Atheros AP83", ap83_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap96.c linux-2.6.39/arch/mips/ar71xx/mach-ap96.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap96.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-ap96.c 2011-08-24 02:41:55.477989660 +0200 -@@ -0,0 +1,180 @@ -+/* -+ * Atheros AP96 board support -+ * -+ * Copyright (C) 2009 Marco Porsch -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * Copyright (C) 2010 Atheros Communications -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "machtype.h" -+#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ap94-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+ -+#define AP96_GPIO_LED_12_GREEN 0 -+#define AP96_GPIO_LED_3_GREEN 1 -+#define AP96_GPIO_LED_2_GREEN 2 -+#define AP96_GPIO_LED_WPS_GREEN 4 -+#define AP96_GPIO_LED_5_GREEN 5 -+#define AP96_GPIO_LED_4_ORANGE 6 -+ -+/* Reset button - next to the power connector */ -+#define AP96_GPIO_BTN_RESET 3 -+/* WPS button - next to a led on right */ -+#define AP96_GPIO_BTN_WPS 8 ++#define AP121_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL) + -+#define AP96_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AP96_KEYS_DEBOUNCE_INTERVAL (3 * AP96_KEYS_POLL_INTERVAL) ++#define AP121_MAC0_OFFSET 0x0000 ++#define AP121_MAC1_OFFSET 0x0006 ++#define AP121_CALDATA_OFFSET 0x1000 ++#define AP121_WMAC_MAC_OFFSET 0x1002 + -+#define AP96_WMAC0_MAC_OFFSET 0x120c -+#define AP96_WMAC1_MAC_OFFSET 0x520c -+#define AP96_CALDATA0_OFFSET 0x1000 -+#define AP96_CALDATA1_OFFSET 0x5000 ++#define AP121_MINI_GPIO_LED_WLAN 0 ++#define AP121_MINI_GPIO_BTN_JUMPSTART 12 ++#define AP121_MINI_GPIO_BTN_RESET 11 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition ap96_partitions[] = { ++static struct mtd_partition ap121_parts[] = { + { -+ .name = "uboot", ++ .name = "u-boot", + .offset = 0, -+ .size = 0x030000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "env", -+ .offset = 0x030000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ }, { ++ }, ++ { + .name = "rootfs", ++ .offset = 0x010000, ++ .size = 0x130000, ++ }, ++ { ++ .name = "uImage", ++ .offset = 0x140000, ++ .size = 0x0a0000, ++ }, ++ { ++ .name = "NVRAM", ++ .offset = 0x1e0000, ++ .size = 0x010000, ++ }, ++ { ++ .name = "ART", ++ .offset = 0x1f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, ++}; ++#define ap121_nr_parts ARRAY_SIZE(ap121_parts) ++ ++static struct mtd_partition ap121_mini_parts[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, ++ { ++ .name = "u-boot-env", + .offset = 0x040000, -+ .size = 0x600000, -+ }, { ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, ++ { ++ .name = "rootfs", ++ .offset = 0x050000, ++ .size = 0x2b0000, ++ }, ++ { + .name = "uImage", -+ .offset = 0x640000, -+ .size = 0x1b0000, -+ }, { -+ .name = "caldata", -+ .offset = 0x7f0000, ++ .offset = 0x300000, ++ .size = 0x0e0000, ++ }, ++ { ++ .name = "NVRAM", ++ .offset = 0x3e0000, ++ .size = 0x010000, ++ }, ++ { ++ .name = "ART", ++ .offset = 0x3f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ } ++ }, +}; ++ ++#define ap121_mini_nr_parts ARRAY_SIZE(ap121_parts) ++ ++#else ++#define ap121_parts NULL ++#define ap121_nr_parts 0 ++#define ap121_mini_parts NULL ++#define ap121_mini_nr_parts 0 +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data ap96_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = ap96_partitions, -+ .nr_parts = ARRAY_SIZE(ap96_partitions), -+#endif ++static struct flash_platform_data ap121_flash_data = { ++ .parts = ap121_parts, ++ .nr_parts = ap121_nr_parts, +}; + -+/* -+ * AP96 has 12 unlabeled leds in the front; these are numbered from 1 to 12 -+ * below (from left to right on the board). Led 1 seems to be on whenever the -+ * board is powered. Led 11 shows LAN link activity actity. Led 3 is orange; -+ * others are green. -+ * -+ * In addition, there is one led next to a button on the right side for WPS. -+ */ -+static struct gpio_led ap96_leds_gpio[] __initdata = { ++static struct gpio_led ap121_leds_gpio[] __initdata = { + { -+ .name = "ap96:green:led2", -+ .gpio = AP96_GPIO_LED_2_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "ap96:green:led3", -+ .gpio = AP96_GPIO_LED_3_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "ap96:orange:led4", -+ .gpio = AP96_GPIO_LED_4_ORANGE, -+ .active_low = 1, -+ }, { -+ .name = "ap96:green:led5", -+ .gpio = AP96_GPIO_LED_5_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "ap96:green:led12", -+ .gpio = AP96_GPIO_LED_12_GREEN, -+ .active_low = 1, -+ }, { /* next to a button on right */ -+ .name = "ap96:green:wps", -+ .gpio = AP96_GPIO_LED_WPS_GREEN, -+ .active_low = 1, -+ } ++ .name = "ap121:green:usb", ++ .gpio = AP121_GPIO_LED_USB, ++ .active_low = 0, ++ }, ++ { ++ .name = "ap121:green:wlan", ++ .gpio = AP121_GPIO_LED_WLAN, ++ .active_low = 0, ++ }, +}; + -+static struct gpio_keys_button ap96_gpio_keys[] __initdata = { ++static struct gpio_keys_button ap121_gpio_keys[] __initdata = { + { -+ .desc = "reset", ++ .desc = "jumpstart button", + .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP96_GPIO_BTN_RESET, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP121_GPIO_BTN_JUMPSTART, + .active_low = 1, -+ }, { -+ .desc = "wps", ++ }, ++ { ++ .desc = "reset button", + .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP96_GPIO_BTN_WPS, ++ .code = KEY_RESTART, ++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP121_GPIO_BTN_RESET, + .active_low = 1, + } +}; + -+#define AP96_WAN_PHYMASK 0x10 -+#define AP96_LAN_PHYMASK 0x0f -+ -+static void __init ap96_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ar71xx_add_device_mdio(~(AP96_WAN_PHYMASK | AP96_LAN_PHYMASK)); ++static struct gpio_led ap121_mini_leds_gpio[] __initdata = { ++ { ++ .name = "ap121:green:wlan", ++ .gpio = AP121_MINI_GPIO_LED_WLAN, ++ .active_low = 0, ++ }, ++}; + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, art, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.phy_mask = AP96_LAN_PHYMASK; -+ ar71xx_eth0_data.speed = SPEED_1000; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ -+ ar71xx_add_device_eth(0); -+ -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, art, 1); -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = AP96_WAN_PHYMASK; -+ -+ ar71xx_eth1_pll_data.pll_1000 = 0x1f000000; -+ -+ ar71xx_add_device_eth(1); -+ -+ ar71xx_add_device_usb(); -+ -+ ar71xx_add_device_m25p80(&ap96_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap96_leds_gpio), -+ ap96_leds_gpio); -+ -+ ar71xx_register_gpio_keys_polled(-1, AP96_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap96_gpio_keys), -+ ap96_gpio_keys); -+ -+ ap94_pci_init(art + AP96_CALDATA0_OFFSET, -+ art + AP96_WMAC0_MAC_OFFSET, -+ art + AP96_CALDATA1_OFFSET, -+ art + AP96_WMAC1_MAC_OFFSET); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_AP96, "AP96", "Atheros AP96", ap96_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c 2011-08-24 02:41:55.487989871 +0200 -@@ -0,0 +1,102 @@ -+/* -+ * AzureWave AW-NR580 board support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "machtype.h" -+#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-gpio-buttons.h" -+#include "dev-pb42-pci.h" -+#include "dev-leds-gpio.h" -+ -+#define AW_NR580_GPIO_LED_READY_RED 0 -+#define AW_NR580_GPIO_LED_WLAN 1 -+#define AW_NR580_GPIO_LED_READY_GREEN 2 -+#define AW_NR580_GPIO_LED_WPS_GREEN 4 -+#define AW_NR580_GPIO_LED_WPS_AMBER 5 -+ -+#define AW_NR580_GPIO_BTN_WPS 3 -+#define AW_NR580_GPIO_BTN_RESET 11 -+ -+#define AW_NR580_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AW_NR580_KEYS_DEBOUNCE_INTERVAL (3 * AW_NR580_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led aw_nr580_leds_gpio[] __initdata = { -+ { -+ .name = "aw-nr580:red:ready", -+ .gpio = AW_NR580_GPIO_LED_READY_RED, -+ .active_low = 0, -+ }, { -+ .name = "aw-nr580:green:ready", -+ .gpio = AW_NR580_GPIO_LED_READY_GREEN, -+ .active_low = 0, -+ }, { -+ .name = "aw-nr580:green:wps", -+ .gpio = AW_NR580_GPIO_LED_WPS_GREEN, -+ .active_low = 0, -+ }, { -+ .name = "aw-nr580:amber:wps", -+ .gpio = AW_NR580_GPIO_LED_WPS_AMBER, -+ .active_low = 0, -+ }, { -+ .name = "aw-nr580:green:wlan", -+ .gpio = AW_NR580_GPIO_LED_WLAN, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button aw_nr580_gpio_keys[] __initdata = { ++static struct gpio_keys_button ap121_mini_gpio_keys[] __initdata = { + { -+ .desc = "reset", ++ .desc = "jumpstart button", + .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AW_NR580_GPIO_BTN_RESET, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP121_MINI_GPIO_BTN_JUMPSTART, + .active_low = 1, -+ }, { -+ .desc = "wps", ++ }, ++ { ++ .desc = "reset button", + .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AW_NR580_GPIO_BTN_WPS, ++ .code = KEY_RESTART, ++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP121_MINI_GPIO_BTN_RESET, + .active_low = 1, + } +}; + -+static void __init aw_nr580_setup(void) ++static void __init ap121_common_setup(void) +{ -+ ar71xx_add_device_mdio(0x0); ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_add_device_m25p80(&ap121_flash_data); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, art + AP121_MAC0_OFFSET, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, art + AP121_MAC1_OFFSET, 0); ++ ++ /* WAN port */ ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = BIT(4); ++ ++ /* LAN ports */ ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_eth1_data.has_ar7240_switch = 1; + ++ ar71xx_add_device_mdio(0x0); ++ ar71xx_add_device_eth(1); + ar71xx_add_device_eth(0); + -+ pb42_pci_init(); ++ ar9xxx_add_device_wmac(art + AP121_CALDATA_OFFSET, ++ art + AP121_WMAC_MAC_OFFSET); ++} + -+ ar71xx_add_device_m25p80(NULL); ++static void __init ap121_setup(void) ++{ ++ ap121_flash_data.parts = ap121_parts; ++ ap121_flash_data.nr_parts = ap121_nr_parts; + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio), -+ aw_nr580_leds_gpio); ++ ap121_common_setup(); + -+ ar71xx_register_gpio_keys_polled(-1, AW_NR580_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(aw_nr580_gpio_keys), -+ aw_nr580_gpio_keys); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio), ++ ap121_leds_gpio); ++ ar71xx_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap121_gpio_keys), ++ ap121_gpio_keys); ++ ++ ar71xx_add_device_usb(); +} + -+MIPS_MACHINE(AR71XX_MACH_AW_NR580, "AW-NR580", "AzureWave AW-NR580", -+ aw_nr580_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-db120.c linux-2.6.39/arch/mips/ar71xx/mach-db120.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-db120.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-db120.c 2011-08-24 02:41:55.487989871 +0200 -@@ -0,0 +1,134 @@ ++static void __init ap121_mini_setup(void) ++{ ++ ap121_flash_data.parts = ap121_mini_parts; ++ ap121_flash_data.nr_parts = ap121_mini_nr_parts; ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap121_mini_leds_gpio), ++ ap121_mini_leds_gpio); ++ ar71xx_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap121_mini_gpio_keys), ++ ap121_mini_gpio_keys); ++ ++ ap121_common_setup(); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_AP121, "AP121", "Atheros AP121", ++ ap121_setup); ++ ++MIPS_MACHINE(AR71XX_MACH_AP121_MINI, "AP121-MINI", "Atheros AP121-MINI", ++ ap121_mini_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c linux-2.6.39/arch/mips/ar71xx/mach-ap81.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap81.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ap81.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,142 @@ +/* -+ * Atheros DB120 board (WASP SoC) support ++ * Atheros AP81 board support + * -+ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2009 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -4293,28 +3728,24 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-db120.c linux-2.6.39/arch/mips +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-usb.h" -+#include "dev-ar9xxx-wmac.h" -+#include "dev-db120-pci.h" -+ -+#define DB120_GPIO_LED_USB 11 -+#define DB120_GPIO_LED_WLAN_5G 12 -+#define DB120_GPIO_LED_WLAN_2G 13 -+#define DB120_GPIO_LED_STATUS 14 -+#define DB120_GPIO_LED_WPS 15 + -+#define DB120_GPIO_BTN_SW1 16 ++#define AP81_GPIO_LED_STATUS 1 ++#define AP81_GPIO_LED_AOSS 3 ++#define AP81_GPIO_LED_WLAN 6 ++#define AP81_GPIO_LED_POWER 14 + -+#define DB120_CALDATA_OFFSET 0x1000 -+#define DB120_WMAC_MAC_OFFSET 0x1002 ++#define AP81_GPIO_BTN_SW4 12 ++#define AP81_GPIO_BTN_SW1 21 + -+#define DB120_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL) ++#define AP81_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL) + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition db120_partitions[] = { ++static struct mtd_partition ap81_partitions[] = { + { + .name = "u-boot", + .offset = 0, @@ -4327,1017 +3758,970 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-db120.c linux-2.6.39/arch/mips + }, { + .name = "rootfs", + .offset = 0x050000, -+ .size = 0x630000, ++ .size = 0x500000, + }, { + .name = "uImage", -+ .offset = 0x680000, -+ .size = 0x160000, -+ }, { -+ .name = "NVRAM", -+ .offset = 0x7E0000, -+ .size = 0x010000, ++ .offset = 0x550000, ++ .size = 0x100000, + }, { + .name = "ART", -+ .offset = 0x7F0000, -+ .size = 0x010000, ++ .offset = 0x650000, ++ .size = 0x1b0000, + .mask_flags = MTD_WRITEABLE, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data db120_flash_data = { ++static struct flash_platform_data ap81_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = db120_partitions, -+ .nr_parts = ARRAY_SIZE(db120_partitions), ++ .parts = ap81_partitions, ++ .nr_parts = ARRAY_SIZE(ap81_partitions), +#endif +}; + -+static struct gpio_led db120_leds_gpio[] __initdata = { ++static struct gpio_led ap81_leds_gpio[] __initdata = { + { -+ .name = "db120:green:status", -+ .gpio = DB120_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "db120:green:wps", -+ .gpio = DB120_GPIO_LED_WPS, ++ .name = "ap81:green:status", ++ .gpio = AP81_GPIO_LED_STATUS, + .active_low = 1, + }, { -+ .name = "db120:green:wlan-5g", -+ .gpio = DB120_GPIO_LED_WLAN_5G, ++ .name = "ap81:amber:aoss", ++ .gpio = AP81_GPIO_LED_AOSS, + .active_low = 1, + }, { -+ .name = "db120:green:wlan-2g", -+ .gpio = DB120_GPIO_LED_WLAN_2G, ++ .name = "ap81:green:wlan", ++ .gpio = AP81_GPIO_LED_WLAN, + .active_low = 1, + }, { -+ .name = "db120:green:usb", -+ .gpio = DB120_GPIO_LED_USB, ++ .name = "ap81:green:power", ++ .gpio = AP81_GPIO_LED_POWER, + .active_low = 1, + } +}; + -+static struct gpio_keys_button db120_gpio_keys[] __initdata = { ++static struct gpio_keys_button ap81_gpio_keys[] __initdata = { + { + .desc = "sw1", + .type = EV_KEY, + .code = BTN_0, -+ .debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DB120_GPIO_BTN_SW1, ++ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP81_GPIO_BTN_SW1, ++ .active_low = 1, ++ }, { ++ .desc = "sw4", ++ .type = EV_KEY, ++ .code = BTN_1, ++ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP81_GPIO_BTN_SW4, + .active_low = 1, + } +}; + -+static void __init db120_setup(void) ++static void __init ap81_setup(void) +{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_add_device_usb(); ++ ar71xx_add_device_mdio(0x0); + -+ ar71xx_add_device_m25p80(&db120_flash_data); ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.has_ar8216 = 1; + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio), -+ db120_leds_gpio); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = 0x10; + -+ ar71xx_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(db120_gpio_keys), -+ db120_gpio_keys); ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ ar9xxx_add_device_wmac(art + DB120_CALDATA_OFFSET, -+ art + DB120_WMAC_MAC_OFFSET); ++ ar71xx_add_device_usb(); + -+ db120_pci_init(); ++ ar71xx_add_device_m25p80(&ap81_flash_data); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio), ++ ap81_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap81_gpio_keys), ++ ap81_gpio_keys); ++ ++ ar9xxx_add_device_wmac(eeprom, NULL); +} + -+MIPS_MACHINE(AR71XX_MACH_DB120, "DB120", "Atheros DB120", db120_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c 2011-08-24 02:41:55.487989871 +0200 -@@ -0,0 +1,159 @@ ++MIPS_MACHINE(AR71XX_MACH_AP81, "AP81", "Atheros AP81", ap81_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c linux-2.6.39/arch/mips/ar71xx/mach-ap83.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap83.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ap83.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,267 @@ +/* -+ * D-Link DIR-600 rev. A1 board support ++ * Atheros AP83 board support + * -+ * Copyright (C) 2010 Gabor Juhos ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include ++#include +#include +#include ++#include ++#include ++#include + +#include ++#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ap91-pci.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "nvram.h" -+ -+#define DIR_600_A1_GPIO_LED_WPS 0 -+#define DIR_600_A1_GPIO_LED_POWER_AMBER 1 -+#define DIR_600_A1_GPIO_LED_POWER_GREEN 6 ++#include "dev-usb.h" + -+#define DIR_600_A1_GPIO_BTN_RESET 8 -+#define DIR_600_A1_GPIO_BTN_WPS 12 ++#define AP83_GPIO_LED_WLAN 6 ++#define AP83_GPIO_LED_POWER 14 ++#define AP83_GPIO_LED_JUMPSTART 15 ++#define AP83_GPIO_BTN_JUMPSTART 12 ++#define AP83_GPIO_BTN_RESET 21 + -+#define DIR_600_A1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DIR_600_A1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_600_A1_KEYS_POLL_INTERVAL) ++#define AP83_050_GPIO_VSC7385_CS 1 ++#define AP83_050_GPIO_VSC7385_MISO 3 ++#define AP83_050_GPIO_VSC7385_MOSI 16 ++#define AP83_050_GPIO_VSC7385_SCK 17 + -+#define DIR_600_A1_NVRAM_ADDR 0x1f030000 -+#define DIR_600_A1_NVRAM_SIZE 0x10000 ++#define AP83_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define AP83_KEYS_DEBOUNCE_INTERVAL (3 * AP83_KEYS_POLL_INTERVAL) + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition dir_600_a1_partitions[] = { ++static struct mtd_partition ap83_flash_partitions[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x030000, ++ .size = 0x040000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "nvram", -+ .offset = 0x030000, -+ .size = 0x010000, ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", -+ .offset = 0x040000, -+ .size = 0x0e0000, ++ .offset = 0x060000, ++ .size = 0x140000, + }, { + .name = "rootfs", -+ .offset = 0x120000, -+ .size = 0x2c0000, -+ }, { -+ .name = "mac", -+ .offset = 0x3e0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .offset = 0x1a0000, ++ .size = 0x650000, + }, { + .name = "art", -+ .offset = 0x3f0000, ++ .offset = 0x7f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", -+ .offset = 0x040000, -+ .size = 0x3a0000, ++ .offset = 0x060000, ++ .size = 0x790000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data dir_600_a1_flash_data = { ++static struct ar91xx_flash_platform_data ap83_flash_data = { ++ .width = 2, +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = dir_600_a1_partitions, -+ .nr_parts = ARRAY_SIZE(dir_600_a1_partitions), ++ .parts = ap83_flash_partitions, ++ .nr_parts = ARRAY_SIZE(ap83_flash_partitions), +#endif +}; + -+static struct gpio_led dir_600_a1_leds_gpio[] __initdata = { ++static struct resource ap83_flash_resources[] = { ++ [0] = { ++ .start = AR71XX_SPI_BASE, ++ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static struct platform_device ap83_flash_device = { ++ .name = "ar91xx-flash", ++ .id = -1, ++ .resource = ap83_flash_resources, ++ .num_resources = ARRAY_SIZE(ap83_flash_resources), ++ .dev = { ++ .platform_data = &ap83_flash_data, ++ } ++}; ++ ++static struct gpio_led ap83_leds_gpio[] __initdata = { + { -+ .name = "dir-600-a1:green:power", -+ .gpio = DIR_600_A1_GPIO_LED_POWER_GREEN, ++ .name = "ap83:green:jumpstart", ++ .gpio = AP83_GPIO_LED_JUMPSTART, ++ .active_low = 0, + }, { -+ .name = "dir-600-a1:amber:power", -+ .gpio = DIR_600_A1_GPIO_LED_POWER_AMBER, ++ .name = "ap83:green:power", ++ .gpio = AP83_GPIO_LED_POWER, ++ .active_low = 0, + }, { -+ .name = "dir-600-a1:blue:wps", -+ .gpio = DIR_600_A1_GPIO_LED_WPS, -+ .active_low = 1, -+ } ++ .name = "ap83:green:wlan", ++ .gpio = AP83_GPIO_LED_WLAN, ++ .active_low = 0, ++ }, +}; + -+static struct gpio_keys_button dir_600_a1_gpio_keys[] __initdata = { ++static struct gpio_keys_button ap83_gpio_keys[] __initdata = { + { -+ .desc = "reset", ++ .desc = "soft_reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_600_A1_GPIO_BTN_RESET, ++ .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP83_GPIO_BTN_RESET, + .active_low = 1, + }, { -+ .desc = "wps", ++ .desc = "jumpstart", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_600_A1_GPIO_BTN_WPS, ++ .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP83_GPIO_BTN_JUMPSTART, + .active_low = 1, + } +}; + -+static void __init dir_600_a1_setup(void) -+{ -+ const char *nvram = (char *) KSEG1ADDR(DIR_600_A1_NVRAM_ADDR); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac_buff[6]; -+ u8 *mac = NULL; -+ -+ if (nvram_parse_mac_addr(nvram, DIR_600_A1_NVRAM_SIZE, -+ "lan_mac=", mac_buff) == 0) { -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac_buff, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac_buff, 1); -+ mac = mac_buff; -+ } -+ -+ ar71xx_add_device_m25p80(&dir_600_a1_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_600_a1_leds_gpio), -+ dir_600_a1_leds_gpio); -+ -+ ar71xx_register_gpio_keys_polled(-1, DIR_600_A1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dir_600_a1_gpio_keys), -+ dir_600_a1_gpio_keys); -+ -+ ar71xx_eth1_data.has_ar7240_switch = 1; -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++static struct resource ap83_040_spi_resources[] = { ++ [0] = { ++ .start = AR71XX_SPI_BASE, ++ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; + -+ /* WAN port */ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.phy_mask = BIT(4); ++static struct platform_device ap83_040_spi_device = { ++ .name = "ap83-spi", ++ .id = 0, ++ .resource = ap83_040_spi_resources, ++ .num_resources = ARRAY_SIZE(ap83_040_spi_resources), ++}; + -+ /* LAN ports */ -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++static struct spi_gpio_platform_data ap83_050_spi_data = { ++ .miso = AP83_050_GPIO_VSC7385_MISO, ++ .mosi = AP83_050_GPIO_VSC7385_MOSI, ++ .sck = AP83_050_GPIO_VSC7385_SCK, ++ .num_chipselect = 1, ++}; + -+ ar71xx_add_device_mdio(0x0); -+ ar71xx_add_device_eth(1); -+ ar71xx_add_device_eth(0); ++static struct platform_device ap83_050_spi_device = { ++ .name = "spi_gpio", ++ .id = 0, ++ .dev = { ++ .platform_data = &ap83_050_spi_data, ++ } ++}; + -+ ap91_pci_init(ee, mac); ++static void ap83_vsc7385_reset(void) ++{ ++ ar71xx_device_stop(RESET_MODULE_GE1_PHY); ++ udelay(10); ++ ar71xx_device_start(RESET_MODULE_GE1_PHY); ++ mdelay(50); +} + -+MIPS_MACHINE(AR71XX_MACH_DIR_600_A1, "DIR-600-A1", "D-Link DIR-600 rev. A1", -+ dir_600_a1_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c 2011-08-24 02:41:55.487989871 +0200 -@@ -0,0 +1,175 @@ ++static struct vsc7385_platform_data ap83_vsc7385_data = { ++ .reset = ap83_vsc7385_reset, ++ .ucode_name = "vsc7385_ucode_ap83.bin", ++ .mac_cfg = { ++ .tx_ipg = 6, ++ .bit2 = 0, ++ .clk_sel = 3, ++ }, ++}; ++ ++static struct spi_board_info ap83_spi_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "spi-vsc7385", ++ .platform_data = &ap83_vsc7385_data, ++ .controller_data = (void *) AP83_050_GPIO_VSC7385_CS, ++ } ++}; ++ ++static void __init ap83_generic_setup(void) ++{ ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ ++ ar71xx_add_device_mdio(0xfffffffe); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = 0x1; ++ ++ ar71xx_add_device_eth(0); ++ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ++ ar71xx_eth1_pll_data.pll_1000 = 0x1f000000; ++ ++ ar71xx_add_device_eth(1); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio), ++ ap83_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, AP83_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap83_gpio_keys), ++ ap83_gpio_keys); ++ ++ ar71xx_add_device_usb(); ++ ++ ar9xxx_add_device_wmac(eeprom, NULL); ++ ++ platform_device_register(&ap83_flash_device); ++ ++ spi_register_board_info(ap83_spi_info, ARRAY_SIZE(ap83_spi_info)); ++} ++ ++static void __init ap83_040_setup(void) ++{ ++ ap83_flash_data.is_shared = 1; ++ ap83_generic_setup(); ++ platform_device_register(&ap83_040_spi_device); ++} ++ ++static void __init ap83_050_setup(void) ++{ ++ ap83_generic_setup(); ++ platform_device_register(&ap83_050_spi_device); ++} ++ ++static void __init ap83_setup(void) ++{ ++ u8 *board_id = (u8 *) KSEG1ADDR(0x1fff1244); ++ unsigned int board_version; ++ ++ board_version = (unsigned int)(board_id[0] - '0'); ++ board_version += ((unsigned int)(board_id[1] - '0')) * 10; ++ ++ switch (board_version) { ++ case 40: ++ ap83_040_setup(); ++ break; ++ case 50: ++ ap83_050_setup(); ++ break; ++ default: ++ printk(KERN_WARNING "AP83-%03u board is not yet supported\n", ++ board_version); ++ } ++} ++ ++MIPS_MACHINE(AR71XX_MACH_AP83, "AP83", "Atheros AP83", ap83_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ap96.c linux-2.6.39/arch/mips/ar71xx/mach-ap96.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ap96.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ap96.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,180 @@ +/* -+ * D-Link DIR-615 rev C1 board support ++ * Atheros AP96 board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009 Marco Porsch ++ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2010 Atheros Communications + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include +#include +#include ++#include + +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ar9xxx-wmac.h" ++#include "dev-ap94-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "nvram.h" -+ -+#define DIR_615C1_GPIO_LED_ORANGE_STATUS 1 /* ORANGE:STATUS:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_BLUE_WPS 3 /* BLUE:WPS */ -+#define DIR_615C1_GPIO_LED_GREEN_WAN 4 /* GREEN:WAN:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_GREEN_WANCPU 5 /* GREEN:WAN:CPU:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_GREEN_WLAN 6 /* GREEN:WLAN */ -+#define DIR_615C1_GPIO_LED_GREEN_STATUS 14 /* GREEN:STATUS:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_ORANGE_WAN 15 /* ORANGE:WAN:TRICOLOR */ ++#include "dev-usb.h" + -+/* buttons may need refinement */ ++#define AP96_GPIO_LED_12_GREEN 0 ++#define AP96_GPIO_LED_3_GREEN 1 ++#define AP96_GPIO_LED_2_GREEN 2 ++#define AP96_GPIO_LED_WPS_GREEN 4 ++#define AP96_GPIO_LED_5_GREEN 5 ++#define AP96_GPIO_LED_4_ORANGE 6 + -+#define DIR_615C1_GPIO_BTN_WPS 12 -+#define DIR_615C1_GPIO_BTN_RESET 21 ++/* Reset button - next to the power connector */ ++#define AP96_GPIO_BTN_RESET 3 ++/* WPS button - next to a led on right */ ++#define AP96_GPIO_BTN_WPS 8 + -+#define DIR_615C1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DIR_615C1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_615C1_KEYS_POLL_INTERVAL) ++#define AP96_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define AP96_KEYS_DEBOUNCE_INTERVAL (3 * AP96_KEYS_POLL_INTERVAL) + -+#define DIR_615C1_CONFIG_ADDR 0x1f020000 -+#define DIR_615C1_CONFIG_SIZE 0x10000 ++#define AP96_WMAC0_MAC_OFFSET 0x120c ++#define AP96_WMAC1_MAC_OFFSET 0x520c ++#define AP96_CALDATA0_OFFSET 0x1000 ++#define AP96_CALDATA1_OFFSET 0x5000 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition dir_615c1_partitions[] = { ++static struct mtd_partition ap96_partitions[] = { + { -+ .name = "u-boot", ++ .name = "uboot", + .offset = 0, -+ .size = 0x020000, ++ .size = 0x030000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "config", -+ .offset = 0x020000, -+ .size = 0x010000, -+ }, { -+ .name = "kernel", ++ .name = "env", + .offset = 0x030000, -+ .size = 0x0e0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, + }, { + .name = "rootfs", -+ .offset = 0x110000, -+ .size = 0x2e0000, ++ .offset = 0x040000, ++ .size = 0x600000, + }, { -+ .name = "art", -+ .offset = 0x3f0000, ++ .name = "uImage", ++ .offset = 0x640000, ++ .size = 0x1b0000, ++ }, { ++ .name = "caldata", ++ .offset = 0x7f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x030000, -+ .size = 0x3c0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data dir_615c1_flash_data = { ++static struct flash_platform_data ap96_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = dir_615c1_partitions, -+ .nr_parts = ARRAY_SIZE(dir_615c1_partitions), ++ .parts = ap96_partitions, ++ .nr_parts = ARRAY_SIZE(ap96_partitions), +#endif +}; + -+static struct gpio_led dir_615c1_leds_gpio[] __initdata = { ++/* ++ * AP96 has 12 unlabeled leds in the front; these are numbered from 1 to 12 ++ * below (from left to right on the board). Led 1 seems to be on whenever the ++ * board is powered. Led 11 shows LAN link activity actity. Led 3 is orange; ++ * others are green. ++ * ++ * In addition, there is one led next to a button on the right side for WPS. ++ */ ++static struct gpio_led ap96_leds_gpio[] __initdata = { + { -+ .name = "dir-615c1:orange:status", -+ .gpio = DIR_615C1_GPIO_LED_ORANGE_STATUS, ++ .name = "ap96:green:led2", ++ .gpio = AP96_GPIO_LED_2_GREEN, + .active_low = 1, + }, { -+ .name = "dir-615c1:blue:wps", -+ .gpio = DIR_615C1_GPIO_LED_BLUE_WPS, ++ .name = "ap96:green:led3", ++ .gpio = AP96_GPIO_LED_3_GREEN, + .active_low = 1, + }, { -+ .name = "dir-615c1:green:wan", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_WAN, ++ .name = "ap96:orange:led4", ++ .gpio = AP96_GPIO_LED_4_ORANGE, + .active_low = 1, + }, { -+ .name = "dir-615c1:green:wancpu", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_WANCPU, ++ .name = "ap96:green:led5", ++ .gpio = AP96_GPIO_LED_5_GREEN, + .active_low = 1, + }, { -+ .name = "dir-615c1:green:wlan", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_WLAN, ++ .name = "ap96:green:led12", ++ .gpio = AP96_GPIO_LED_12_GREEN, + .active_low = 1, -+ }, { -+ .name = "dir-615c1:green:status", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "dir-615c1:orange:wan", -+ .gpio = DIR_615C1_GPIO_LED_ORANGE_WAN, ++ }, { /* next to a button on right */ ++ .name = "ap96:green:wps", ++ .gpio = AP96_GPIO_LED_WPS_GREEN, + .active_low = 1, + } -+ +}; + -+static struct gpio_keys_button dir_615c1_gpio_keys[] __initdata = { ++static struct gpio_keys_button ap96_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_615C1_GPIO_BTN_RESET, ++ .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP96_GPIO_BTN_RESET, ++ .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_615C1_GPIO_BTN_WPS, ++ .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP96_GPIO_BTN_WPS, ++ .active_low = 1, + } +}; + -+#define DIR_615C1_LAN_PHYMASK BIT(0) -+#define DIR_615C1_WAN_PHYMASK BIT(4) -+#define DIR_615C1_MDIO_MASK (~(DIR_615C1_LAN_PHYMASK | \ -+ DIR_615C1_WAN_PHYMASK)) ++#define AP96_WAN_PHYMASK 0x10 ++#define AP96_LAN_PHYMASK 0x0f + -+static void __init dir_615c1_setup(void) ++static void __init ap96_setup(void) +{ -+ const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[6]; -+ u8 *wlan_mac = NULL; -+ -+ if (nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE, -+ "lan_mac=", mac) == 0) { -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); -+ wlan_mac = mac; -+ } -+ -+ ar71xx_add_device_mdio(DIR_615C1_MDIO_MASK); ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.phy_mask = DIR_615C1_LAN_PHYMASK; ++ ar71xx_add_device_mdio(~(AP96_WAN_PHYMASK | AP96_LAN_PHYMASK)); + -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = DIR_615C1_WAN_PHYMASK; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, art, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = AP96_LAN_PHYMASK; ++ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + + ar71xx_add_device_eth(0); ++ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, art, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = AP96_WAN_PHYMASK; ++ ++ ar71xx_eth1_pll_data.pll_1000 = 0x1f000000; ++ + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_m25p80(&dir_615c1_flash_data); ++ ar71xx_add_device_usb(); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_615c1_leds_gpio), -+ dir_615c1_leds_gpio); ++ ar71xx_add_device_m25p80(&ap96_flash_data); + -+ ar71xx_register_gpio_keys_polled(-1, DIR_615C1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dir_615c1_gpio_keys), -+ dir_615c1_gpio_keys); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap96_leds_gpio), ++ ap96_leds_gpio); + -+ ar9xxx_add_device_wmac(eeprom, wlan_mac); ++ ar71xx_register_gpio_keys_polled(-1, AP96_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap96_gpio_keys), ++ ap96_gpio_keys); ++ ++ ap94_pci_init(art + AP96_CALDATA0_OFFSET, ++ art + AP96_WMAC0_MAC_OFFSET, ++ art + AP96_CALDATA1_OFFSET, ++ art + AP96_WMAC1_MAC_OFFSET); +} + -+MIPS_MACHINE(AR71XX_MACH_DIR_615_C1, "DIR-615-C1", "D-Link DIR-615 rev. C1", -+ dir_615c1_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c 2011-08-24 02:41:55.487989871 +0200 -@@ -0,0 +1,198 @@ ++MIPS_MACHINE(AR71XX_MACH_AP96, "AP96", "Atheros AP96", ap96_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-aw-nr580.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-aw-nr580.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,102 @@ +/* -+ * D-Link DIR-825 rev. B1 board support -+ * -+ * Copyright (C) 2009 Lukas Kuna, Evkanet, s.r.o. ++ * AzureWave AW-NR580 board support + * -+ * based on mach-wndr3700.c ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include +#include +#include -+#include -+#include + ++#include +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ap94-pci.h" +#include "dev-gpio-buttons.h" ++#include "dev-pb42-pci.h" +#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+ -+#define DIR825B1_GPIO_LED_BLUE_USB 0 -+#define DIR825B1_GPIO_LED_ORANGE_POWER 1 -+#define DIR825B1_GPIO_LED_BLUE_POWER 2 -+#define DIR825B1_GPIO_LED_BLUE_WPS 4 -+#define DIR825B1_GPIO_LED_ORANGE_PLANET 6 -+#define DIR825B1_GPIO_LED_BLUE_PLANET 11 -+ -+#define DIR825B1_GPIO_BTN_RESET 3 -+#define DIR825B1_GPIO_BTN_WPS 8 -+ -+#define DIR825B1_GPIO_RTL8366_SDA 5 -+#define DIR825B1_GPIO_RTL8366_SCK 7 -+ -+#define DIR825B1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DIR825B1_KEYS_DEBOUNCE_INTERVAL (3 * DIR825B1_KEYS_POLL_INTERVAL) + -+#define DIR825B1_CAL_LOCATION_0 0x1f661000 -+#define DIR825B1_CAL_LOCATION_1 0x1f665000 -+ -+#define DIR825B1_MAC_LOCATION_0 0x2ffa81b8 -+#define DIR825B1_MAC_LOCATION_1 0x2ffa8370 ++#define AW_NR580_GPIO_LED_READY_RED 0 ++#define AW_NR580_GPIO_LED_WLAN 1 ++#define AW_NR580_GPIO_LED_READY_GREEN 2 ++#define AW_NR580_GPIO_LED_WPS_GREEN 4 ++#define AW_NR580_GPIO_LED_WPS_AMBER 5 + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition dir825b1_partitions[] = { -+ { -+ .name = "uboot", -+ .offset = 0, -+ .size = 0x040000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "config", -+ .offset = 0x040000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x050000, -+ .size = 0x610000, -+ }, { -+ .name = "caldata", -+ .offset = 0x660000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "unknown", -+ .offset = 0x670000, -+ .size = 0x190000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ ++#define AW_NR580_GPIO_BTN_WPS 3 ++#define AW_NR580_GPIO_BTN_RESET 11 + -+static struct flash_platform_data dir825b1_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = dir825b1_partitions, -+ .nr_parts = ARRAY_SIZE(dir825b1_partitions), -+#endif -+}; ++#define AW_NR580_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define AW_NR580_KEYS_DEBOUNCE_INTERVAL (3 * AW_NR580_KEYS_POLL_INTERVAL) + -+static struct gpio_led dir825b1_leds_gpio[] __initdata = { ++static struct gpio_led aw_nr580_leds_gpio[] __initdata = { + { -+ .name = "dir825b1:blue:usb", -+ .gpio = DIR825B1_GPIO_LED_BLUE_USB, -+ .active_low = 1, -+ }, { -+ .name = "dir825b1:orange:power", -+ .gpio = DIR825B1_GPIO_LED_ORANGE_POWER, -+ .active_low = 1, ++ .name = "aw-nr580:red:ready", ++ .gpio = AW_NR580_GPIO_LED_READY_RED, ++ .active_low = 0, + }, { -+ .name = "dir825b1:blue:power", -+ .gpio = DIR825B1_GPIO_LED_BLUE_POWER, -+ .active_low = 1, ++ .name = "aw-nr580:green:ready", ++ .gpio = AW_NR580_GPIO_LED_READY_GREEN, ++ .active_low = 0, + }, { -+ .name = "dir825b1:blue:wps", -+ .gpio = DIR825B1_GPIO_LED_BLUE_WPS, -+ .active_low = 1, ++ .name = "aw-nr580:green:wps", ++ .gpio = AW_NR580_GPIO_LED_WPS_GREEN, ++ .active_low = 0, + }, { -+ .name = "dir825b1:orange:planet", -+ .gpio = DIR825B1_GPIO_LED_ORANGE_PLANET, -+ .active_low = 1, ++ .name = "aw-nr580:amber:wps", ++ .gpio = AW_NR580_GPIO_LED_WPS_AMBER, ++ .active_low = 0, + }, { -+ .name = "dir825b1:blue:planet", -+ .gpio = DIR825B1_GPIO_LED_BLUE_PLANET, -+ .active_low = 1, ++ .name = "aw-nr580:green:wlan", ++ .gpio = AW_NR580_GPIO_LED_WLAN, ++ .active_low = 0, + } +}; + -+static struct gpio_keys_button dir825b1_gpio_keys[] __initdata = { ++static struct gpio_keys_button aw_nr580_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR825B1_GPIO_BTN_RESET, ++ .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AW_NR580_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR825B1_GPIO_BTN_WPS, ++ .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AW_NR580_GPIO_BTN_WPS, + .active_low = 1, + } +}; + -+static struct rtl8366_initval dir825b1_rtl8366s_initvals[] = { -+ { .reg = 0x06, .val = 0x0108 }, -+}; -+ -+static struct rtl8366_platform_data dir825b1_rtl8366s_data = { -+ .gpio_sda = DIR825B1_GPIO_RTL8366_SDA, -+ .gpio_sck = DIR825B1_GPIO_RTL8366_SCK, -+ .num_initvals = ARRAY_SIZE(dir825b1_rtl8366s_initvals), -+ .initvals = dir825b1_rtl8366s_initvals, -+}; -+ -+static struct platform_device dir825b1_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &dir825b1_rtl8366s_data, -+ } -+}; -+ -+static void __init dir825b1_setup(void) ++static void __init aw_nr580_setup(void) +{ -+ u8 *mac = (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1); -+ + ar71xx_add_device_mdio(0x0); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 1); -+ ar71xx_eth0_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_pll_data.pll_1000 = 0x11110000; -+ -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 2); -+ ar71xx_eth1_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = 0x10; -+ ar71xx_eth1_pll_data.pll_1000 = 0x11110000; + + ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); -+ -+ ar71xx_add_device_m25p80(&dir825b1_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir825b1_leds_gpio), -+ dir825b1_leds_gpio); -+ -+ ar71xx_register_gpio_keys_polled(-1, DIR825B1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dir825b1_gpio_keys), -+ dir825b1_gpio_keys); + -+ ar71xx_add_device_usb(); ++ pb42_pci_init(); + -+ platform_device_register(&dir825b1_rtl8366s_device); ++ ar71xx_add_device_m25p80(NULL); + -+ ap94_pci_setup_wmac_led_pin(0, 5); -+ ap94_pci_setup_wmac_led_pin(1, 5); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio), ++ aw_nr580_leds_gpio); + -+ ap94_pci_init((u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_0), -+ (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_0), -+ (u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_1), -+ (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1)); ++ ar71xx_register_gpio_keys_polled(-1, AW_NR580_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(aw_nr580_gpio_keys), ++ aw_nr580_gpio_keys); +} + -+MIPS_MACHINE(AR71XX_MACH_DIR_825_B1, "DIR-825-B1", "D-Link DIR-825 rev. B1", -+ dir825b1_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-eap7660d.c linux-2.6.39/arch/mips/ar71xx/mach-eap7660d.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-eap7660d.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-eap7660d.c 2011-08-24 02:41:55.497990784 +0200 -@@ -0,0 +1,180 @@ ++MIPS_MACHINE(AR71XX_MACH_AW_NR580, "AW-NR580", "AzureWave AW-NR580", ++ aw_nr580_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-db120.c linux-2.6.39/arch/mips/ar71xx/mach-db120.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-db120.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-db120.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,134 @@ +/* -+ * Senao EAP7660D board support ++ * Atheros DB120 board (WASP SoC) support + * -+ * Copyright (C) 2010 Daniel Golle -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include ++#include ++#include ++ +#include -+#include + +#include "machtype.h" +#include "devices.h" ++#include "dev-m25p80.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" ++#include "dev-usb.h" ++#include "dev-ar9xxx-wmac.h" ++#include "dev-db120-pci.h" + -+#define EAP7660D_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define EAP7660D_KEYS_DEBOUNCE_INTERVAL (3 * EAP7660D_KEYS_POLL_INTERVAL) ++#define DB120_GPIO_LED_USB 11 ++#define DB120_GPIO_LED_WLAN_5G 12 ++#define DB120_GPIO_LED_WLAN_2G 13 ++#define DB120_GPIO_LED_STATUS 14 ++#define DB120_GPIO_LED_WPS 15 + -+#define EAP7660D_GPIO_DS4 7 -+#define EAP7660D_GPIO_DS5 2 -+#define EAP7660D_GPIO_DS7 0 -+#define EAP7660D_GPIO_DS8 4 -+#define EAP7660D_GPIO_SW1 3 -+#define EAP7660D_GPIO_SW3 8 -+#define EAP7660D_PHYMASK BIT(20) -+#define EAP7660D_BOARDCONFIG 0x1F7F0000 -+#define EAP7660D_GBIC_MAC_OFFSET 0x1000 -+#define EAP7660D_WMAC0_MAC_OFFSET 0x1010 -+#define EAP7660D_WMAC1_MAC_OFFSET 0x1016 -+#define EAP7660D_WMAC0_CALDATA_OFFSET 0x2000 -+#define EAP7660D_WMAC1_CALDATA_OFFSET 0x3000 ++#define DB120_GPIO_BTN_SW1 16 + -+static struct ath5k_platform_data eap7660d_wmac0_data; -+static struct ath5k_platform_data eap7660d_wmac1_data; -+static char eap7660d_wmac0_mac[6]; -+static char eap7660d_wmac1_mac[6]; -+static u16 eap7660d_wmac0_eeprom[ATH5K_PLAT_EEP_MAX_WORDS]; -+static u16 eap7660d_wmac1_eeprom[ATH5K_PLAT_EEP_MAX_WORDS]; ++#define DB120_CALDATA_OFFSET 0x1000 ++#define DB120_WMAC_MAC_OFFSET 0x1002 + -+#ifdef CONFIG_PCI -+static struct ar71xx_pci_irq eap7660d_pci_irqs[] __initdata = { ++#define DB120_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL) ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition db120_partitions[] = { + { -+ .slot = 0, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV0, ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .slot = 1, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV1, ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x050000, ++ .size = 0x630000, ++ }, { ++ .name = "uImage", ++ .offset = 0x680000, ++ .size = 0x160000, ++ }, { ++ .name = "NVRAM", ++ .offset = 0x7E0000, ++ .size = 0x010000, ++ }, { ++ .name = "ART", ++ .offset = 0x7F0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, + } +}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+static int eap7660d_pci_plat_dev_init(struct pci_dev *dev) -+{ -+ switch (PCI_SLOT(dev->devfn)) { -+ case 17: -+ dev->dev.platform_data = &eap7660d_wmac0_data; -+ break; -+ -+ case 18: -+ dev->dev.platform_data = &eap7660d_wmac1_data; -+ break; -+ } -+ -+ return 0; -+} -+ -+void __init eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0, -+ u8 *cal_data1, u8 *mac_addr1) -+{ -+ if (cal_data0 && *cal_data0 == 0xa55a) { -+ memcpy(eap7660d_wmac0_eeprom, cal_data0, -+ ATH5K_PLAT_EEP_MAX_WORDS); -+ eap7660d_wmac0_data.eeprom_data = eap7660d_wmac0_eeprom; -+ } -+ -+ if (cal_data1 && *cal_data1 == 0xa55a) { -+ memcpy(eap7660d_wmac1_eeprom, cal_data1, -+ ATH5K_PLAT_EEP_MAX_WORDS); -+ eap7660d_wmac1_data.eeprom_data = eap7660d_wmac1_eeprom; -+ } -+ -+ if (mac_addr0) { -+ memcpy(eap7660d_wmac0_mac, mac_addr0, -+ sizeof(eap7660d_wmac0_mac)); -+ eap7660d_wmac0_data.macaddr = eap7660d_wmac0_mac; -+ } -+ -+ if (mac_addr1) { -+ memcpy(eap7660d_wmac1_mac, mac_addr1, -+ sizeof(eap7660d_wmac1_mac)); -+ eap7660d_wmac1_data.macaddr = eap7660d_wmac1_mac; -+ } -+ -+ ar71xx_pci_plat_dev_init = eap7660d_pci_plat_dev_init; -+ ar71xx_pci_init(ARRAY_SIZE(eap7660d_pci_irqs), eap7660d_pci_irqs); -+} -+#else -+static inline void eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0, -+ u8 *cal_data1, u8 *mac_addr1) -+{ -+} -+#endif /* CONFIG_PCI */ ++static struct flash_platform_data db120_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = db120_partitions, ++ .nr_parts = ARRAY_SIZE(db120_partitions), ++#endif ++}; + -+static struct gpio_led eap7660d_leds_gpio[] __initdata = { -+ { -+ .name = "eap7660d:green:ds8", -+ .gpio = EAP7660D_GPIO_DS8, -+ .active_low = 0, -+ }, -+ { -+ .name = "eap7660d:green:ds5", -+ .gpio = EAP7660D_GPIO_DS5, -+ .active_low = 0, -+ }, -+ { -+ .name = "eap7660d:green:ds7", -+ .gpio = EAP7660D_GPIO_DS7, -+ .active_low = 0, -+ }, ++static struct gpio_led db120_leds_gpio[] __initdata = { + { -+ .name = "eap7660d:green:ds4", -+ .gpio = EAP7660D_GPIO_DS4, -+ .active_low = 0, ++ .name = "db120:green:status", ++ .gpio = DB120_GPIO_LED_STATUS, ++ .active_low = 1, ++ }, { ++ .name = "db120:green:wps", ++ .gpio = DB120_GPIO_LED_WPS, ++ .active_low = 1, ++ }, { ++ .name = "db120:green:wlan-5g", ++ .gpio = DB120_GPIO_LED_WLAN_5G, ++ .active_low = 1, ++ }, { ++ .name = "db120:green:wlan-2g", ++ .gpio = DB120_GPIO_LED_WLAN_2G, ++ .active_low = 1, ++ }, { ++ .name = "db120:green:usb", ++ .gpio = DB120_GPIO_LED_USB, ++ .active_low = 1, + } +}; + -+static struct gpio_keys_button eap7660d_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = EAP7660D_GPIO_SW1, -+ .active_low = 1, -+ }, ++static struct gpio_keys_button db120_gpio_keys[] __initdata = { + { -+ .desc = "wps", ++ .desc = "sw1", + .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = EAP7660D_GPIO_SW3, ++ .code = BTN_0, ++ .debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DB120_GPIO_BTN_SW1, + .active_low = 1, + } +}; + -+static void __init eap7660d_setup(void) ++static void __init db120_setup(void) +{ -+ u8 *boardconfig = (u8 *) KSEG1ADDR(EAP7660D_BOARDCONFIG); ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + -+ ar71xx_add_device_mdio(~EAP7660D_PHYMASK); ++ ar71xx_add_device_usb(); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, -+ boardconfig + EAP7660D_GBIC_MAC_OFFSET, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.phy_mask = EAP7660D_PHYMASK; -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_m25p80(NULL); -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(eap7660d_leds_gpio), -+ eap7660d_leds_gpio); -+ ar71xx_register_gpio_keys_polled(-1, EAP7660D_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(eap7660d_gpio_keys), -+ eap7660d_gpio_keys); -+ eap7660d_pci_init(boardconfig + EAP7660D_WMAC0_CALDATA_OFFSET, -+ boardconfig + EAP7660D_WMAC0_MAC_OFFSET, -+ boardconfig + EAP7660D_WMAC1_CALDATA_OFFSET, -+ boardconfig + EAP7660D_WMAC1_MAC_OFFSET); -+}; ++ ar71xx_add_device_m25p80(&db120_flash_data); + -+MIPS_MACHINE(AR71XX_MACH_EAP7660D, "EAP7660D", "Senao EAP7660D", -+ eap7660d_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ja76pf.c linux-2.6.39/arch/mips/ar71xx/mach-ja76pf.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-ja76pf.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-ja76pf.c 2011-08-24 02:41:55.517989552 +0200 -@@ -0,0 +1,102 @@ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio), ++ db120_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(db120_gpio_keys), ++ db120_gpio_keys); ++ ++ ar9xxx_add_device_wmac(art + DB120_CALDATA_OFFSET, ++ art + DB120_WMAC_MAC_OFFSET); ++ ++ db120_pci_init(); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_DB120, "DB120", "Atheros DB120", db120_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-600-a1.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-dir-600-a1.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,159 @@ +/* -+ * jjPlus JA76PF board support ++ * D-Link DIR-600 rev. A1 board support ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + */ + ++#include ++#include ++ +#include -+#include -+#include -+#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" ++#include "dev-ap91-pci.h" +#include "dev-gpio-buttons.h" -+#include "dev-pb42-pci.h" -+#include "dev-usb.h" +#include "dev-leds-gpio.h" ++#include "nvram.h" + -+#define JA76PF_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define JA76PF_KEYS_DEBOUNCE_INTERVAL (3 * JA76PF_KEYS_POLL_INTERVAL) -+ -+#define JA76PF_GPIO_I2C_SCL 0 -+#define JA76PF_GPIO_I2C_SDA 1 -+#define JA76PF_GPIO_LED_1 5 -+#define JA76PF_GPIO_LED_2 4 -+#define JA76PF_GPIO_LED_3 3 -+#define JA76PF_GPIO_BTN_RESET 11 ++#define DIR_600_A1_GPIO_LED_WPS 0 ++#define DIR_600_A1_GPIO_LED_POWER_AMBER 1 ++#define DIR_600_A1_GPIO_LED_POWER_GREEN 6 + -+static struct gpio_led ja76pf_leds_gpio[] __initdata = { ++#define DIR_600_A1_GPIO_BTN_RESET 8 ++#define DIR_600_A1_GPIO_BTN_WPS 12 ++ ++#define DIR_600_A1_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define DIR_600_A1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_600_A1_KEYS_POLL_INTERVAL) ++ ++#define DIR_600_A1_NVRAM_ADDR 0x1f030000 ++#define DIR_600_A1_NVRAM_SIZE 0x10000 ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition dir_600_a1_partitions[] = { + { -+ .name = "ja76pf:green:led1", -+ .gpio = JA76PF_GPIO_LED_1, -+ .active_low = 1, ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x030000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "ja76pf:green:led2", -+ .gpio = JA76PF_GPIO_LED_2, -+ .active_low = 1, ++ .name = "nvram", ++ .offset = 0x030000, ++ .size = 0x010000, + }, { -+ .name = "ja76pf:green:led3", -+ .gpio = JA76PF_GPIO_LED_3, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button ja76pf_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = JA76PF_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = JA76PF_GPIO_BTN_RESET, -+ .active_low = 1, ++ .name = "kernel", ++ .offset = 0x040000, ++ .size = 0x0e0000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x120000, ++ .size = 0x2c0000, ++ }, { ++ .name = "mac", ++ .offset = 0x3e0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "art", ++ .offset = 0x3f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x040000, ++ .size = 0x3a0000, + } +}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct i2c_gpio_platform_data ja76pf_i2c_gpio_data = { -+ .sda_pin = JA76PF_GPIO_I2C_SDA, -+ .scl_pin = JA76PF_GPIO_I2C_SCL, ++static struct flash_platform_data dir_600_a1_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = dir_600_a1_partitions, ++ .nr_parts = ARRAY_SIZE(dir_600_a1_partitions), ++#endif +}; + -+static struct platform_device ja76pf_i2c_gpio_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &ja76pf_i2c_gpio_data, ++static struct gpio_led dir_600_a1_leds_gpio[] __initdata = { ++ { ++ .name = "dir-600-a1:green:power", ++ .gpio = DIR_600_A1_GPIO_LED_POWER_GREEN, ++ }, { ++ .name = "dir-600-a1:amber:power", ++ .gpio = DIR_600_A1_GPIO_LED_POWER_AMBER, ++ }, { ++ .name = "dir-600-a1:blue:wps", ++ .gpio = DIR_600_A1_GPIO_LED_WPS, ++ .active_low = 1, + } +}; + -+#define JA76PF_WAN_PHYMASK (1 << 4) -+#define JA76PF_LAN_PHYMASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 < 3)) -+#define JA76PF_MDIO_PHYMASK (JA76PF_LAN_PHYMASK | JA76PF_WAN_PHYMASK) -+ -+static void __init ja76pf_init(void) -+{ -+ ar71xx_add_device_m25p80(NULL); -+ -+ ar71xx_add_device_mdio(~JA76PF_MDIO_PHYMASK); -+ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.phy_mask = JA76PF_LAN_PHYMASK; -+ -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = JA76PF_WAN_PHYMASK; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; -+ -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); -+ -+ platform_device_register(&ja76pf_i2c_gpio_device); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ja76pf_leds_gpio), -+ ja76pf_leds_gpio); -+ -+ ar71xx_register_gpio_keys_polled(-1, JA76PF_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ja76pf_gpio_keys), -+ ja76pf_gpio_keys); -+ -+ ar71xx_add_device_usb(); -+ pb42_pci_init(); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_JA76PF, "JA76PF", "jjPlus JA76PF", ja76pf_init); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-jwap003.c linux-2.6.39/arch/mips/ar71xx/mach-jwap003.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-jwap003.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-jwap003.c 2011-08-24 02:41:55.517989552 +0200 -@@ -0,0 +1,83 @@ -+/* -+ * jjPlus JWAP003 board support -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "machtype.h" -+#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-gpio-buttons.h" -+#include "dev-pb42-pci.h" -+#include "dev-usb.h" -+ -+#define JWAP003_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define JWAP003_KEYS_DEBOUNCE_INTERVAL (3 * JWAP003_KEYS_POLL_INTERVAL) -+ -+#define JWAP003_GPIO_WPS 11 -+#define JWAP003_GPIO_I2C_SCL 0 -+#define JWAP003_GPIO_I2C_SDA 1 -+ -+static struct gpio_keys_button jwap003_gpio_keys[] __initdata = { ++static struct gpio_keys_button dir_600_a1_gpio_keys[] __initdata = { + { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR_600_A1_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = JWAP003_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = JWAP003_GPIO_WPS, ++ .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR_600_A1_GPIO_BTN_WPS, + .active_low = 1, + } +}; + -+static struct i2c_gpio_platform_data jwap003_i2c_gpio_data = { -+ .sda_pin = JWAP003_GPIO_I2C_SDA, -+ .scl_pin = JWAP003_GPIO_I2C_SCL, -+}; ++static void __init dir_600_a1_setup(void) ++{ ++ const char *nvram = (char *) KSEG1ADDR(DIR_600_A1_NVRAM_ADDR); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 mac_buff[6]; ++ u8 *mac = NULL; + -+static struct platform_device jwap003_i2c_gpio_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &jwap003_i2c_gpio_data, ++ if (nvram_parse_mac_addr(nvram, DIR_600_A1_NVRAM_SIZE, ++ "lan_mac=", mac_buff) == 0) { ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac_buff, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac_buff, 1); ++ mac = mac_buff; + } -+}; + -+#define JWAP003_WAN_PHYMASK BIT(0) -+#define JWAP003_LAN_PHYMASK BIT(4) ++ ar71xx_add_device_m25p80(&dir_600_a1_flash_data); + -+static void __init jwap003_init(void) -+{ -+ ar71xx_add_device_m25p80(NULL); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_600_a1_leds_gpio), ++ dir_600_a1_leds_gpio); + -+ ar71xx_add_device_mdio(0x0); ++ ar71xx_register_gpio_keys_polled(-1, DIR_600_A1_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(dir_600_a1_gpio_keys), ++ dir_600_a1_gpio_keys); ++ ++ ar71xx_eth1_data.has_ar7240_switch = 1; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); + ++ /* WAN port */ + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.phy_mask = JWAP003_WAN_PHYMASK; + ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.has_ar8216 = 1; ++ ar71xx_eth0_data.phy_mask = BIT(4); + ++ /* LAN ports */ + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = JWAP003_LAN_PHYMASK; -+ ar71xx_eth1_data.speed = SPEED_100; ++ ar71xx_eth1_data.speed = SPEED_1000; + ar71xx_eth1_data.duplex = DUPLEX_FULL; + -+ ar71xx_add_device_eth(0); ++ ar71xx_add_device_mdio(0x0); + ar71xx_add_device_eth(1); ++ ar71xx_add_device_eth(0); + -+ platform_device_register(&jwap003_i2c_gpio_device); -+ -+ ar71xx_add_device_usb(); -+ -+ ar71xx_register_gpio_keys_polled(-1, JWAP003_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(jwap003_gpio_keys), -+ jwap003_gpio_keys); -+ -+ pb42_pci_init(); ++ ap91_pci_init(ee, mac); +} + -+MIPS_MACHINE(AR71XX_MACH_JWAP003, "JWAP003", "jjPlus JWAP003", jwap003_init); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c 2011-08-24 02:41:55.517989552 +0200 -@@ -0,0 +1,166 @@ ++MIPS_MACHINE(AR71XX_MACH_DIR_600_A1, "DIR-600-A1", "D-Link DIR-600 rev. A1", ++ dir_600_a1_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-615-c1.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-dir-615-c1.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,175 @@ +/* -+ * Planex MZK-W04NU board support ++ * D-Link DIR-615 rev C1 board support + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -5351,563 +4735,561 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.39/arch/ + +#include "machtype.h" +#include "devices.h" ++#include "dev-m25p80.h" +#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+ -+#define MZK_W04NU_GPIO_LED_USB 0 -+#define MZK_W04NU_GPIO_LED_STATUS 1 -+#define MZK_W04NU_GPIO_LED_WPS 3 -+#define MZK_W04NU_GPIO_LED_WLAN 6 -+#define MZK_W04NU_GPIO_LED_AP 15 -+#define MZK_W04NU_GPIO_LED_ROUTER 16 ++#include "nvram.h" + -+#define MZK_W04NU_GPIO_BTN_APROUTER 5 -+#define MZK_W04NU_GPIO_BTN_WPS 12 -+#define MZK_W04NU_GPIO_BTN_RESET 21 ++#define DIR_615C1_GPIO_LED_ORANGE_STATUS 1 /* ORANGE:STATUS:TRICOLOR */ ++#define DIR_615C1_GPIO_LED_BLUE_WPS 3 /* BLUE:WPS */ ++#define DIR_615C1_GPIO_LED_GREEN_WAN 4 /* GREEN:WAN:TRICOLOR */ ++#define DIR_615C1_GPIO_LED_GREEN_WANCPU 5 /* GREEN:WAN:CPU:TRICOLOR */ ++#define DIR_615C1_GPIO_LED_GREEN_WLAN 6 /* GREEN:WLAN */ ++#define DIR_615C1_GPIO_LED_GREEN_STATUS 14 /* GREEN:STATUS:TRICOLOR */ ++#define DIR_615C1_GPIO_LED_ORANGE_WAN 15 /* ORANGE:WAN:TRICOLOR */ + -+#define MZK_W04NU_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MZK_W04NU_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W04NU_KEYS_POLL_INTERVAL) ++/* buttons may need refinement */ ++ ++#define DIR_615C1_GPIO_BTN_WPS 12 ++#define DIR_615C1_GPIO_BTN_RESET 21 ++ ++#define DIR_615C1_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define DIR_615C1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_615C1_KEYS_POLL_INTERVAL) ++ ++#define DIR_615C1_CONFIG_ADDR 0x1f020000 ++#define DIR_615C1_CONFIG_SIZE 0x10000 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition mzk_w04nu_partitions[] = { ++static struct mtd_partition dir_615c1_partitions[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x040000, ++ .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "u-boot-env", -+ .offset = 0x040000, ++ .name = "config", ++ .offset = 0x020000, + .size = 0x010000, + }, { + .name = "kernel", -+ .offset = 0x050000, -+ .size = 0x160000, ++ .offset = 0x030000, ++ .size = 0x0e0000, + }, { + .name = "rootfs", -+ .offset = 0x1b0000, -+ .size = 0x630000, ++ .offset = 0x110000, ++ .size = 0x2e0000, + }, { + .name = "art", -+ .offset = 0x7e0000, -+ .size = 0x020000, ++ .offset = 0x3f0000, ++ .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", -+ .offset = 0x050000, -+ .size = 0x790000, ++ .offset = 0x030000, ++ .size = 0x3c0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data mzk_w04nu_flash_data = { ++static struct flash_platform_data dir_615c1_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = mzk_w04nu_partitions, -+ .nr_parts = ARRAY_SIZE(mzk_w04nu_partitions), ++ .parts = dir_615c1_partitions, ++ .nr_parts = ARRAY_SIZE(dir_615c1_partitions), +#endif +}; + -+static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = { ++static struct gpio_led dir_615c1_leds_gpio[] __initdata = { + { -+ .name = "mzk-w04nu:green:status", -+ .gpio = MZK_W04NU_GPIO_LED_STATUS, ++ .name = "dir-615c1:orange:status", ++ .gpio = DIR_615C1_GPIO_LED_ORANGE_STATUS, + .active_low = 1, + }, { -+ .name = "mzk-w04nu:blue:wps", -+ .gpio = MZK_W04NU_GPIO_LED_WPS, ++ .name = "dir-615c1:blue:wps", ++ .gpio = DIR_615C1_GPIO_LED_BLUE_WPS, + .active_low = 1, + }, { -+ .name = "mzk-w04nu:green:wlan", -+ .gpio = MZK_W04NU_GPIO_LED_WLAN, ++ .name = "dir-615c1:green:wan", ++ .gpio = DIR_615C1_GPIO_LED_GREEN_WAN, + .active_low = 1, + }, { -+ .name = "mzk-w04nu:green:usb", -+ .gpio = MZK_W04NU_GPIO_LED_USB, ++ .name = "dir-615c1:green:wancpu", ++ .gpio = DIR_615C1_GPIO_LED_GREEN_WANCPU, + .active_low = 1, + }, { -+ .name = "mzk-w04nu:green:ap", -+ .gpio = MZK_W04NU_GPIO_LED_AP, ++ .name = "dir-615c1:green:wlan", ++ .gpio = DIR_615C1_GPIO_LED_GREEN_WLAN, + .active_low = 1, + }, { -+ .name = "mzk-w04nu:green:router", -+ .gpio = MZK_W04NU_GPIO_LED_ROUTER, ++ .name = "dir-615c1:green:status", ++ .gpio = DIR_615C1_GPIO_LED_GREEN_STATUS, ++ .active_low = 1, ++ }, { ++ .name = "dir-615c1:orange:wan", ++ .gpio = DIR_615C1_GPIO_LED_ORANGE_WAN, + .active_low = 1, + } ++ +}; + -+static struct gpio_keys_button mzk_w04nu_gpio_keys[] __initdata = { ++static struct gpio_keys_button dir_615c1_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W04NU_GPIO_BTN_RESET, -+ .active_low = 1, ++ .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR_615C1_GPIO_BTN_RESET, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W04NU_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, { -+ .desc = "aprouter", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W04NU_GPIO_BTN_APROUTER, -+ .active_low = 0, ++ .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR_615C1_GPIO_BTN_WPS, + } +}; + -+#define MZK_W04NU_WAN_PHYMASK BIT(4) -+#define MZK_W04NU_MDIO_MASK (~MZK_W04NU_WAN_PHYMASK) ++#define DIR_615C1_LAN_PHYMASK BIT(0) ++#define DIR_615C1_WAN_PHYMASK BIT(4) ++#define DIR_615C1_MDIO_MASK (~(DIR_615C1_LAN_PHYMASK | \ ++ DIR_615C1_WAN_PHYMASK)) + -+static void __init mzk_w04nu_setup(void) ++static void __init dir_615c1_setup(void) +{ ++ const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR); + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 mac[6]; ++ u8 *wlan_mac = NULL; + -+ ar71xx_add_device_mdio(MZK_W04NU_MDIO_MASK); ++ if (nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE, ++ "lan_mac=", mac) == 0) { ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ wlan_mac = mac; ++ } ++ ++ ar71xx_add_device_mdio(DIR_615C1_MDIO_MASK); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.has_ar8216 = 1; ++ ar71xx_eth0_data.phy_mask = DIR_615C1_LAN_PHYMASK; + -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = MZK_W04NU_WAN_PHYMASK; ++ ar71xx_eth1_data.phy_mask = DIR_615C1_WAN_PHYMASK; + + ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_m25p80(&mzk_w04nu_flash_data); ++ ar71xx_add_device_m25p80(&dir_615c1_flash_data); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio), -+ mzk_w04nu_leds_gpio); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir_615c1_leds_gpio), ++ dir_615c1_leds_gpio); + -+ ar71xx_register_gpio_keys_polled(-1, MZK_W04NU_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mzk_w04nu_gpio_keys), -+ mzk_w04nu_gpio_keys); -+ ar71xx_add_device_usb(); ++ ar71xx_register_gpio_keys_polled(-1, DIR_615C1_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(dir_615c1_gpio_keys), ++ dir_615c1_gpio_keys); + -+ ar9xxx_add_device_wmac(eeprom, NULL); ++ ar9xxx_add_device_wmac(eeprom, wlan_mac); +} + -+MIPS_MACHINE(AR71XX_MACH_MZK_W04NU, "MZK-W04NU", "Planex MZK-W04NU", -+ mzk_w04nu_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c 2011-08-24 02:41:55.527982711 +0200 -@@ -0,0 +1,159 @@ ++MIPS_MACHINE(AR71XX_MACH_DIR_615_C1, "DIR-615-C1", "D-Link DIR-615 rev. C1", ++ dir_615c1_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-dir-825-b1.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-dir-825-b1.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,198 @@ +/* -+ * Planex MZK-W300NH board support ++ * D-Link DIR-825 rev. B1 board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009 Lukas Kuna, Evkanet, s.r.o. ++ * ++ * based on mach-wndr3700.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include +#include +#include ++#include ++#include + +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ar9xxx-wmac.h" ++#include "dev-ap94-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+#define MZK_W300NH_GPIO_LED_STATUS 1 -+#define MZK_W300NH_GPIO_LED_WPS 3 -+#define MZK_W300NH_GPIO_LED_WLAN 6 -+#define MZK_W300NH_GPIO_LED_AP 15 -+#define MZK_W300NH_GPIO_LED_ROUTER 16 ++#define DIR825B1_GPIO_LED_BLUE_USB 0 ++#define DIR825B1_GPIO_LED_ORANGE_POWER 1 ++#define DIR825B1_GPIO_LED_BLUE_POWER 2 ++#define DIR825B1_GPIO_LED_BLUE_WPS 4 ++#define DIR825B1_GPIO_LED_ORANGE_PLANET 6 ++#define DIR825B1_GPIO_LED_BLUE_PLANET 11 + -+#define MZK_W300NH_GPIO_BTN_APROUTER 5 -+#define MZK_W300NH_GPIO_BTN_WPS 12 -+#define MZK_W300NH_GPIO_BTN_RESET 21 ++#define DIR825B1_GPIO_BTN_RESET 3 ++#define DIR825B1_GPIO_BTN_WPS 8 + -+#define MZK_W300NH_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MZK_W300NH_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W300NH_KEYS_POLL_INTERVAL) ++#define DIR825B1_GPIO_RTL8366_SDA 5 ++#define DIR825B1_GPIO_RTL8366_SCK 7 ++ ++#define DIR825B1_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define DIR825B1_KEYS_DEBOUNCE_INTERVAL (3 * DIR825B1_KEYS_POLL_INTERVAL) ++ ++#define DIR825B1_CAL_LOCATION_0 0x1f661000 ++#define DIR825B1_CAL_LOCATION_1 0x1f665000 ++ ++#define DIR825B1_MAC_LOCATION_0 0x2ffa81b8 ++#define DIR825B1_MAC_LOCATION_1 0x2ffa8370 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition mzk_w300nh_partitions[] = { ++static struct mtd_partition dir825b1_partitions[] = { + { -+ .name = "u-boot", ++ .name = "uboot", + .offset = 0, + .size = 0x040000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "u-boot-env", ++ .name = "config", + .offset = 0x040000, + .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "kernel", ++ .name = "firmware", + .offset = 0x050000, -+ .size = 0x160000, -+ }, { -+ .name = "rootfs", -+ .offset = 0x1b0000, -+ .size = 0x630000, ++ .size = 0x610000, + }, { -+ .name = "art", -+ .offset = 0x7e0000, -+ .size = 0x020000, ++ .name = "caldata", ++ .offset = 0x660000, ++ .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "firmware", -+ .offset = 0x050000, -+ .size = 0x790000, ++ .name = "unknown", ++ .offset = 0x670000, ++ .size = 0x190000, ++ .mask_flags = MTD_WRITEABLE, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data mzk_w300nh_flash_data = { ++static struct flash_platform_data dir825b1_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = mzk_w300nh_partitions, -+ .nr_parts = ARRAY_SIZE(mzk_w300nh_partitions), ++ .parts = dir825b1_partitions, ++ .nr_parts = ARRAY_SIZE(dir825b1_partitions), +#endif +}; + -+static struct gpio_led mzk_w300nh_leds_gpio[] __initdata = { ++static struct gpio_led dir825b1_leds_gpio[] __initdata = { + { -+ .name = "mzk-w300nh:green:status", -+ .gpio = MZK_W300NH_GPIO_LED_STATUS, ++ .name = "dir825b1:blue:usb", ++ .gpio = DIR825B1_GPIO_LED_BLUE_USB, + .active_low = 1, + }, { -+ .name = "mzk-w300nh:blue:wps", -+ .gpio = MZK_W300NH_GPIO_LED_WPS, ++ .name = "dir825b1:orange:power", ++ .gpio = DIR825B1_GPIO_LED_ORANGE_POWER, + .active_low = 1, + }, { -+ .name = "mzk-w300nh:green:wlan", -+ .gpio = MZK_W300NH_GPIO_LED_WLAN, ++ .name = "dir825b1:blue:power", ++ .gpio = DIR825B1_GPIO_LED_BLUE_POWER, + .active_low = 1, + }, { -+ .name = "mzk-w300nh:green:ap", -+ .gpio = MZK_W300NH_GPIO_LED_AP, ++ .name = "dir825b1:blue:wps", ++ .gpio = DIR825B1_GPIO_LED_BLUE_WPS, + .active_low = 1, + }, { -+ .name = "mzk-w300nh:green:router", -+ .gpio = MZK_W300NH_GPIO_LED_ROUTER, ++ .name = "dir825b1:orange:planet", ++ .gpio = DIR825B1_GPIO_LED_ORANGE_PLANET, ++ .active_low = 1, ++ }, { ++ .name = "dir825b1:blue:planet", ++ .gpio = DIR825B1_GPIO_LED_BLUE_PLANET, + .active_low = 1, + } +}; + -+static struct gpio_keys_button mzk_w300nh_gpio_keys[] __initdata = { ++static struct gpio_keys_button dir825b1_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W300NH_GPIO_BTN_RESET, ++ .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR825B1_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W300NH_GPIO_BTN_WPS, ++ .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DIR825B1_GPIO_BTN_WPS, + .active_low = 1, -+ }, { -+ .desc = "aprouter", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W300NH_GPIO_BTN_APROUTER, -+ .active_low = 0, + } +}; + -+#define MZK_W300NH_WAN_PHYMASK BIT(4) -+#define MZK_W300NH_MDIO_MASK (~MZK_W300NH_WAN_PHYMASK) ++static struct rtl8366_initval dir825b1_rtl8366s_initvals[] = { ++ { .reg = 0x06, .val = 0x0108 }, ++}; + -+static void __init mzk_w300nh_setup(void) ++static struct rtl8366_platform_data dir825b1_rtl8366s_data = { ++ .gpio_sda = DIR825B1_GPIO_RTL8366_SDA, ++ .gpio_sck = DIR825B1_GPIO_RTL8366_SCK, ++ .num_initvals = ARRAY_SIZE(dir825b1_rtl8366s_initvals), ++ .initvals = dir825b1_rtl8366s_initvals, ++}; ++ ++static struct platform_device dir825b1_rtl8366s_device = { ++ .name = RTL8366S_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &dir825b1_rtl8366s_data, ++ } ++}; ++ ++static void __init dir825b1_setup(void) +{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 *mac = (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1); + -+ ar71xx_add_device_mdio(MZK_W300NH_MDIO_MASK); ++ ar71xx_add_device_mdio(0x0); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 1); ++ ar71xx_eth0_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.speed = SPEED_1000; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.has_ar8216 = 1; ++ ar71xx_eth0_pll_data.pll_1000 = 0x11110000; + -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = MZK_W300NH_WAN_PHYMASK; ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 2); ++ ar71xx_eth1_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = 0x10; ++ ar71xx_eth1_pll_data.pll_1000 = 0x11110000; + + ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_m25p80(&mzk_w300nh_flash_data); ++ ar71xx_add_device_m25p80(&dir825b1_flash_data); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w300nh_leds_gpio), -+ mzk_w300nh_leds_gpio); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(dir825b1_leds_gpio), ++ dir825b1_leds_gpio); + -+ ar71xx_register_gpio_keys_polled(-1, MZK_W300NH_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mzk_w300nh_gpio_keys), -+ mzk_w300nh_gpio_keys); -+ ar9xxx_add_device_wmac(eeprom, NULL); ++ ar71xx_register_gpio_keys_polled(-1, DIR825B1_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(dir825b1_gpio_keys), ++ dir825b1_gpio_keys); ++ ++ ar71xx_add_device_usb(); ++ ++ platform_device_register(&dir825b1_rtl8366s_device); ++ ++ ap94_pci_setup_wmac_led_pin(0, 5); ++ ap94_pci_setup_wmac_led_pin(1, 5); ++ ++ ap94_pci_init((u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_0), ++ (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_0), ++ (u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_1), ++ (u8 *) KSEG1ADDR(DIR825B1_MAC_LOCATION_1)); +} + -+MIPS_MACHINE(AR71XX_MACH_MZK_W300NH, "MZK-W300NH", "Planex MZK-W300NH", -+ mzk_w300nh_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c 2011-08-24 02:41:55.537990605 +0200 -@@ -0,0 +1,225 @@ ++MIPS_MACHINE(AR71XX_MACH_DIR_825_B1, "DIR-825-B1", "D-Link DIR-825 rev. B1", ++ dir825b1_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-eap7660d.c linux-2.6.39/arch/mips/ar71xx/mach-eap7660d.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-eap7660d.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-eap7660d.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,180 @@ +/* -+ * Zyxel NBG 460N/550N/550NH board support -+ * -+ * Copyright (C) 2010 Michael Kurz ++ * Senao EAP7660D board support + * -+ * based on mach-tl-wr1043nd.c ++ * Copyright (C) 2010 Daniel Golle ++ * Copyright (C) 2008 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include ++#include ++#include +#include -+#include -+ -+#include -+#include -+#include -+ +#include ++#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "dev-m25p80.h" + -+/* LEDs */ -+#define NBG460N_GPIO_LED_WPS 3 -+#define NBG460N_GPIO_LED_WAN 6 -+#define NBG460N_GPIO_LED_POWER 14 -+#define NBG460N_GPIO_LED_WLAN 15 -+ -+/* Buttons */ -+#define NBG460N_GPIO_BTN_WPS 12 -+#define NBG460N_GPIO_BTN_RESET 21 -+ -+#define NBG460N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define NBG460N_KEYS_DEBOUNCE_INTERVAL (3 * NBG460N_KEYS_POLL_INTERVAL) ++#define EAP7660D_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define EAP7660D_KEYS_DEBOUNCE_INTERVAL (3 * EAP7660D_KEYS_POLL_INTERVAL) + -+/* RTC chip PCF8563 I2C interface */ -+#define NBG460N_GPIO_PCF8563_SDA 8 -+#define NBG460N_GPIO_PCF8563_SCK 7 ++#define EAP7660D_GPIO_DS4 7 ++#define EAP7660D_GPIO_DS5 2 ++#define EAP7660D_GPIO_DS7 0 ++#define EAP7660D_GPIO_DS8 4 ++#define EAP7660D_GPIO_SW1 3 ++#define EAP7660D_GPIO_SW3 8 ++#define EAP7660D_PHYMASK BIT(20) ++#define EAP7660D_BOARDCONFIG 0x1F7F0000 ++#define EAP7660D_GBIC_MAC_OFFSET 0x1000 ++#define EAP7660D_WMAC0_MAC_OFFSET 0x1010 ++#define EAP7660D_WMAC1_MAC_OFFSET 0x1016 ++#define EAP7660D_WMAC0_CALDATA_OFFSET 0x2000 ++#define EAP7660D_WMAC1_CALDATA_OFFSET 0x3000 + -+/* Switch configuration I2C interface */ -+#define NBG460N_GPIO_RTL8366_SDA 16 -+#define NBG460N_GPIO_RTL8366_SCK 18 ++static struct ath5k_platform_data eap7660d_wmac0_data; ++static struct ath5k_platform_data eap7660d_wmac1_data; ++static char eap7660d_wmac0_mac[6]; ++static char eap7660d_wmac1_mac[6]; ++static u16 eap7660d_wmac0_eeprom[ATH5K_PLAT_EEP_MAX_WORDS]; ++static u16 eap7660d_wmac1_eeprom[ATH5K_PLAT_EEP_MAX_WORDS]; + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition nbg460n_partitions[] = { ++#ifdef CONFIG_PCI ++static struct ar71xx_pci_irq eap7660d_pci_irqs[] __initdata = { + { -+ .name = "Bootbase", -+ .offset = 0, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "U-Boot Config", -+ .offset = 0x010000, -+ .size = 0x030000, -+ }, { -+ .name = "U-Boot", -+ .offset = 0x040000, -+ .size = 0x030000, -+ }, { -+ .name = "linux", -+ .offset = 0x070000, -+ .size = 0x0e0000, -+ }, { -+ .name = "rootfs", -+ .offset = 0x150000, -+ .size = 0x2a0000, -+ }, { -+ .name = "CalibData", -+ .offset = 0x3f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, + }, { -+ .name = "firmware", -+ .offset = 0x070000, -+ .size = 0x380000, ++ .slot = 1, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV1, + } +}; -+#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data nbg460n_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = nbg460n_partitions, -+ .nr_parts = ARRAY_SIZE(nbg460n_partitions), -+#endif -+}; ++static int eap7660d_pci_plat_dev_init(struct pci_dev *dev) ++{ ++ switch (PCI_SLOT(dev->devfn)) { ++ case 17: ++ dev->dev.platform_data = &eap7660d_wmac0_data; ++ break; + -+static struct gpio_led nbg460n_leds_gpio[] __initdata = { -+ { -+ .name = "nbg460n:green:power", -+ .gpio = NBG460N_GPIO_LED_POWER, -+ .active_low = 0, -+ .default_trigger = "default-on", -+ }, { -+ .name = "nbg460n:green:wps", -+ .gpio = NBG460N_GPIO_LED_WPS, -+ .active_low = 0, -+ }, { -+ .name = "nbg460n:green:wlan", -+ .gpio = NBG460N_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, { -+ /* Not really for controlling the LED, -+ when set low the LED blinks uncontrollable */ -+ .name = "nbg460n:green:wan", -+ .gpio = NBG460N_GPIO_LED_WAN, -+ .active_low = 0, ++ case 18: ++ dev->dev.platform_data = &eap7660d_wmac1_data; ++ break; + } -+}; + -+static struct gpio_keys_button nbg460n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG460N_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG460N_GPIO_BTN_WPS, -+ .active_low = 1, ++ return 0; ++} ++ ++void __init eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0, ++ u8 *cal_data1, u8 *mac_addr1) ++{ ++ if (cal_data0 && *cal_data0 == 0xa55a) { ++ memcpy(eap7660d_wmac0_eeprom, cal_data0, ++ ATH5K_PLAT_EEP_MAX_WORDS); ++ eap7660d_wmac0_data.eeprom_data = eap7660d_wmac0_eeprom; + } -+}; + -+static struct i2c_gpio_platform_data nbg460n_i2c_device_platdata = { -+ .sda_pin = NBG460N_GPIO_PCF8563_SDA, -+ .scl_pin = NBG460N_GPIO_PCF8563_SCK, -+ .udelay = 10, -+}; ++ if (cal_data1 && *cal_data1 == 0xa55a) { ++ memcpy(eap7660d_wmac1_eeprom, cal_data1, ++ ATH5K_PLAT_EEP_MAX_WORDS); ++ eap7660d_wmac1_data.eeprom_data = eap7660d_wmac1_eeprom; ++ } + -+static struct platform_device nbg460n_i2c_device = { -+ .name = "i2c-gpio", -+ .id = -1, -+ .num_resources = 0, -+ .resource = NULL, -+ .dev = { -+ .platform_data = &nbg460n_i2c_device_platdata, -+ }, -+}; ++ if (mac_addr0) { ++ memcpy(eap7660d_wmac0_mac, mac_addr0, ++ sizeof(eap7660d_wmac0_mac)); ++ eap7660d_wmac0_data.macaddr = eap7660d_wmac0_mac; ++ } + -+static struct i2c_board_info nbg460n_i2c_devs[] __initdata = { -+ { -+ I2C_BOARD_INFO("pcf8563", 0x51), -+ }, -+}; ++ if (mac_addr1) { ++ memcpy(eap7660d_wmac1_mac, mac_addr1, ++ sizeof(eap7660d_wmac1_mac)); ++ eap7660d_wmac1_data.macaddr = eap7660d_wmac1_mac; ++ } + -+static void __devinit nbg460n_i2c_init(void) ++ ar71xx_pci_plat_dev_init = eap7660d_pci_plat_dev_init; ++ ar71xx_pci_init(ARRAY_SIZE(eap7660d_pci_irqs), eap7660d_pci_irqs); ++} ++#else ++static inline void eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0, ++ u8 *cal_data1, u8 *mac_addr1) +{ -+ /* The gpio interface */ -+ platform_device_register(&nbg460n_i2c_device); -+ /* I2C devices */ -+ i2c_register_board_info(0, nbg460n_i2c_devs, -+ ARRAY_SIZE(nbg460n_i2c_devs)); +} ++#endif /* CONFIG_PCI */ + -+ -+static struct rtl8366_platform_data nbg460n_rtl8366s_data = { -+ .gpio_sda = NBG460N_GPIO_RTL8366_SDA, -+ .gpio_sck = NBG460N_GPIO_RTL8366_SCK, ++static struct gpio_led eap7660d_leds_gpio[] __initdata = { ++ { ++ .name = "eap7660d:green:ds8", ++ .gpio = EAP7660D_GPIO_DS8, ++ .active_low = 0, ++ }, ++ { ++ .name = "eap7660d:green:ds5", ++ .gpio = EAP7660D_GPIO_DS5, ++ .active_low = 0, ++ }, ++ { ++ .name = "eap7660d:green:ds7", ++ .gpio = EAP7660D_GPIO_DS7, ++ .active_low = 0, ++ }, ++ { ++ .name = "eap7660d:green:ds4", ++ .gpio = EAP7660D_GPIO_DS4, ++ .active_low = 0, ++ } +}; + -+static struct platform_device nbg460n_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &nbg460n_rtl8366s_data, ++static struct gpio_keys_button eap7660d_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = EAP7660D_GPIO_SW1, ++ .active_low = 1, ++ }, ++ { ++ .desc = "wps", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = EAP7660D_GPIO_SW3, ++ .active_low = 1, + } +}; + -+static void __init nbg460n_setup(void) ++static void __init eap7660d_setup(void) +{ -+ /* end of bootloader sector contains mac address */ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fc0fff8); -+ /* last sector contains wlan calib data */ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* LAN Port */ -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_eth0_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.speed = SPEED_1000; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ u8 *boardconfig = (u8 *) KSEG1ADDR(EAP7660D_BOARDCONFIG); + -+ /* WAN Port */ -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); -+ ar71xx_eth1_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++ ar71xx_add_device_mdio(~EAP7660D_PHYMASK); + ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ++ boardconfig + EAP7660D_GBIC_MAC_OFFSET, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = EAP7660D_PHYMASK; + ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); -+ -+ /* register the switch phy */ -+ platform_device_register(&nbg460n_rtl8366s_device); -+ -+ /* register flash */ -+ ar71xx_add_device_m25p80(&nbg460n_flash_data); -+ -+ ar9xxx_add_device_wmac(eeprom, mac); -+ -+ /* register RTC chip */ -+ nbg460n_i2c_init(); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(nbg460n_leds_gpio), -+ nbg460n_leds_gpio); -+ -+ ar71xx_register_gpio_keys_polled(-1, NBG460N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(nbg460n_gpio_keys), -+ nbg460n_gpio_keys); -+} ++ ar71xx_add_device_m25p80(NULL); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(eap7660d_leds_gpio), ++ eap7660d_leds_gpio); ++ ar71xx_register_gpio_keys_polled(-1, EAP7660D_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(eap7660d_gpio_keys), ++ eap7660d_gpio_keys); ++ eap7660d_pci_init(boardconfig + EAP7660D_WMAC0_CALDATA_OFFSET, ++ boardconfig + EAP7660D_WMAC0_MAC_OFFSET, ++ boardconfig + EAP7660D_WMAC1_CALDATA_OFFSET, ++ boardconfig + EAP7660D_WMAC1_MAC_OFFSET); ++}; + -+MIPS_MACHINE(AR71XX_MACH_NBG460N, "NBG460N", "Zyxel NBG460N/550N/550NH", -+ nbg460n_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c linux-2.6.39/arch/mips/ar71xx/mach-pb42.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-pb42.c 2011-08-24 02:41:55.537990605 +0200 -@@ -0,0 +1,74 @@ ++MIPS_MACHINE(AR71XX_MACH_EAP7660D, "EAP7660D", "Senao EAP7660D", ++ eap7660d_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ja76pf.c linux-2.6.39/arch/mips/ar71xx/mach-ja76pf.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ja76pf.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ja76pf.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,102 @@ +/* -+ * Atheros PB42 board support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. ++ * jjPlus JA76PF board support + */ + +#include ++#include ++#include ++#include + +#include "machtype.h" +#include "devices.h" @@ -5915,288 +5297,188 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c linux-2.6.39/arch/mips/ +#include "dev-gpio-buttons.h" +#include "dev-pb42-pci.h" +#include "dev-usb.h" ++#include "dev-leds-gpio.h" + -+#define PB42_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define PB42_KEYS_DEBOUNCE_INTERVAL (3 * PB42_KEYS_POLL_INTERVAL) ++#define JA76PF_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define JA76PF_KEYS_DEBOUNCE_INTERVAL (3 * JA76PF_KEYS_POLL_INTERVAL) + -+#define PB42_GPIO_BTN_SW4 8 -+#define PB42_GPIO_BTN_SW5 3 ++#define JA76PF_GPIO_I2C_SCL 0 ++#define JA76PF_GPIO_I2C_SDA 1 ++#define JA76PF_GPIO_LED_1 5 ++#define JA76PF_GPIO_LED_2 4 ++#define JA76PF_GPIO_LED_3 3 ++#define JA76PF_GPIO_BTN_RESET 11 + -+static struct gpio_keys_button pb42_gpio_keys[] __initdata = { ++static struct gpio_led ja76pf_leds_gpio[] __initdata = { + { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PB42_GPIO_BTN_SW4, ++ .name = "ja76pf:green:led1", ++ .gpio = JA76PF_GPIO_LED_1, + .active_low = 1, + }, { -+ .desc = "sw5", ++ .name = "ja76pf:green:led2", ++ .gpio = JA76PF_GPIO_LED_2, ++ .active_low = 1, ++ }, { ++ .name = "ja76pf:green:led3", ++ .gpio = JA76PF_GPIO_LED_3, ++ .active_low = 1, ++ } ++}; ++ ++static struct gpio_keys_button ja76pf_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", + .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PB42_GPIO_BTN_SW5, ++ .code = KEY_RESTART, ++ .debounce_interval = JA76PF_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = JA76PF_GPIO_BTN_RESET, + .active_low = 1, + } +}; + -+#define PB42_WAN_PHYMASK BIT(20) -+#define PB42_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19)) -+#define PB42_MDIO_PHYMASK (PB42_LAN_PHYMASK | PB42_WAN_PHYMASK) ++static struct i2c_gpio_platform_data ja76pf_i2c_gpio_data = { ++ .sda_pin = JA76PF_GPIO_I2C_SDA, ++ .scl_pin = JA76PF_GPIO_I2C_SCL, ++}; + -+static void __init pb42_init(void) ++static struct platform_device ja76pf_i2c_gpio_device = { ++ .name = "i2c-gpio", ++ .id = 0, ++ .dev = { ++ .platform_data = &ja76pf_i2c_gpio_data, ++ } ++}; ++ ++#define JA76PF_WAN_PHYMASK (1 << 4) ++#define JA76PF_LAN_PHYMASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 < 3)) ++#define JA76PF_MDIO_PHYMASK (JA76PF_LAN_PHYMASK | JA76PF_WAN_PHYMASK) ++ ++static void __init ja76pf_init(void) +{ + ar71xx_add_device_m25p80(NULL); + -+ ar71xx_add_device_mdio(~PB42_MDIO_PHYMASK); ++ ar71xx_add_device_mdio(~JA76PF_MDIO_PHYMASK); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = PB42_WAN_PHYMASK; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = JA76PF_LAN_PHYMASK; + -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1); -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_100; ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = JA76PF_WAN_PHYMASK; ++ ar71xx_eth1_data.speed = SPEED_1000; + ar71xx_eth1_data.duplex = DUPLEX_FULL; + + ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_register_gpio_keys_polled(-1, PB42_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(pb42_gpio_keys), -+ pb42_gpio_keys); ++ platform_device_register(&ja76pf_i2c_gpio_device); + ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ja76pf_leds_gpio), ++ ja76pf_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, JA76PF_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ja76pf_gpio_keys), ++ ja76pf_gpio_keys); ++ ++ ar71xx_add_device_usb(); + pb42_pci_init(); +} + -+MIPS_MACHINE(AR71XX_MACH_PB42, "PB42", "Atheros PB42", pb42_init); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c linux-2.6.39/arch/mips/ar71xx/mach-pb44.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-pb44.c 2011-08-24 02:41:55.537990605 +0200 -@@ -0,0 +1,213 @@ ++MIPS_MACHINE(AR71XX_MACH_JA76PF, "JA76PF", "jjPlus JA76PF", ja76pf_init); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-jwap003.c linux-2.6.39/arch/mips/ar71xx/mach-jwap003.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-jwap003.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-jwap003.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,83 @@ +/* -+ * Atheros PB44 board support -+ * -+ * Copyright (C) 2009 Gabor Juhos ++ * jjPlus JWAP003 board support + * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#include +#include +#include -+#include -+ -+#include ++#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-pb42-pci.h" ++#include "dev-m25p80.h" +#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" ++#include "dev-pb42-pci.h" +#include "dev-usb.h" + -+#define PB44_PCF8757_VSC7395_CS 0 -+#define PB44_PCF8757_STEREO_CS 1 -+#define PB44_PCF8757_SLIC_CS0 2 -+#define PB44_PCF8757_SLIC_TEST 3 -+#define PB44_PCF8757_SLIC_INT0 4 -+#define PB44_PCF8757_SLIC_INT1 5 -+#define PB44_PCF8757_SW_RESET 6 -+#define PB44_PCF8757_SW_JUMP 8 -+#define PB44_PCF8757_LED_JUMP1 9 -+#define PB44_PCF8757_LED_JUMP2 10 -+#define PB44_PCF8757_TP24 11 -+#define PB44_PCF8757_TP25 12 -+#define PB44_PCF8757_TP26 13 -+#define PB44_PCF8757_TP27 14 -+#define PB44_PCF8757_TP28 15 -+ -+#define PB44_GPIO_I2C_SCL 0 -+#define PB44_GPIO_I2C_SDA 1 -+ -+#define PB44_GPIO_EXP_BASE 16 -+#define PB44_GPIO_VSC7395_CS (PB44_GPIO_EXP_BASE + PB44_PCF8757_VSC7395_CS) -+#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_RESET) -+#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_JUMP) -+#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP1) -+#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP2) -+ -+#define PB44_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL) -+ -+static struct i2c_gpio_platform_data pb44_i2c_gpio_data = { -+ .sda_pin = PB44_GPIO_I2C_SDA, -+ .scl_pin = PB44_GPIO_I2C_SCL, -+}; -+ -+static struct platform_device pb44_i2c_gpio_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &pb44_i2c_gpio_data, -+ } -+}; -+ -+static struct pcf857x_platform_data pb44_pcf857x_data = { -+ .gpio_base = PB44_GPIO_EXP_BASE, -+}; -+ -+static struct i2c_board_info pb44_i2c_board_info[] __initdata = { -+ { -+ I2C_BOARD_INFO("pcf8575", 0x20), -+ .platform_data = &pb44_pcf857x_data, -+ }, -+}; ++#define JWAP003_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define JWAP003_KEYS_DEBOUNCE_INTERVAL (3 * JWAP003_KEYS_POLL_INTERVAL) + -+static struct gpio_led pb44_leds_gpio[] __initdata = { -+ { -+ .name = "pb44:amber:jump1", -+ .gpio = PB44_GPIO_LED_JUMP1, -+ .active_low = 1, -+ }, { -+ .name = "pb44:green:jump2", -+ .gpio = PB44_GPIO_LED_JUMP2, -+ .active_low = 1, -+ }, -+}; ++#define JWAP003_GPIO_WPS 11 ++#define JWAP003_GPIO_I2C_SCL 0 ++#define JWAP003_GPIO_I2C_SDA 1 + -+static struct gpio_keys_button pb44_gpio_keys[] __initdata = { ++static struct gpio_keys_button jwap003_gpio_keys[] __initdata = { + { -+ .desc = "soft_reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PB44_GPIO_SW_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "jumpstart", ++ .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PB44_GPIO_SW_JUMP, ++ .debounce_interval = JWAP003_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = JWAP003_GPIO_WPS, + .active_low = 1, + } +}; + -+static void pb44_vsc7395_reset(void) -+{ -+ ar71xx_device_stop(RESET_MODULE_GE1_PHY); -+ udelay(10); -+ ar71xx_device_start(RESET_MODULE_GE1_PHY); -+ mdelay(50); -+} -+ -+static struct vsc7385_platform_data pb44_vsc7395_data = { -+ .reset = pb44_vsc7395_reset, -+ .ucode_name = "vsc7395_ucode_pb44.bin", -+ .mac_cfg = { -+ .tx_ipg = 6, -+ .bit2 = 1, -+ .clk_sel = 0, -+ }, -+}; -+ -+static struct spi_board_info pb44_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ }, { -+ .bus_num = 0, -+ .chip_select = 1, -+ .max_speed_hz = 25000000, -+ .modalias = "spi-vsc7385", -+ .platform_data = &pb44_vsc7395_data, -+ .controller_data = (void *) PB44_GPIO_VSC7395_CS, -+ }, -+}; -+ -+static struct resource pb44_spi_resources[] = { -+ [0] = { -+ .start = AR71XX_SPI_BASE, -+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+static struct ar71xx_spi_platform_data pb44_spi_data = { -+ .bus_num = 0, -+ .num_chipselect = 2, ++static struct i2c_gpio_platform_data jwap003_i2c_gpio_data = { ++ .sda_pin = JWAP003_GPIO_I2C_SDA, ++ .scl_pin = JWAP003_GPIO_I2C_SCL, +}; + -+static struct platform_device pb44_spi_device = { -+ .name = "pb44-spi", -+ .id = -1, -+ .resource = pb44_spi_resources, -+ .num_resources = ARRAY_SIZE(pb44_spi_resources), ++static struct platform_device jwap003_i2c_gpio_device = { ++ .name = "i2c-gpio", ++ .id = 0, + .dev = { -+ .platform_data = &pb44_spi_data, -+ }, ++ .platform_data = &jwap003_i2c_gpio_data, ++ } +}; + -+#define PB44_WAN_PHYMASK BIT(0) -+#define PB44_LAN_PHYMASK 0 -+#define PB44_MDIO_PHYMASK (PB44_LAN_PHYMASK | PB44_WAN_PHYMASK) ++#define JWAP003_WAN_PHYMASK BIT(0) ++#define JWAP003_LAN_PHYMASK BIT(4) + -+static void __init pb44_init(void) ++static void __init jwap003_init(void) +{ -+ ar71xx_add_device_mdio(~PB44_MDIO_PHYMASK); ++ ar71xx_add_device_m25p80(NULL); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.phy_mask = PB44_WAN_PHYMASK; ++ ar71xx_add_device_mdio(0x0); + -+ ar71xx_add_device_eth(0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.phy_mask = JWAP003_WAN_PHYMASK; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.has_ar8216 = 1; + -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1); -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = JWAP003_LAN_PHYMASK; ++ ar71xx_eth1_data.speed = SPEED_100; + ar71xx_eth1_data.duplex = DUPLEX_FULL; -+ ar71xx_eth1_pll_data.pll_1000 = 0x110000; + ++ ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_usb(); -+ -+ pb42_pci_init(); -+ -+ i2c_register_board_info(0, pb44_i2c_board_info, -+ ARRAY_SIZE(pb44_i2c_board_info)); -+ -+ platform_device_register(&pb44_i2c_gpio_device); ++ platform_device_register(&jwap003_i2c_gpio_device); + -+ spi_register_board_info(pb44_spi_info, ARRAY_SIZE(pb44_spi_info)); -+ platform_device_register(&pb44_spi_device); ++ ar71xx_add_device_usb(); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio), -+ pb44_leds_gpio); ++ ar71xx_register_gpio_keys_polled(-1, JWAP003_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(jwap003_gpio_keys), ++ jwap003_gpio_keys); + -+ ar71xx_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(pb44_gpio_keys), -+ pb44_gpio_keys); ++ pb42_pci_init(); +} + -+MIPS_MACHINE(AR71XX_MACH_PB44, "PB44", "Atheros PB44", pb44_init); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c linux-2.6.39/arch/mips/ar71xx/mach-pb92.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-pb92.c 2011-08-24 02:41:55.567991163 +0200 -@@ -0,0 +1,105 @@ ++MIPS_MACHINE(AR71XX_MACH_JWAP003, "JWAP003", "jjPlus JWAP003", jwap003_init); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w04nu.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w04nu.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,166 @@ +/* -+ * Atheros PB92 board support ++ * Planex MZK-W04NU board support + * -+ * Copyright (C) 2010 Felix Fietkau -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -6205,17 +5487,33 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c linux-2.6.39/arch/mips/ + +#include +#include ++ +#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" -+#include "dev-pb9x-pci.h" ++#include "dev-leds-gpio.h" ++#include "dev-m25p80.h" +#include "dev-usb.h" + ++#define MZK_W04NU_GPIO_LED_USB 0 ++#define MZK_W04NU_GPIO_LED_STATUS 1 ++#define MZK_W04NU_GPIO_LED_WPS 3 ++#define MZK_W04NU_GPIO_LED_WLAN 6 ++#define MZK_W04NU_GPIO_LED_AP 15 ++#define MZK_W04NU_GPIO_LED_ROUTER 16 ++ ++#define MZK_W04NU_GPIO_BTN_APROUTER 5 ++#define MZK_W04NU_GPIO_BTN_WPS 12 ++#define MZK_W04NU_GPIO_BTN_RESET 21 ++ ++#define MZK_W04NU_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define MZK_W04NU_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W04NU_KEYS_POLL_INTERVAL) ++ +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition pb92_partitions[] = { ++static struct mtd_partition mzk_w04nu_partitions[] = { + { + .name = "u-boot", + .offset = 0, @@ -6226,84 +5524,131 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c linux-2.6.39/arch/mips/ + .offset = 0x040000, + .size = 0x010000, + }, { -+ .name = "rootfs", ++ .name = "kernel", + .offset = 0x050000, -+ .size = 0x2b0000, ++ .size = 0x160000, + }, { -+ .name = "uImage", -+ .offset = 0x300000, -+ .size = 0x0e0000, ++ .name = "rootfs", ++ .offset = 0x1b0000, ++ .size = 0x630000, + }, { -+ .name = "ART", -+ .offset = 0x3e0000, ++ .name = "art", ++ .offset = 0x7e0000, + .size = 0x020000, + .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x050000, ++ .size = 0x790000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data pb92_flash_data = { ++static struct flash_platform_data mzk_w04nu_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = pb92_partitions, -+ .nr_parts = ARRAY_SIZE(pb92_partitions), ++ .parts = mzk_w04nu_partitions, ++ .nr_parts = ARRAY_SIZE(mzk_w04nu_partitions), +#endif +}; + -+#define PB92_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define PB92_KEYS_DEBOUNCE_INTERVAL (3 * PB92_KEYS_POLL_INTERVAL) -+ -+#define PB92_GPIO_BTN_SW4 8 -+#define PB92_GPIO_BTN_SW5 3 ++static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = { ++ { ++ .name = "mzk-w04nu:green:status", ++ .gpio = MZK_W04NU_GPIO_LED_STATUS, ++ .active_low = 1, ++ }, { ++ .name = "mzk-w04nu:blue:wps", ++ .gpio = MZK_W04NU_GPIO_LED_WPS, ++ .active_low = 1, ++ }, { ++ .name = "mzk-w04nu:green:wlan", ++ .gpio = MZK_W04NU_GPIO_LED_WLAN, ++ .active_low = 1, ++ }, { ++ .name = "mzk-w04nu:green:usb", ++ .gpio = MZK_W04NU_GPIO_LED_USB, ++ .active_low = 1, ++ }, { ++ .name = "mzk-w04nu:green:ap", ++ .gpio = MZK_W04NU_GPIO_LED_AP, ++ .active_low = 1, ++ }, { ++ .name = "mzk-w04nu:green:router", ++ .gpio = MZK_W04NU_GPIO_LED_ROUTER, ++ .active_low = 1, ++ } ++}; + -+static struct gpio_keys_button pb92_gpio_keys[] __initdata = { ++static struct gpio_keys_button mzk_w04nu_gpio_keys[] __initdata = { + { -+ .desc = "sw4", ++ .desc = "reset", + .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = PB92_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PB92_GPIO_BTN_SW4, ++ .code = KEY_RESTART, ++ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W04NU_GPIO_BTN_RESET, + .active_low = 1, + }, { -+ .desc = "sw5", ++ .desc = "wps", + .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = PB92_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PB92_GPIO_BTN_SW5, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W04NU_GPIO_BTN_WPS, + .active_low = 1, ++ }, { ++ .desc = "aprouter", ++ .type = EV_KEY, ++ .code = BTN_2, ++ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W04NU_GPIO_BTN_APROUTER, ++ .active_low = 0, + } +}; + -+static void __init pb92_init(void) ++#define MZK_W04NU_WAN_PHYMASK BIT(4) ++#define MZK_W04NU_MDIO_MASK (~MZK_W04NU_WAN_PHYMASK) ++ ++static void __init mzk_w04nu_setup(void) +{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_add_device_m25p80(&pb92_flash_data); ++ ar71xx_add_device_mdio(MZK_W04NU_MDIO_MASK); + -+ ar71xx_add_device_mdio(~BIT(0)); -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.phy_mask = BIT(0); ++ ar71xx_eth0_data.has_ar8216 = 1; ++ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = MZK_W04NU_WAN_PHYMASK; + + ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ ar71xx_register_gpio_keys_polled(-1, PB92_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(pb92_gpio_keys), -+ pb92_gpio_keys); ++ ar71xx_add_device_m25p80(&mzk_w04nu_flash_data); + -+ pb9x_pci_init(); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio), ++ mzk_w04nu_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, MZK_W04NU_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(mzk_w04nu_gpio_keys), ++ mzk_w04nu_gpio_keys); ++ ar71xx_add_device_usb(); ++ ++ ar9xxx_add_device_wmac(eeprom, NULL); +} + -+MIPS_MACHINE(AR71XX_MACH_PB92, "PB92", "Atheros PB92", pb92_init); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c 2011-08-24 02:41:55.567991163 +0200 -@@ -0,0 +1,344 @@ ++MIPS_MACHINE(AR71XX_MACH_MZK_W04NU, "MZK-W04NU", "Planex MZK-W04NU", ++ mzk_w04nu_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-mzk-w300nh.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-mzk-w300nh.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,159 @@ +/* -+ * MikroTik RouterBOARD 4xx series support ++ * Planex MZK-W300NH board support + * -+ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it @@ -6311,1359 +5656,1260 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c linux-2.6.39/arch/mips + * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+#include -+#include -+#include +#include +#include + +#include -+#include -+#include + +#include "machtype.h" +#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "dev-usb.h" + -+#define RB4XX_GPIO_USER_LED 4 -+#define RB4XX_GPIO_RESET_SWITCH 7 ++#define MZK_W300NH_GPIO_LED_STATUS 1 ++#define MZK_W300NH_GPIO_LED_WPS 3 ++#define MZK_W300NH_GPIO_LED_WLAN 6 ++#define MZK_W300NH_GPIO_LED_AP 15 ++#define MZK_W300NH_GPIO_LED_ROUTER 16 + -+#define RB4XX_GPIO_CPLD_BASE 32 -+#define RB4XX_GPIO_CPLD_LED1 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED1) -+#define RB4XX_GPIO_CPLD_LED2 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED2) -+#define RB4XX_GPIO_CPLD_LED3 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED3) -+#define RB4XX_GPIO_CPLD_LED4 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED4) -+#define RB4XX_GPIO_CPLD_LED5 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED5) ++#define MZK_W300NH_GPIO_BTN_APROUTER 5 ++#define MZK_W300NH_GPIO_BTN_WPS 12 ++#define MZK_W300NH_GPIO_BTN_RESET 21 + -+#define RB4XX_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define RB4XX_KEYS_DEBOUNCE_INTERVAL (3 * RB4XX_KEYS_POLL_INTERVAL) ++#define MZK_W300NH_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define MZK_W300NH_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W300NH_KEYS_POLL_INTERVAL) + -+static struct gpio_led rb4xx_leds_gpio[] __initdata = { ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition mzk_w300nh_partitions[] = { + { -+ .name = "rb4xx:yellow:user", -+ .gpio = RB4XX_GPIO_USER_LED, -+ .active_low = 0, ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "rb4xx:green:led1", -+ .gpio = RB4XX_GPIO_CPLD_LED1, -+ .active_low = 1, ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, + }, { -+ .name = "rb4xx:green:led2", -+ .gpio = RB4XX_GPIO_CPLD_LED2, -+ .active_low = 1, ++ .name = "kernel", ++ .offset = 0x050000, ++ .size = 0x160000, + }, { -+ .name = "rb4xx:green:led3", -+ .gpio = RB4XX_GPIO_CPLD_LED3, -+ .active_low = 1, ++ .name = "rootfs", ++ .offset = 0x1b0000, ++ .size = 0x630000, + }, { -+ .name = "rb4xx:green:led4", -+ .gpio = RB4XX_GPIO_CPLD_LED4, -+ .active_low = 1, ++ .name = "art", ++ .offset = 0x7e0000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "rb4xx:green:led5", -+ .gpio = RB4XX_GPIO_CPLD_LED5, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button rb4xx_gpio_keys[] __initdata = { -+ { -+ .desc = "reset_switch", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = RB4XX_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = RB4XX_GPIO_RESET_SWITCH, -+ .active_low = 1, ++ .name = "firmware", ++ .offset = 0x050000, ++ .size = 0x790000, + } +}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct platform_device rb4xx_nand_device = { -+ .name = "rb4xx-nand", -+ .id = -1, ++static struct flash_platform_data mzk_w300nh_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = mzk_w300nh_partitions, ++ .nr_parts = ARRAY_SIZE(mzk_w300nh_partitions), ++#endif +}; + -+static struct ar71xx_pci_irq rb4xx_pci_irqs[] __initdata = { ++static struct gpio_led mzk_w300nh_leds_gpio[] __initdata = { + { -+ .slot = 0, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV2, ++ .name = "mzk-w300nh:green:status", ++ .gpio = MZK_W300NH_GPIO_LED_STATUS, ++ .active_low = 1, + }, { -+ .slot = 1, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV0, ++ .name = "mzk-w300nh:blue:wps", ++ .gpio = MZK_W300NH_GPIO_LED_WPS, ++ .active_low = 1, + }, { -+ .slot = 1, -+ .pin = 2, -+ .irq = AR71XX_PCI_IRQ_DEV1, ++ .name = "mzk-w300nh:green:wlan", ++ .gpio = MZK_W300NH_GPIO_LED_WLAN, ++ .active_low = 1, + }, { -+ .slot = 2, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV1, ++ .name = "mzk-w300nh:green:ap", ++ .gpio = MZK_W300NH_GPIO_LED_AP, ++ .active_low = 1, + }, { -+ .slot = 3, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV2, ++ .name = "mzk-w300nh:green:router", ++ .gpio = MZK_W300NH_GPIO_LED_ROUTER, ++ .active_low = 1, + } +}; + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition rb4xx_partitions[] = { ++static struct gpio_keys_button mzk_w300nh_gpio_keys[] __initdata = { + { -+ .name = "routerboot", -+ .offset = 0, -+ .size = 0x0b000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "hard_config", -+ .offset = 0x0b000, -+ .size = 0x01000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "bios", -+ .offset = 0x0d000, -+ .size = 0x02000, -+ .mask_flags = MTD_WRITEABLE, ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W300NH_GPIO_BTN_RESET, ++ .active_low = 1, + }, { -+ .name = "soft_config", -+ .offset = 0x0f000, -+ .size = 0x01000, -+ } -+}; -+#define rb4xx_num_partitions ARRAY_SIZE(rb4xx_partitions) -+#else /* CONFIG_MTD_PARTITIONS */ -+#define rb4xx_partitions NULL -+#define rb4xx_num_partitions 0 -+#endif /* CONFIG_MTD_PARTITIONS */ -+ -+static struct flash_platform_data rb4xx_flash_data = { -+ .type = "pm25lv512", -+ .parts = rb4xx_partitions, -+ .nr_parts = rb4xx_num_partitions, -+}; -+ -+static struct rb4xx_cpld_platform_data rb4xx_cpld_data = { -+ .gpio_base = RB4XX_GPIO_CPLD_BASE, -+}; -+ -+static struct mmc_spi_platform_data rb4xx_mmc_data = { -+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, -+}; -+ -+static struct spi_board_info rb4xx_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ .platform_data = &rb4xx_flash_data, ++ .desc = "wps", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W300NH_GPIO_BTN_WPS, ++ .active_low = 1, + }, { -+ .bus_num = 0, -+ .chip_select = 1, -+ .max_speed_hz = 25000000, -+ .modalias = "spi-rb4xx-cpld", -+ .platform_data = &rb4xx_cpld_data, -+ } -+}; -+ -+static struct spi_board_info rb4xx_microsd_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 2, -+ .max_speed_hz = 25000000, -+ .modalias = "mmc_spi", -+ .platform_data = &rb4xx_mmc_data, ++ .desc = "aprouter", ++ .type = EV_KEY, ++ .code = BTN_2, ++ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = MZK_W300NH_GPIO_BTN_APROUTER, ++ .active_low = 0, + } +}; + ++#define MZK_W300NH_WAN_PHYMASK BIT(4) ++#define MZK_W300NH_MDIO_MASK (~MZK_W300NH_WAN_PHYMASK) + -+static struct resource rb4xx_spi_resources[] = { -+ { -+ .start = AR71XX_SPI_BASE, -+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+static struct platform_device rb4xx_spi_device = { -+ .name = "rb4xx-spi", -+ .id = -1, -+ .resource = rb4xx_spi_resources, -+ .num_resources = ARRAY_SIZE(rb4xx_spi_resources), -+}; -+ -+static void __init rb4xx_generic_setup(void) ++static void __init mzk_w300nh_setup(void) +{ -+ ar71xx_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN | -+ AR71XX_GPIO_FUNC_SPI_CS2_EN); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio), -+ rb4xx_leds_gpio); -+ -+ ar71xx_register_gpio_keys_polled(-1, RB4XX_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(rb4xx_gpio_keys), -+ rb4xx_gpio_keys); -+ -+ spi_register_board_info(rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info)); -+ platform_device_register(&rb4xx_spi_device); -+ platform_device_register(&rb4xx_nand_device); -+} ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+static void __init rb411_setup(void) -+{ -+ rb4xx_generic_setup(); -+ spi_register_board_info(rb4xx_microsd_info, -+ ARRAY_SIZE(rb4xx_microsd_info)); ++ ar71xx_add_device_mdio(MZK_W300NH_MDIO_MASK); + -+ ar71xx_add_device_mdio(0xfffffffc); ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.has_ar8216 = 1; + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = 0x00000003; ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = MZK_W300NH_WAN_PHYMASK; + + ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); -+} ++ ar71xx_add_device_m25p80(&mzk_w300nh_flash_data); + -+MIPS_MACHINE(AR71XX_MACH_RB_411, "411", "MikroTik RouterBOARD 411/A/AH", -+ rb411_setup); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w300nh_leds_gpio), ++ mzk_w300nh_leds_gpio); + -+static void __init rb411u_setup(void) -+{ -+ rb411_setup(); -+ ar71xx_add_device_usb(); ++ ar71xx_register_gpio_keys_polled(-1, MZK_W300NH_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(mzk_w300nh_gpio_keys), ++ mzk_w300nh_gpio_keys); ++ ar9xxx_add_device_wmac(eeprom, NULL); +} + -+MIPS_MACHINE(AR71XX_MACH_RB_411U, "411U", "MikroTik RouterBOARD 411U", -+ rb411u_setup); ++MIPS_MACHINE(AR71XX_MACH_MZK_W300NH, "MZK-W300NH", "Planex MZK-W300NH", ++ mzk_w300nh_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-nbg460n.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-nbg460n.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,225 @@ ++/* ++ * Zyxel NBG 460N/550N/550NH board support ++ * ++ * Copyright (C) 2010 Michael Kurz ++ * ++ * based on mach-tl-wr1043nd.c ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+#define RB433_LAN_PHYMASK BIT(0) -+#define RB433_WAN_PHYMASK BIT(4) -+#define RB433_MDIO_PHYMASK (RB433_LAN_PHYMASK | RB433_WAN_PHYMASK) ++#include ++#include ++#include ++#include ++#include + -+static void __init rb433_setup(void) -+{ -+ rb4xx_generic_setup(); -+ spi_register_board_info(rb4xx_microsd_info, -+ ARRAY_SIZE(rb4xx_microsd_info)); ++#include ++#include ++#include + -+ ar71xx_add_device_mdio(~RB433_MDIO_PHYMASK); ++#include + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 1); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = RB433_LAN_PHYMASK; ++#include "machtype.h" ++#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" + -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 0); -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = RB433_WAN_PHYMASK; ++/* LEDs */ ++#define NBG460N_GPIO_LED_WPS 3 ++#define NBG460N_GPIO_LED_WAN 6 ++#define NBG460N_GPIO_LED_POWER 14 ++#define NBG460N_GPIO_LED_WLAN 15 + -+ ar71xx_add_device_eth(1); -+ ar71xx_add_device_eth(0); ++/* Buttons */ ++#define NBG460N_GPIO_BTN_WPS 12 ++#define NBG460N_GPIO_BTN_RESET 21 + -+ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); -+} ++#define NBG460N_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define NBG460N_KEYS_DEBOUNCE_INTERVAL (3 * NBG460N_KEYS_POLL_INTERVAL) + -+MIPS_MACHINE(AR71XX_MACH_RB_433, "433", "MikroTik RouterBOARD 433/AH", -+ rb433_setup); ++/* RTC chip PCF8563 I2C interface */ ++#define NBG460N_GPIO_PCF8563_SDA 8 ++#define NBG460N_GPIO_PCF8563_SCK 7 + -+static void __init rb433u_setup(void) -+{ -+ rb433_setup(); -+ ar71xx_add_device_usb(); -+} ++/* Switch configuration I2C interface */ ++#define NBG460N_GPIO_RTL8366_SDA 16 ++#define NBG460N_GPIO_RTL8366_SCK 18 + -+MIPS_MACHINE(AR71XX_MACH_RB_433U, "433U", "MikroTik RouterBOARD 433UAH", -+ rb433u_setup); ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition nbg460n_partitions[] = { ++ { ++ .name = "Bootbase", ++ .offset = 0, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "U-Boot Config", ++ .offset = 0x010000, ++ .size = 0x030000, ++ }, { ++ .name = "U-Boot", ++ .offset = 0x040000, ++ .size = 0x030000, ++ }, { ++ .name = "linux", ++ .offset = 0x070000, ++ .size = 0x0e0000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x150000, ++ .size = 0x2a0000, ++ }, { ++ .name = "CalibData", ++ .offset = 0x3f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x070000, ++ .size = 0x380000, ++ } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+#define RB450_LAN_PHYMASK BIT(0) -+#define RB450_WAN_PHYMASK BIT(4) -+#define RB450_MDIO_PHYMASK (RB450_LAN_PHYMASK | RB450_WAN_PHYMASK) ++static struct flash_platform_data nbg460n_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = nbg460n_partitions, ++ .nr_parts = ARRAY_SIZE(nbg460n_partitions), ++#endif ++}; + -+static void __init rb450_generic_setup(int gige) -+{ -+ rb4xx_generic_setup(); -+ ar71xx_add_device_mdio(~RB450_MDIO_PHYMASK); ++static struct gpio_led nbg460n_leds_gpio[] __initdata = { ++ { ++ .name = "nbg460n:green:power", ++ .gpio = NBG460N_GPIO_LED_POWER, ++ .active_low = 0, ++ .default_trigger = "default-on", ++ }, { ++ .name = "nbg460n:green:wps", ++ .gpio = NBG460N_GPIO_LED_WPS, ++ .active_low = 0, ++ }, { ++ .name = "nbg460n:green:wlan", ++ .gpio = NBG460N_GPIO_LED_WLAN, ++ .active_low = 0, ++ }, { ++ /* Not really for controlling the LED, ++ when set low the LED blinks uncontrollable */ ++ .name = "nbg460n:green:wan", ++ .gpio = NBG460N_GPIO_LED_WAN, ++ .active_low = 0, ++ } ++}; + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 1); -+ ar71xx_eth0_data.phy_if_mode = (gige) ? -+ PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = RB450_LAN_PHYMASK; ++static struct gpio_keys_button nbg460n_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = NBG460N_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "wps", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = NBG460N_GPIO_BTN_WPS, ++ .active_low = 1, ++ } ++}; + -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 0); -+ ar71xx_eth1_data.phy_if_mode = (gige) ? -+ PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = RB450_WAN_PHYMASK; ++static struct i2c_gpio_platform_data nbg460n_i2c_device_platdata = { ++ .sda_pin = NBG460N_GPIO_PCF8563_SDA, ++ .scl_pin = NBG460N_GPIO_PCF8563_SCK, ++ .udelay = 10, ++}; + -+ ar71xx_add_device_eth(1); -+ ar71xx_add_device_eth(0); -+} ++static struct platform_device nbg460n_i2c_device = { ++ .name = "i2c-gpio", ++ .id = -1, ++ .num_resources = 0, ++ .resource = NULL, ++ .dev = { ++ .platform_data = &nbg460n_i2c_device_platdata, ++ }, ++}; + -+static void __init rb450_setup(void) ++static struct i2c_board_info nbg460n_i2c_devs[] __initdata = { ++ { ++ I2C_BOARD_INFO("pcf8563", 0x51), ++ }, ++}; ++ ++static void __devinit nbg460n_i2c_init(void) +{ -+ rb450_generic_setup(0); ++ /* The gpio interface */ ++ platform_device_register(&nbg460n_i2c_device); ++ /* I2C devices */ ++ i2c_register_board_info(0, nbg460n_i2c_devs, ++ ARRAY_SIZE(nbg460n_i2c_devs)); +} + -+MIPS_MACHINE(AR71XX_MACH_RB_450, "450", "MikroTik RouterBOARD 450", -+ rb450_setup); + -+static void __init rb450g_setup(void) -+{ -+ rb450_generic_setup(1); -+ spi_register_board_info(rb4xx_microsd_info, -+ ARRAY_SIZE(rb4xx_microsd_info)); -+} ++static struct rtl8366_platform_data nbg460n_rtl8366s_data = { ++ .gpio_sda = NBG460N_GPIO_RTL8366_SDA, ++ .gpio_sck = NBG460N_GPIO_RTL8366_SCK, ++}; + -+MIPS_MACHINE(AR71XX_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G", -+ rb450g_setup); ++static struct platform_device nbg460n_rtl8366s_device = { ++ .name = RTL8366S_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &nbg460n_rtl8366s_data, ++ } ++}; + -+static void __init rb493_setup(void) ++static void __init nbg460n_setup(void) +{ -+ rb4xx_generic_setup(); -+ -+ ar71xx_add_device_mdio(0x3fffff00); ++ /* end of bootloader sector contains mac address */ ++ u8 *mac = (u8 *) KSEG1ADDR(0x1fc0fff8); ++ /* last sector contains wlan calib data */ ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.speed = SPEED_100; ++ /* LAN Port */ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_eth0_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.speed = SPEED_1000; + ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1); -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x00000001; ++ /* WAN Port */ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ ar71xx_eth1_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = 0x10; + + ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); ++ /* register the switch phy */ ++ platform_device_register(&nbg460n_rtl8366s_device); ++ ++ /* register flash */ ++ ar71xx_add_device_m25p80(&nbg460n_flash_data); ++ ++ ar9xxx_add_device_wmac(eeprom, mac); ++ ++ /* register RTC chip */ ++ nbg460n_i2c_init(); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(nbg460n_leds_gpio), ++ nbg460n_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, NBG460N_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(nbg460n_gpio_keys), ++ nbg460n_gpio_keys); +} + -+MIPS_MACHINE(AR71XX_MACH_RB_493, "493", "MikroTik RouterBOARD 493/AH", -+ rb493_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c linux-2.6.39/arch/mips/ar71xx/mach-rb750.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-rb750.c 2011-08-24 02:41:55.567991163 +0200 -@@ -0,0 +1,144 @@ ++MIPS_MACHINE(AR71XX_MACH_NBG460N, "NBG460N", "Zyxel NBG460N/550N/550NH", ++ nbg460n_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c linux-2.6.39/arch/mips/ar71xx/mach-pb42.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb42.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-pb42.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,74 @@ +/* -+ * MikroTik RouterBOARD 750 support ++ * Atheros PB42 board support + * -+ * Copyright (C) 2010 Gabor Juhos ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include +#include -+#include + +#include "machtype.h" +#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-gpio-buttons.h" ++#include "dev-pb42-pci.h" ++#include "dev-usb.h" + -+static struct rb750_led_data rb750_leds[] = { ++#define PB42_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define PB42_KEYS_DEBOUNCE_INTERVAL (3 * PB42_KEYS_POLL_INTERVAL) ++ ++#define PB42_GPIO_BTN_SW4 8 ++#define PB42_GPIO_BTN_SW5 3 ++ ++static struct gpio_keys_button pb42_gpio_keys[] __initdata = { + { -+ .name = "rb750:green:act", -+ .mask = RB750_LED_ACT, -+ .active_low = 1, -+ }, { -+ .name = "rb750:green:port1", -+ .mask = RB750_LED_PORT5, -+ .active_low = 1, -+ }, { -+ .name = "rb750:green:port2", -+ .mask = RB750_LED_PORT4, -+ .active_low = 1, -+ }, { -+ .name = "rb750:green:port3", -+ .mask = RB750_LED_PORT3, -+ .active_low = 1, -+ }, { -+ .name = "rb750:green:port4", -+ .mask = RB750_LED_PORT2, ++ .desc = "sw4", ++ .type = EV_KEY, ++ .code = BTN_0, ++ .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB42_GPIO_BTN_SW4, + .active_low = 1, + }, { -+ .name = "rb750:green:port5", -+ .mask = RB750_LED_PORT1, ++ .desc = "sw5", ++ .type = EV_KEY, ++ .code = BTN_1, ++ .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB42_GPIO_BTN_SW5, + .active_low = 1, + } +}; + -+static struct rb750_led_platform_data rb750_leds_data = { -+ .num_leds = ARRAY_SIZE(rb750_leds), -+ .leds = rb750_leds, -+}; -+ -+static struct platform_device rb750_leds_device = { -+ .name = "leds-rb750", -+ .dev = { -+ .platform_data = &rb750_leds_data, -+ } -+}; -+ -+static struct platform_device rb750_nand_device = { -+ .name = "rb750-nand", -+ .id = -1, -+}; ++#define PB42_WAN_PHYMASK BIT(20) ++#define PB42_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19)) ++#define PB42_MDIO_PHYMASK (PB42_LAN_PHYMASK | PB42_WAN_PHYMASK) + -+int rb750_latch_change(u32 mask_clr, u32 mask_set) ++static void __init pb42_init(void) +{ -+ static DEFINE_SPINLOCK(lock); -+ static u32 latch_set = RB750_LED_BITS | RB750_LVC573_LE; -+ static u32 latch_oe; -+ static u32 latch_clr; -+ unsigned long flags; -+ u32 t; -+ int ret = 0; -+ -+ spin_lock_irqsave(&lock, flags); ++ ar71xx_add_device_m25p80(NULL); + -+ if ((mask_clr & BIT(31)) != 0 && -+ (latch_set & RB750_LVC573_LE) == 0) { -+ goto unlock; -+ } ++ ar71xx_add_device_mdio(~PB42_MDIO_PHYMASK); + -+ latch_set = (latch_set | mask_set) & ~mask_clr; -+ latch_clr = (latch_clr | mask_clr) & ~mask_set; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = PB42_WAN_PHYMASK; + -+ if (latch_oe == 0) -+ latch_oe = __raw_readl(ar71xx_gpio_base + GPIO_REG_OE); -+ -+ if (likely(latch_set & RB750_LVC573_LE)) { -+ void __iomem *base = ar71xx_gpio_base; -+ -+ t = __raw_readl(base + GPIO_REG_OE); -+ t |= mask_clr | latch_oe | mask_set; -+ -+ __raw_writel(t, base + GPIO_REG_OE); -+ __raw_writel(latch_clr, base + GPIO_REG_CLEAR); -+ __raw_writel(latch_set, base + GPIO_REG_SET); -+ } else if (mask_clr & RB750_LVC573_LE) { -+ void __iomem *base = ar71xx_gpio_base; -+ -+ latch_oe = __raw_readl(base + GPIO_REG_OE); -+ __raw_writel(RB750_LVC573_LE, base + GPIO_REG_CLEAR); -+ /* flush write */ -+ __raw_readl(base + GPIO_REG_CLEAR); -+ } -+ -+ ret = 1; -+ -+unlock: -+ spin_unlock_irqrestore(&lock, flags); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(rb750_latch_change); -+ -+static void __init rb750_setup(void) -+{ -+ ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); + ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1); -+ -+ /* WAN port */ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.phy_mask = BIT(4); -+ -+ /* LAN ports */ + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.speed = SPEED_100; + ar71xx_eth1_data.duplex = DUPLEX_FULL; -+ ar71xx_eth1_data.has_ar7240_switch = 1; + -+ ar71xx_add_device_mdio(0x0); -+ ar71xx_add_device_eth(1); + ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ platform_device_register(&rb750_leds_device); -+ platform_device_register(&rb750_nand_device); ++ ar71xx_register_gpio_keys_polled(-1, PB42_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(pb42_gpio_keys), ++ pb42_gpio_keys); ++ ++ pb42_pci_init(); +} + -+MIPS_MACHINE(AR71XX_MACH_RB_750, "750i", "MikroTik RouterBOARD 750", -+ rb750_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c 2011-08-24 02:41:55.577989822 +0200 -@@ -0,0 +1,151 @@ ++MIPS_MACHINE(AR71XX_MACH_PB42, "PB42", "Atheros PB42", pb42_init); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c linux-2.6.39/arch/mips/ar71xx/mach-pb44.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb44.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-pb44.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,213 @@ +/* -+ * TrendNET TEW-632BRP board support ++ * Atheros PB44 board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + +#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ar9xxx-wmac.h" ++#include "dev-pb42-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "nvram.h" ++#include "dev-usb.h" + -+#define TEW_632BRP_GPIO_LED_STATUS 1 -+#define TEW_632BRP_GPIO_LED_WPS 3 -+#define TEW_632BRP_GPIO_LED_WLAN 6 -+#define TEW_632BRP_GPIO_BTN_WPS 12 -+#define TEW_632BRP_GPIO_BTN_RESET 21 ++#define PB44_PCF8757_VSC7395_CS 0 ++#define PB44_PCF8757_STEREO_CS 1 ++#define PB44_PCF8757_SLIC_CS0 2 ++#define PB44_PCF8757_SLIC_TEST 3 ++#define PB44_PCF8757_SLIC_INT0 4 ++#define PB44_PCF8757_SLIC_INT1 5 ++#define PB44_PCF8757_SW_RESET 6 ++#define PB44_PCF8757_SW_JUMP 8 ++#define PB44_PCF8757_LED_JUMP1 9 ++#define PB44_PCF8757_LED_JUMP2 10 ++#define PB44_PCF8757_TP24 11 ++#define PB44_PCF8757_TP25 12 ++#define PB44_PCF8757_TP26 13 ++#define PB44_PCF8757_TP27 14 ++#define PB44_PCF8757_TP28 15 + -+#define TEW_632BRP_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TEW_632BRP_KEYS_DEBOUNCE_INTERVAL (3 * TEW_632BRP_KEYS_POLL_INTERVAL) ++#define PB44_GPIO_I2C_SCL 0 ++#define PB44_GPIO_I2C_SDA 1 + -+#define TEW_632BRP_CONFIG_ADDR 0x1f020000 -+#define TEW_632BRP_CONFIG_SIZE 0x10000 ++#define PB44_GPIO_EXP_BASE 16 ++#define PB44_GPIO_VSC7395_CS (PB44_GPIO_EXP_BASE + PB44_PCF8757_VSC7395_CS) ++#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_RESET) ++#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + PB44_PCF8757_SW_JUMP) ++#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP1) ++#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + PB44_PCF8757_LED_JUMP2) + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tew_632brp_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "config", -+ .offset = 0x020000, -+ .size = 0x010000, -+ }, { -+ .name = "kernel", -+ .offset = 0x030000, -+ .size = 0x0e0000, -+ }, { -+ .name = "rootfs", -+ .offset = 0x110000, -+ .size = 0x2e0000, -+ }, { -+ .name = "art", -+ .offset = 0x3f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x030000, -+ .size = 0x3c0000, ++#define PB44_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL) ++ ++static struct i2c_gpio_platform_data pb44_i2c_gpio_data = { ++ .sda_pin = PB44_GPIO_I2C_SDA, ++ .scl_pin = PB44_GPIO_I2C_SCL, ++}; ++ ++static struct platform_device pb44_i2c_gpio_device = { ++ .name = "i2c-gpio", ++ .id = 0, ++ .dev = { ++ .platform_data = &pb44_i2c_gpio_data, + } +}; -+#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data tew_632brp_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tew_632brp_partitions, -+ .nr_parts = ARRAY_SIZE(tew_632brp_partitions), -+#endif ++static struct pcf857x_platform_data pb44_pcf857x_data = { ++ .gpio_base = PB44_GPIO_EXP_BASE, +}; + -+static struct gpio_led tew_632brp_leds_gpio[] __initdata = { ++static struct i2c_board_info pb44_i2c_board_info[] __initdata = { + { -+ .name = "tew-632brp:green:status", -+ .gpio = TEW_632BRP_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "tew-632brp:blue:wps", -+ .gpio = TEW_632BRP_GPIO_LED_WPS, ++ I2C_BOARD_INFO("pcf8575", 0x20), ++ .platform_data = &pb44_pcf857x_data, ++ }, ++}; ++ ++static struct gpio_led pb44_leds_gpio[] __initdata = { ++ { ++ .name = "pb44:amber:jump1", ++ .gpio = PB44_GPIO_LED_JUMP1, + .active_low = 1, + }, { -+ .name = "tew-632brp:green:wlan", -+ .gpio = TEW_632BRP_GPIO_LED_WLAN, ++ .name = "pb44:green:jump2", ++ .gpio = PB44_GPIO_LED_JUMP2, + .active_low = 1, -+ } ++ }, +}; + -+static struct gpio_keys_button tew_632brp_gpio_keys[] __initdata = { ++static struct gpio_keys_button pb44_gpio_keys[] __initdata = { + { -+ .desc = "reset", ++ .desc = "soft_reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW_632BRP_GPIO_BTN_RESET, ++ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB44_GPIO_SW_RESET, ++ .active_low = 1, + }, { -+ .desc = "wps", ++ .desc = "jumpstart", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW_632BRP_GPIO_BTN_WPS, ++ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB44_GPIO_SW_JUMP, ++ .active_low = 1, + } +}; + -+#define TEW_632BRP_LAN_PHYMASK BIT(0) -+#define TEW_632BRP_WAN_PHYMASK BIT(4) -+#define TEW_632BRP_MDIO_MASK (~(TEW_632BRP_LAN_PHYMASK | \ -+ TEW_632BRP_WAN_PHYMASK)) -+ -+static void __init tew_632brp_setup(void) ++static void pb44_vsc7395_reset(void) +{ -+ const char *config = (char *) KSEG1ADDR(TEW_632BRP_CONFIG_ADDR); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[6]; -+ u8 *wlan_mac = NULL; ++ ar71xx_device_stop(RESET_MODULE_GE1_PHY); ++ udelay(10); ++ ar71xx_device_start(RESET_MODULE_GE1_PHY); ++ mdelay(50); ++} + -+ if (nvram_parse_mac_addr(config, TEW_632BRP_CONFIG_SIZE, -+ "lan_mac=", mac) == 0) { -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); -+ wlan_mac = mac; -+ } ++static struct vsc7385_platform_data pb44_vsc7395_data = { ++ .reset = pb44_vsc7395_reset, ++ .ucode_name = "vsc7395_ucode_pb44.bin", ++ .mac_cfg = { ++ .tx_ipg = 6, ++ .bit2 = 1, ++ .clk_sel = 0, ++ }, ++}; + -+ ar71xx_add_device_mdio(TEW_632BRP_MDIO_MASK); ++static struct spi_board_info pb44_spi_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "m25p80", ++ }, { ++ .bus_num = 0, ++ .chip_select = 1, ++ .max_speed_hz = 25000000, ++ .modalias = "spi-vsc7385", ++ .platform_data = &pb44_vsc7395_data, ++ .controller_data = (void *) PB44_GPIO_VSC7395_CS, ++ }, ++}; + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.phy_mask = TEW_632BRP_LAN_PHYMASK; ++static struct resource pb44_spi_resources[] = { ++ [0] = { ++ .start = AR71XX_SPI_BASE, ++ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; + -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = TEW_632BRP_WAN_PHYMASK; ++static struct ar71xx_spi_platform_data pb44_spi_data = { ++ .bus_num = 0, ++ .num_chipselect = 2, ++}; ++ ++static struct platform_device pb44_spi_device = { ++ .name = "pb44-spi", ++ .id = -1, ++ .resource = pb44_spi_resources, ++ .num_resources = ARRAY_SIZE(pb44_spi_resources), ++ .dev = { ++ .platform_data = &pb44_spi_data, ++ }, ++}; ++ ++#define PB44_WAN_PHYMASK BIT(0) ++#define PB44_LAN_PHYMASK 0 ++#define PB44_MDIO_PHYMASK (PB44_LAN_PHYMASK | PB44_WAN_PHYMASK) ++ ++static void __init pb44_init(void) ++{ ++ ar71xx_add_device_mdio(~PB44_MDIO_PHYMASK); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = PB44_WAN_PHYMASK; + + ar71xx_add_device_eth(0); ++ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_eth1_pll_data.pll_1000 = 0x110000; ++ + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_m25p80(&tew_632brp_flash_data); ++ ar71xx_add_device_usb(); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio), -+ tew_632brp_leds_gpio); ++ pb42_pci_init(); + -+ ar71xx_register_gpio_keys_polled(-1, TEW_632BRP_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tew_632brp_gpio_keys), -+ tew_632brp_gpio_keys); ++ i2c_register_board_info(0, pb44_i2c_board_info, ++ ARRAY_SIZE(pb44_i2c_board_info)); + -+ ar9xxx_add_device_wmac(eeprom, wlan_mac); ++ platform_device_register(&pb44_i2c_gpio_device); ++ ++ spi_register_board_info(pb44_spi_info, ARRAY_SIZE(pb44_spi_info)); ++ platform_device_register(&pb44_spi_device); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio), ++ pb44_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(pb44_gpio_keys), ++ pb44_gpio_keys); +} + -+MIPS_MACHINE(AR71XX_MACH_TEW_632BRP, "TEW-632BRP", "TRENDnet TEW-632BRP", -+ tew_632brp_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-mr3x20.c linux-2.6.39/arch/mips/ar71xx/mach-tl-mr3x20.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-mr3x20.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tl-mr3x20.c 2011-08-24 02:41:55.577989822 +0200 -@@ -0,0 +1,166 @@ ++MIPS_MACHINE(AR71XX_MACH_PB44, "PB44", "Atheros PB44", pb44_init); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c linux-2.6.39/arch/mips/ar71xx/mach-pb92.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-pb92.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-pb92.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,105 @@ +/* -+ * TP-LINK TL-MR3220/3420 board support ++ * Atheros PB92 board support + * -+ * Copyright (C) 2010 Gabor Juhos ++ * Copyright (C) 2010 Felix Fietkau ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include +#include +#include -+ +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ap91-pci.h" +#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" ++#include "dev-pb9x-pci.h" +#include "dev-usb.h" + -+#define TL_MR3X20_GPIO_LED_QSS 0 -+#define TL_MR3X20_GPIO_LED_SYSTEM 1 -+#define TL_MR3X20_GPIO_LED_3G 8 -+ -+#define TL_MR3X20_GPIO_BTN_RESET 11 -+#define TL_MR3X20_GPIO_BTN_QSS 12 -+ -+#define TL_MR3X20_GPIO_USB_POWER 6 -+ -+#define TL_MR3X20_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_MR3X20_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3X20_KEYS_POLL_INTERVAL) -+ +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_mr3x20_partitions[] = { ++static struct mtd_partition pb92_partitions[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x020000, ++ .size = 0x040000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "kernel", -+ .offset = 0x020000, -+ .size = 0x140000, ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, + }, { + .name = "rootfs", -+ .offset = 0x160000, -+ .size = 0x290000, ++ .offset = 0x050000, ++ .size = 0x2b0000, + }, { -+ .name = "art", -+ .offset = 0x3f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "uImage", ++ .offset = 0x300000, ++ .size = 0x0e0000, + }, { -+ .name = "firmware", -+ .offset = 0x020000, -+ .size = 0x3d0000, ++ .name = "ART", ++ .offset = 0x3e0000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, + } +}; -+#define tl_mr3x20_num_partitions ARRAY_SIZE(tl_mr3x20_partitions) -+#else -+#define tl_mr3x20_partitions NULL -+#define tl_mr3x20_num_partitions 0 +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data tl_mr3x20_flash_data = { -+ .parts = tl_mr3x20_partitions, -+ .nr_parts = tl_mr3x20_num_partitions, ++static struct flash_platform_data pb92_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = pb92_partitions, ++ .nr_parts = ARRAY_SIZE(pb92_partitions), ++#endif +}; + -+static struct gpio_led tl_mr3x20_leds_gpio[] __initdata = { -+ { -+ .name = "tl-mr3x20:green:system", -+ .gpio = TL_MR3X20_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tl-mr3x20:green:qss", -+ .gpio = TL_MR3X20_GPIO_LED_QSS, -+ .active_low = 1, -+ }, { -+ .name = "tl-mr3x20:green:3g", -+ .gpio = TL_MR3X20_GPIO_LED_3G, -+ .active_low = 1, -+ } -+}; ++#define PB92_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define PB92_KEYS_DEBOUNCE_INTERVAL (3 * PB92_KEYS_POLL_INTERVAL) + -+static struct gpio_keys_button tl_mr3x20_gpio_keys[] __initdata = { ++#define PB92_GPIO_BTN_SW4 8 ++#define PB92_GPIO_BTN_SW5 3 ++ ++static struct gpio_keys_button pb92_gpio_keys[] __initdata = { + { -+ .desc = "reset", ++ .desc = "sw4", + .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR3X20_GPIO_BTN_RESET, ++ .code = BTN_0, ++ .debounce_interval = PB92_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB92_GPIO_BTN_SW4, + .active_low = 1, + }, { -+ .desc = "qss", ++ .desc = "sw5", + .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR3X20_GPIO_BTN_QSS, ++ .code = BTN_1, ++ .debounce_interval = PB92_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = PB92_GPIO_BTN_SW5, + .active_low = 1, + } +}; + -+static void __init tl_mr3x20_setup(void) ++static void __init pb92_init(void) +{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* enable power for the USB port */ -+ gpio_request(TL_MR3X20_GPIO_USB_POWER, "USB power"); -+ gpio_direction_output(TL_MR3X20_GPIO_USB_POWER, 1); -+ -+ ar71xx_add_device_m25p80(&tl_mr3x20_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_mr3x20_leds_gpio), -+ tl_mr3x20_leds_gpio); ++ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); + -+ ar71xx_register_gpio_keys_polled(-1, TL_MR3X20_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_mr3x20_gpio_keys), -+ tl_mr3x20_gpio_keys); ++ ar71xx_add_device_m25p80(&pb92_flash_data); + -+ ar71xx_eth1_data.has_ar7240_switch = 1; ++ ar71xx_add_device_mdio(~BIT(0)); + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); -+ -+ /* WAN port */ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.speed = SPEED_1000; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.phy_mask = BIT(4); -+ -+ /* LAN ports */ -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = BIT(0); + -+ ar71xx_add_device_mdio(0x0); -+ ar71xx_add_device_eth(1); + ar71xx_add_device_eth(0); + -+ ar71xx_add_device_usb(); -+ -+ ap91_pci_init(ee, mac); -+} -+ -+static void __init tl_mr3220_setup(void) -+{ -+ tl_mr3x20_setup(); -+ ap91_pci_setup_wmac_led_pin(1); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_TL_MR3220, "TL-MR3220", "TP-LINK TL-MR3220", -+ tl_mr3220_setup); ++ ar71xx_register_gpio_keys_polled(-1, PB92_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(pb92_gpio_keys), ++ pb92_gpio_keys); + -+static void __init tl_mr3420_setup(void) -+{ -+ tl_mr3x20_setup(); -+ ap91_pci_setup_wmac_led_pin(0); ++ pb9x_pci_init(); +} + -+MIPS_MACHINE(AR71XX_MACH_TL_MR3420, "TL-MR3420", "TP-LINK TL-MR3420", -+ tl_mr3420_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd.c 2011-08-24 02:41:55.587990766 +0200 -@@ -0,0 +1,130 @@ ++MIPS_MACHINE(AR71XX_MACH_PB92, "PB92", "Atheros PB92", pb92_init); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb4xx.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-rb4xx.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,344 @@ +/* -+ * TP-LINK TL-WA901ND board support ++ * MikroTik RouterBOARD 4xx series support + * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * Copyright (C) 2010 Pieter Hollants ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include ++#include ++#include ++#include ++#include ++#include +#include +#include + +#include ++#include ++#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ap91-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+#define TL_WA901ND_GPIO_LED_QSS 0 -+#define TL_WA901ND_GPIO_LED_SYSTEM 1 ++#define RB4XX_GPIO_USER_LED 4 ++#define RB4XX_GPIO_RESET_SWITCH 7 + -+#define TL_WA901ND_GPIO_BTN_RESET 11 -+#define TL_WA901ND_GPIO_BTN_QSS 12 ++#define RB4XX_GPIO_CPLD_BASE 32 ++#define RB4XX_GPIO_CPLD_LED1 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED1) ++#define RB4XX_GPIO_CPLD_LED2 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED2) ++#define RB4XX_GPIO_CPLD_LED3 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED3) ++#define RB4XX_GPIO_CPLD_LED4 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED4) ++#define RB4XX_GPIO_CPLD_LED5 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED5) + -+#define TL_WA901ND_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WA901ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WA901ND_KEYS_POLL_INTERVAL) ++#define RB4XX_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define RB4XX_KEYS_DEBOUNCE_INTERVAL (3 * RB4XX_KEYS_POLL_INTERVAL) + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_wa901nd_partitions[] = { ++static struct gpio_led rb4xx_leds_gpio[] __initdata = { + { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "kernel", -+ .offset = 0x020000, -+ .size = 0x140000, ++ .name = "rb4xx:yellow:user", ++ .gpio = RB4XX_GPIO_USER_LED, ++ .active_low = 0, + }, { -+ .name = "rootfs", -+ .offset = 0x160000, -+ .size = 0x290000, ++ .name = "rb4xx:green:led1", ++ .gpio = RB4XX_GPIO_CPLD_LED1, ++ .active_low = 1, + }, { -+ .name = "art", -+ .offset = 0x3f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "rb4xx:green:led2", ++ .gpio = RB4XX_GPIO_CPLD_LED2, ++ .active_low = 1, + }, { -+ .name = "firmware", -+ .offset = 0x020000, -+ .size = 0x3d0000, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ -+ -+static struct flash_platform_data tl_wa901nd_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tl_wa901nd_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wa901nd_partitions), -+#endif -+}; -+ -+static struct gpio_led tl_wa901nd_leds_gpio[] __initdata = { -+ { -+ .name = "tl-wa901nd:green:system", -+ .gpio = TL_WA901ND_GPIO_LED_SYSTEM, ++ .name = "rb4xx:green:led3", ++ .gpio = RB4XX_GPIO_CPLD_LED3, + .active_low = 1, + }, { -+ .name = "tl-wa901nd:green:qss", -+ .gpio = TL_WA901ND_GPIO_LED_QSS, ++ .name = "rb4xx:green:led4", ++ .gpio = RB4XX_GPIO_CPLD_LED4, + .active_low = 1, -+ } ++ }, { ++ .name = "rb4xx:green:led5", ++ .gpio = RB4XX_GPIO_CPLD_LED5, ++ .active_low = 0, ++ }, +}; + -+static struct gpio_keys_button tl_wa901nd_gpio_keys[] __initdata = { ++static struct gpio_keys_button rb4xx_gpio_keys[] __initdata = { + { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA901ND_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "qss", ++ .desc = "reset_switch", + .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA901ND_GPIO_BTN_QSS, ++ .code = KEY_RESTART, ++ .debounce_interval = RB4XX_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = RB4XX_GPIO_RESET_SWITCH, + .active_low = 1, + } +}; + -+static void __init tl_wa901nd_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* -+ * ar71xx_eth0 would be the WAN port, but is not connected on -+ * the TL-WA901ND. ar71xx_eth1 connects to the internal switch chip, -+ * however we have a single LAN port only. -+ */ -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 0); -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; -+ ar71xx_eth1_data.has_ar7240_switch = 1; -+ -+ ar71xx_add_device_mdio(0x0); -+ ar71xx_add_device_eth(1); -+ -+ ar71xx_add_device_m25p80(&tl_wa901nd_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_leds_gpio), -+ tl_wa901nd_leds_gpio); -+ -+ ar71xx_register_gpio_keys_polled(-1, TL_WA901ND_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wa901nd_gpio_keys), -+ tl_wa901nd_gpio_keys); -+ -+ ap91_pci_init(ee, mac); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_TL_WA901ND, "TL-WA901ND", "TP-LINK TL-WA901ND", -+ tl_wa901nd_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd-v2.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd-v2.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd-v2.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd-v2.c 2011-08-24 02:41:55.587990766 +0200 -@@ -0,0 +1,132 @@ -+/* -+ * TP-LINK TL-WA901ND v2 board support -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * Copyright (C) 2010 Pieter Hollants -+ * Copyright (C) 2011 Jonathan Bennett -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "machtype.h" -+#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-ar9xxx-wmac.h" -+ -+#define TL_WA901ND_V2_GPIO_LED_QSS 4 -+#define TL_WA901ND_V2_GPIO_LED_SYSTEM 2 -+#define TL_WA901ND_V2_GPIO_LED_WLAN 9 -+ ++static struct platform_device rb4xx_nand_device = { ++ .name = "rb4xx-nand", ++ .id = -1, ++}; + -+#define TL_WA901ND_V2_GPIO_BTN_RESET 3 -+#define TL_WA901ND_V2_GPIO_BTN_QSS 7 ++static struct ar71xx_pci_irq rb4xx_pci_irqs[] __initdata = { ++ { ++ .slot = 0, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV2, ++ }, { ++ .slot = 1, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV0, ++ }, { ++ .slot = 1, ++ .pin = 2, ++ .irq = AR71XX_PCI_IRQ_DEV1, ++ }, { ++ .slot = 2, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV1, ++ }, { ++ .slot = 3, ++ .pin = 1, ++ .irq = AR71XX_PCI_IRQ_DEV2, ++ } ++}; + -+#define TL_WA901ND_V2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * TL_WA901ND_V2_KEYS_POLL_INTERVAL) +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_wa901nd_v2_partitions[] = { ++static struct mtd_partition rb4xx_partitions[] = { + { -+ .name = "u-boot", ++ .name = "routerboot", + .offset = 0, -+ .size = 0x020000, ++ .size = 0x0b000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "kernel", -+ .offset = 0x020000, -+ .size = 0x140000, -+ }, { -+ .name = "rootfs", -+ .offset = 0x160000, -+ .size = 0x290000, ++ .name = "hard_config", ++ .offset = 0x0b000, ++ .size = 0x01000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "art", -+ .offset = 0x3f0000, -+ .size = 0x010000, ++ .name = "bios", ++ .offset = 0x0d000, ++ .size = 0x02000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "firmware", -+ .offset = 0x020000, -+ .size = 0x3d0000, ++ .name = "soft_config", ++ .offset = 0x0f000, ++ .size = 0x01000, + } +}; ++#define rb4xx_num_partitions ARRAY_SIZE(rb4xx_partitions) ++#else /* CONFIG_MTD_PARTITIONS */ ++#define rb4xx_partitions NULL ++#define rb4xx_num_partitions 0 +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data tl_wa901nd_v2_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tl_wa901nd_v2_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wa901nd_v2_partitions), -+#endif ++static struct flash_platform_data rb4xx_flash_data = { ++ .type = "pm25lv512", ++ .parts = rb4xx_partitions, ++ .nr_parts = rb4xx_num_partitions, +}; + -+static struct gpio_led tl_wa901nd_v2_leds_gpio[] __initdata = { -+ { -+ .name = "tl-wa901nd-v2:green:system", -+ .gpio = TL_WA901ND_V2_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tl-wa901nd-v2:green:qss", -+ .gpio = TL_WA901ND_V2_GPIO_LED_QSS, -+ }, { -+ .name = "tl-wa901nd-v2:green:wlan", -+ .gpio = TL_WA901ND_V2_GPIO_LED_WLAN, -+ .active_low = 1, -+ } ++static struct rb4xx_cpld_platform_data rb4xx_cpld_data = { ++ .gpio_base = RB4XX_GPIO_CPLD_BASE, +}; + -+static struct gpio_keys_button tl_wa901nd_v2_gpio_keys[] __initdata = { ++static struct mmc_spi_platform_data rb4xx_mmc_data = { ++ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, ++}; ++ ++static struct spi_board_info rb4xx_spi_info[] = { + { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA901ND_V2_GPIO_BTN_RESET, -+ .active_low = 1, ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "m25p80", ++ .platform_data = &rb4xx_flash_data, + }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA901ND_V2_GPIO_BTN_QSS, -+ .active_low = 1, ++ .bus_num = 0, ++ .chip_select = 1, ++ .max_speed_hz = 25000000, ++ .modalias = "spi-rb4xx-cpld", ++ .platform_data = &rb4xx_cpld_data, + } +}; + -+static void __init tl_wa901nd_v2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++static struct spi_board_info rb4xx_microsd_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 2, ++ .max_speed_hz = 25000000, ++ .modalias = "mmc_spi", ++ .platform_data = &rb4xx_mmc_data, ++ } ++}; + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = 0x00001000; -+ ar71xx_add_device_mdio(0x0); ++static struct resource rb4xx_spi_resources[] = { ++ { ++ .start = AR71XX_SPI_BASE, ++ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; + -+ ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC | -+ RESET_MODULE_GE0_PHY; -+ ar71xx_add_device_eth(0); ++static struct platform_device rb4xx_spi_device = { ++ .name = "rb4xx-spi", ++ .id = -1, ++ .resource = rb4xx_spi_resources, ++ .num_resources = ARRAY_SIZE(rb4xx_spi_resources), ++}; + -+ ar71xx_add_device_m25p80(&tl_wa901nd_v2_flash_data); ++static void __init rb4xx_generic_setup(void) ++{ ++ ar71xx_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN | ++ AR71XX_GPIO_FUNC_SPI_CS2_EN); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_v2_leds_gpio), -+ tl_wa901nd_v2_leds_gpio); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio), ++ rb4xx_leds_gpio); + -+ ar71xx_register_gpio_keys_polled(-1, TL_WA901ND_V2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wa901nd_v2_gpio_keys), -+ tl_wa901nd_v2_gpio_keys); ++ ar71xx_register_gpio_keys_polled(-1, RB4XX_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(rb4xx_gpio_keys), ++ rb4xx_gpio_keys); + -+ ar9xxx_add_device_wmac(eeprom, mac); ++ spi_register_board_info(rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info)); ++ platform_device_register(&rb4xx_spi_device); ++ platform_device_register(&rb4xx_nand_device); +} + -+MIPS_MACHINE(AR71XX_MACH_TL_WA901ND_V2, "TL-WA901ND-v2", -+ "TP-LINK TL-WA901ND v2", tl_wa901nd_v2_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c 2011-08-24 02:41:55.587990766 +0200 -@@ -0,0 +1,156 @@ -+/* -+ * TP-LINK TL-WR1043ND board support -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++static void __init rb411_setup(void) ++{ ++ rb4xx_generic_setup(); ++ spi_register_board_info(rb4xx_microsd_info, ++ ARRAY_SIZE(rb4xx_microsd_info)); + -+#include -+#include -+#include -+#include -+#include ++ ar71xx_add_device_mdio(0xfffffffc); + -+#include "machtype.h" -+#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ar9xxx-wmac.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-usb.h" ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = 0x00000003; + -+#define TL_WR1043ND_GPIO_LED_USB 1 -+#define TL_WR1043ND_GPIO_LED_SYSTEM 2 -+#define TL_WR1043ND_GPIO_LED_QSS 5 -+#define TL_WR1043ND_GPIO_LED_WLAN 9 ++ ar71xx_add_device_eth(0); + -+#define TL_WR1043ND_GPIO_BTN_RESET 3 -+#define TL_WR1043ND_GPIO_BTN_QSS 7 ++ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); ++} + -+#define TL_WR1043ND_GPIO_RTL8366_SDA 18 -+#define TL_WR1043ND_GPIO_RTL8366_SCK 19 ++MIPS_MACHINE(AR71XX_MACH_RB_411, "411", "MikroTik RouterBOARD 411/A/AH", ++ rb411_setup); + -+#define TL_WR1043ND_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR1043ND_KEYS_POLL_INTERVAL) ++static void __init rb411u_setup(void) ++{ ++ rb411_setup(); ++ ar71xx_add_device_usb(); ++} + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_wr1043nd_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "kernel", -+ .offset = 0x020000, -+ .size = 0x140000, -+ }, { -+ .name = "rootfs", -+ .offset = 0x160000, -+ .size = 0x690000, -+ }, { -+ .name = "art", -+ .offset = 0x7f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x020000, -+ .size = 0x7d0000, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ ++MIPS_MACHINE(AR71XX_MACH_RB_411U, "411U", "MikroTik RouterBOARD 411U", ++ rb411u_setup); + -+static struct flash_platform_data tl_wr1043nd_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tl_wr1043nd_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wr1043nd_partitions), -+#endif -+}; ++#define RB433_LAN_PHYMASK BIT(0) ++#define RB433_WAN_PHYMASK BIT(4) ++#define RB433_MDIO_PHYMASK (RB433_LAN_PHYMASK | RB433_WAN_PHYMASK) + -+static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = { -+ { -+ .name = "tl-wr1043nd:green:usb", -+ .gpio = TL_WR1043ND_GPIO_LED_USB, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr1043nd:green:system", -+ .gpio = TL_WR1043ND_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr1043nd:green:qss", -+ .gpio = TL_WR1043ND_GPIO_LED_QSS, -+ .active_low = 0, -+ }, { -+ .name = "tl-wr1043nd:green:wlan", -+ .gpio = TL_WR1043ND_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; ++static void __init rb433_setup(void) ++{ ++ rb4xx_generic_setup(); ++ spi_register_board_info(rb4xx_microsd_info, ++ ARRAY_SIZE(rb4xx_microsd_info)); + -+static struct gpio_keys_button tl_wr1043nd_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR1043ND_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR1043ND_GPIO_BTN_QSS, -+ .active_low = 1, -+ } -+}; ++ ar71xx_add_device_mdio(~RB433_MDIO_PHYMASK); + -+static struct rtl8366_platform_data tl_wr1043nd_rtl8366rb_data = { -+ .gpio_sda = TL_WR1043ND_GPIO_RTL8366_SDA, -+ .gpio_sck = TL_WR1043ND_GPIO_RTL8366_SCK, -+}; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 1); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = RB433_LAN_PHYMASK; + -+static struct platform_device tl_wr1043nd_rtl8366rb_device = { -+ .name = RTL8366RB_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &tl_wr1043nd_rtl8366rb_data, -+ } -+}; ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = RB433_WAN_PHYMASK; + -+static void __init tl_wr1043nd_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ ar71xx_add_device_eth(1); ++ ar71xx_add_device_eth(0); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_eth0_data.mii_bus_dev = &tl_wr1043nd_rtl8366rb_device.dev; -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.speed = SPEED_1000; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_pll_data.pll_1000 = 0x1a000000; ++ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); ++} + -+ ar71xx_add_device_eth(0); ++MIPS_MACHINE(AR71XX_MACH_RB_433, "433", "MikroTik RouterBOARD 433/AH", ++ rb433_setup); + ++static void __init rb433u_setup(void) ++{ ++ rb433_setup(); + ar71xx_add_device_usb(); ++} + -+ ar71xx_add_device_m25p80(&tl_wr1043nd_flash_data); ++MIPS_MACHINE(AR71XX_MACH_RB_433U, "433U", "MikroTik RouterBOARD 433UAH", ++ rb433u_setup); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr1043nd_leds_gpio), -+ tl_wr1043nd_leds_gpio); ++#define RB450_LAN_PHYMASK BIT(0) ++#define RB450_WAN_PHYMASK BIT(4) ++#define RB450_MDIO_PHYMASK (RB450_LAN_PHYMASK | RB450_WAN_PHYMASK) + -+ platform_device_register(&tl_wr1043nd_rtl8366rb_device); ++static void __init rb450_generic_setup(int gige) ++{ ++ rb4xx_generic_setup(); ++ ar71xx_add_device_mdio(~RB450_MDIO_PHYMASK); + -+ ar71xx_register_gpio_keys_polled(-1, TL_WR1043ND_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr1043nd_gpio_keys), -+ tl_wr1043nd_gpio_keys); ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 1); ++ ar71xx_eth0_data.phy_if_mode = (gige) ? ++ PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = RB450_LAN_PHYMASK; + -+ ar9xxx_add_device_wmac(eeprom, mac); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth1_data.phy_if_mode = (gige) ? ++ PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = RB450_WAN_PHYMASK; ++ ++ ar71xx_add_device_eth(1); ++ ar71xx_add_device_eth(0); +} + -+MIPS_MACHINE(AR71XX_MACH_TL_WR1043ND, "TL-WR1043ND", "TP-LINK TL-WR1043ND", -+ tl_wr1043nd_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c 2011-08-24 02:41:55.587990766 +0200 -@@ -0,0 +1,135 @@ ++static void __init rb450_setup(void) ++{ ++ rb450_generic_setup(0); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_RB_450, "450", "MikroTik RouterBOARD 450", ++ rb450_setup); ++ ++static void __init rb450g_setup(void) ++{ ++ rb450_generic_setup(1); ++ spi_register_board_info(rb4xx_microsd_info, ++ ARRAY_SIZE(rb4xx_microsd_info)); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G", ++ rb450g_setup); ++ ++static void __init rb493_setup(void) ++{ ++ rb4xx_generic_setup(); ++ ++ ar71xx_add_device_mdio(0x3fffff00); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = 0x00000001; ++ ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); ++ ++ ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_RB_493, "493", "MikroTik RouterBOARD 493/AH", ++ rb493_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c linux-2.6.39/arch/mips/ar71xx/mach-rb750.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-rb750.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-rb750.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,144 @@ +/* -+ * TP-LINK TL-WR741ND board support ++ * MikroTik RouterBOARD 750 support + * -+ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+ ++#include +#include ++#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-m25p80.h" -+#include "dev-ap91-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+ -+#define TL_WR741ND_GPIO_LED_QSS 0 -+#define TL_WR741ND_GPIO_LED_SYSTEM 1 -+ -+#define TL_WR741ND_GPIO_BTN_RESET 11 -+#define TL_WR741ND_GPIO_BTN_QSS 12 -+ -+#define TL_WR741ND_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR741ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR741ND_KEYS_POLL_INTERVAL) + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_wr741nd_partitions[] = { ++static struct rb750_led_data rb750_leds[] = { + { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "rb750:green:act", ++ .mask = RB750_LED_ACT, ++ .active_low = 1, + }, { -+ .name = "kernel", -+ .offset = 0x020000, -+ .size = 0x140000, ++ .name = "rb750:green:port1", ++ .mask = RB750_LED_PORT5, ++ .active_low = 1, + }, { -+ .name = "rootfs", -+ .offset = 0x160000, -+ .size = 0x290000, ++ .name = "rb750:green:port2", ++ .mask = RB750_LED_PORT4, ++ .active_low = 1, + }, { -+ .name = "art", -+ .offset = 0x3f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "rb750:green:port3", ++ .mask = RB750_LED_PORT3, ++ .active_low = 1, + }, { -+ .name = "firmware", -+ .offset = 0x020000, -+ .size = 0x3d0000, ++ .name = "rb750:green:port4", ++ .mask = RB750_LED_PORT2, ++ .active_low = 1, ++ }, { ++ .name = "rb750:green:port5", ++ .mask = RB750_LED_PORT1, ++ .active_low = 1, + } +}; -+#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data tl_wr741nd_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tl_wr741nd_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wr741nd_partitions), -+#endif ++static struct rb750_led_platform_data rb750_leds_data = { ++ .num_leds = ARRAY_SIZE(rb750_leds), ++ .leds = rb750_leds, +}; + -+static struct gpio_led tl_wr741nd_leds_gpio[] __initdata = { -+ { -+ .name = "tl-wr741nd:green:system", -+ .gpio = TL_WR741ND_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr741nd:green:qss", -+ .gpio = TL_WR741ND_GPIO_LED_QSS, -+ .active_low = 1, ++static struct platform_device rb750_leds_device = { ++ .name = "leds-rb750", ++ .dev = { ++ .platform_data = &rb750_leds_data, + } +}; + -+static struct gpio_keys_button tl_wr741nd_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR741ND_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR741ND_GPIO_BTN_QSS, -+ .active_low = 1, -+ } ++static struct platform_device rb750_nand_device = { ++ .name = "rb750-nand", ++ .id = -1, +}; + -+static void __init tl_wr741nd_setup(void) ++int rb750_latch_change(u32 mask_clr, u32 mask_set) +{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); ++ static DEFINE_SPINLOCK(lock); ++ static u32 latch_set = RB750_LED_BITS | RB750_LVC573_LE; ++ static u32 latch_oe; ++ static u32 latch_clr; ++ unsigned long flags; ++ u32 t; ++ int ret = 0; + -+ ar71xx_add_device_m25p80(&tl_wr741nd_flash_data); ++ spin_lock_irqsave(&lock, flags); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr741nd_leds_gpio), -+ tl_wr741nd_leds_gpio); ++ if ((mask_clr & BIT(31)) != 0 && ++ (latch_set & RB750_LVC573_LE) == 0) { ++ goto unlock; ++ } + -+ ar71xx_register_gpio_keys_polled(-1, TL_WR741ND_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr741nd_gpio_keys), -+ tl_wr741nd_gpio_keys); ++ latch_set = (latch_set | mask_set) & ~mask_clr; ++ latch_clr = (latch_clr | mask_clr) & ~mask_set; + -+ ar71xx_eth1_data.has_ar7240_switch = 1; -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ if (latch_oe == 0) ++ latch_oe = __raw_readl(ar71xx_gpio_base + GPIO_REG_OE); ++ ++ if (likely(latch_set & RB750_LVC573_LE)) { ++ void __iomem *base = ar71xx_gpio_base; ++ ++ t = __raw_readl(base + GPIO_REG_OE); ++ t |= mask_clr | latch_oe | mask_set; ++ ++ __raw_writel(t, base + GPIO_REG_OE); ++ __raw_writel(latch_clr, base + GPIO_REG_CLEAR); ++ __raw_writel(latch_set, base + GPIO_REG_SET); ++ } else if (mask_clr & RB750_LVC573_LE) { ++ void __iomem *base = ar71xx_gpio_base; ++ ++ latch_oe = __raw_readl(base + GPIO_REG_OE); ++ __raw_writel(RB750_LVC573_LE, base + GPIO_REG_CLEAR); ++ /* flush write */ ++ __raw_readl(base + GPIO_REG_CLEAR); ++ } ++ ++ ret = 1; ++ ++unlock: ++ spin_unlock_irqrestore(&lock, flags); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(rb750_latch_change); ++ ++static void __init rb750_setup(void) ++{ ++ ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, 1); + + /* WAN port */ + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; @@ -7675,25 +6921,27 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c linux-2.6.39/arch + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ar71xx_eth1_data.speed = SPEED_1000; + ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_eth1_data.has_ar7240_switch = 1; + + ar71xx_add_device_mdio(0x0); + ar71xx_add_device_eth(1); + ar71xx_add_device_eth(0); + -+ ap91_pci_setup_wmac_led_pin(1); -+ -+ ap91_pci_init(ee, mac); ++ platform_device_register(&rb750_leds_device); ++ platform_device_register(&rb750_nand_device); +} -+MIPS_MACHINE(AR71XX_MACH_TL_WR741ND, "TL-WR741ND", "TP-LINK TL-WR741ND", -+ tl_wr741nd_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c 2011-08-24 02:41:55.597982750 +0200 -@@ -0,0 +1,144 @@ ++ ++MIPS_MACHINE(AR71XX_MACH_RB_750, "750i", "MikroTik RouterBOARD 750", ++ rb750_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tew-632brp.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tew-632brp.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,151 @@ +/* -+ * TP-LINK TL-WR841N board support ++ * TrendNET TEW-632BRP board support + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -7707,147 +6955,154 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c linux-2.6.39/arch/ + +#include "machtype.h" +#include "devices.h" -+#include "dev-dsa.h" +#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" -+#include "dev-pb42-pci.h" +#include "dev-leds-gpio.h" ++#include "nvram.h" + -+#define TL_WR841ND_V1_GPIO_LED_SYSTEM 2 -+#define TL_WR841ND_V1_GPIO_LED_QSS_GREEN 4 -+#define TL_WR841ND_V1_GPIO_LED_QSS_RED 5 ++#define TEW_632BRP_GPIO_LED_STATUS 1 ++#define TEW_632BRP_GPIO_LED_WPS 3 ++#define TEW_632BRP_GPIO_LED_WLAN 6 ++#define TEW_632BRP_GPIO_BTN_WPS 12 ++#define TEW_632BRP_GPIO_BTN_RESET 21 + -+#define TL_WR841ND_V1_GPIO_BTN_RESET 3 -+#define TL_WR841ND_V1_GPIO_BTN_QSS 7 ++#define TEW_632BRP_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TEW_632BRP_KEYS_DEBOUNCE_INTERVAL (3 * TEW_632BRP_KEYS_POLL_INTERVAL) + -+#define TL_WR841ND_V1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * TL_WR841ND_V1_KEYS_POLL_INTERVAL) ++#define TEW_632BRP_CONFIG_ADDR 0x1f020000 ++#define TEW_632BRP_CONFIG_SIZE 0x10000 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_wr841n_v1_partitions[] = { ++static struct mtd_partition tew_632brp_partitions[] = { + { -+ .name = "redboot", ++ .name = "u-boot", + .offset = 0, + .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "kernel", ++ .name = "config", + .offset = 0x020000, -+ .size = 0x140000, ++ .size = 0x010000, ++ }, { ++ .name = "kernel", ++ .offset = 0x030000, ++ .size = 0x0e0000, + }, { + .name = "rootfs", -+ .offset = 0x160000, -+ .size = 0x280000, ++ .offset = 0x110000, ++ .size = 0x2e0000, + }, { -+ .name = "config", -+ .offset = 0x3e0000, -+ .size = 0x020000, ++ .name = "art", ++ .offset = 0x3f0000, ++ .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", -+ .offset = 0x020000, ++ .offset = 0x030000, + .size = 0x3c0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data tl_wr841n_v1_flash_data = { ++static struct flash_platform_data tew_632brp_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tl_wr841n_v1_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wr841n_v1_partitions), ++ .parts = tew_632brp_partitions, ++ .nr_parts = ARRAY_SIZE(tew_632brp_partitions), +#endif +}; + -+static struct gpio_led tl_wr841n_v1_leds_gpio[] __initdata = { ++static struct gpio_led tew_632brp_leds_gpio[] __initdata = { + { -+ .name = "tl-wr841n:green:system", -+ .gpio = TL_WR841ND_V1_GPIO_LED_SYSTEM, ++ .name = "tew-632brp:green:status", ++ .gpio = TEW_632BRP_GPIO_LED_STATUS, + .active_low = 1, + }, { -+ .name = "tl-wr841n:red:qss", -+ .gpio = TL_WR841ND_V1_GPIO_LED_QSS_RED, ++ .name = "tew-632brp:blue:wps", ++ .gpio = TEW_632BRP_GPIO_LED_WPS, ++ .active_low = 1, + }, { -+ .name = "tl-wr841n:green:qss", -+ .gpio = TL_WR841ND_V1_GPIO_LED_QSS_GREEN, ++ .name = "tew-632brp:green:wlan", ++ .gpio = TEW_632BRP_GPIO_LED_WLAN, ++ .active_low = 1, + } +}; + -+static struct gpio_keys_button tl_wr841n_v1_gpio_keys[] __initdata = { ++static struct gpio_keys_button tew_632brp_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR841ND_V1_GPIO_BTN_RESET, -+ .active_low = 1, ++ .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TEW_632BRP_GPIO_BTN_RESET, + }, { -+ .desc = "qss", ++ .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR841ND_V1_GPIO_BTN_QSS, -+ .active_low = 1, ++ .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TEW_632BRP_GPIO_BTN_WPS, + } +}; + -+static struct dsa_chip_data tl_wr841n_v1_dsa_chip = { -+ .port_names[0] = "wan", -+ .port_names[1] = "lan1", -+ .port_names[2] = "lan2", -+ .port_names[3] = "lan3", -+ .port_names[4] = "lan4", -+ .port_names[5] = "cpu", -+}; -+ -+static struct dsa_platform_data tl_wr841n_v1_dsa_data = { -+ .nr_chips = 1, -+ .chip = &tl_wr841n_v1_dsa_chip, -+}; ++#define TEW_632BRP_LAN_PHYMASK BIT(0) ++#define TEW_632BRP_WAN_PHYMASK BIT(4) ++#define TEW_632BRP_MDIO_MASK (~(TEW_632BRP_LAN_PHYMASK | \ ++ TEW_632BRP_WAN_PHYMASK)) + -+static void __init tl_wr841n_v1_setup(void) ++static void __init tew_632brp_setup(void) +{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); ++ const char *config = (char *) KSEG1ADDR(TEW_632BRP_CONFIG_ADDR); ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 mac[6]; ++ u8 *wlan_mac = NULL; + -+ ar71xx_add_device_mdio(0x0); ++ if (nvram_parse_mac_addr(config, TEW_632BRP_CONFIG_SIZE, ++ "lan_mac=", mac) == 0) { ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ wlan_mac = mac; ++ } ++ ++ ar71xx_add_device_mdio(TEW_632BRP_MDIO_MASK); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = TEW_632BRP_LAN_PHYMASK; + -+ ar71xx_add_device_eth(0); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = TEW_632BRP_WAN_PHYMASK; + -+ ar71xx_add_device_dsa(0, &tl_wr841n_v1_dsa_data); ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ ar71xx_add_device_m25p80(&tl_wr841n_v1_flash_data); ++ ar71xx_add_device_m25p80(&tew_632brp_flash_data); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v1_leds_gpio), -+ tl_wr841n_v1_leds_gpio); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio), ++ tew_632brp_leds_gpio); + -+ ar71xx_register_gpio_keys_polled(-1, TL_WR841ND_V1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr841n_v1_gpio_keys), -+ tl_wr841n_v1_gpio_keys); ++ ar71xx_register_gpio_keys_polled(-1, TEW_632BRP_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tew_632brp_gpio_keys), ++ tew_632brp_gpio_keys); + -+ pb42_pci_init(); ++ ar9xxx_add_device_wmac(eeprom, wlan_mac); +} + -+MIPS_MACHINE(AR71XX_MACH_TL_WR841N_V1, "TL-WR841N-v1.5", "TP-LINK TL-WR841N v1", -+ tl_wr841n_v1_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c 2011-08-24 02:41:55.597982750 +0200 -@@ -0,0 +1,147 @@ ++MIPS_MACHINE(AR71XX_MACH_TEW_632BRP, "TEW-632BRP", "TRENDnet TEW-632BRP", ++ tew_632brp_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-mr3x20.c linux-2.6.39/arch/mips/ar71xx/mach-tl-mr3x20.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-mr3x20.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-mr3x20.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,166 @@ +/* -+ * TP-LINK TL-WR941ND board support ++ * TP-LINK TL-MR3220/3420 board support + * -+ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include +#include +#include + @@ -7855,25 +7110,26 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.39/arch + +#include "machtype.h" +#include "devices.h" -+#include "dev-dsa.h" +#include "dev-m25p80.h" -+#include "dev-ar9xxx-wmac.h" ++#include "dev-ap91-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+#define TL_WR941ND_GPIO_LED_SYSTEM 2 -+#define TL_WR941ND_GPIO_LED_QSS_RED 4 -+#define TL_WR941ND_GPIO_LED_QSS_GREEN 5 -+#define TL_WR941ND_GPIO_LED_WLAN 9 ++#define TL_MR3X20_GPIO_LED_QSS 0 ++#define TL_MR3X20_GPIO_LED_SYSTEM 1 ++#define TL_MR3X20_GPIO_LED_3G 8 + -+#define TL_WR941ND_GPIO_BTN_RESET 3 -+#define TL_WR941ND_GPIO_BTN_QSS 7 ++#define TL_MR3X20_GPIO_BTN_RESET 11 ++#define TL_MR3X20_GPIO_BTN_QSS 12 + -+#define TL_WR941ND_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR941ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR941ND_KEYS_POLL_INTERVAL) ++#define TL_MR3X20_GPIO_USB_POWER 6 ++ ++#define TL_MR3X20_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_MR3X20_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3X20_KEYS_POLL_INTERVAL) + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_wr941nd_partitions[] = { ++static struct mtd_partition tl_mr3x20_partitions[] = { + { + .name = "u-boot", + .offset = 0, @@ -7898,813 +7154,548 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.39/arch + .size = 0x3d0000, + } +}; ++#define tl_mr3x20_num_partitions ARRAY_SIZE(tl_mr3x20_partitions) ++#else ++#define tl_mr3x20_partitions NULL ++#define tl_mr3x20_num_partitions 0 +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data tl_wr941nd_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tl_wr941nd_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wr941nd_partitions), -+#endif ++static struct flash_platform_data tl_mr3x20_flash_data = { ++ .parts = tl_mr3x20_partitions, ++ .nr_parts = tl_mr3x20_num_partitions, +}; + -+static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = { ++static struct gpio_led tl_mr3x20_leds_gpio[] __initdata = { + { -+ .name = "tl-wr941nd:green:system", -+ .gpio = TL_WR941ND_GPIO_LED_SYSTEM, ++ .name = "tl-mr3x20:green:system", ++ .gpio = TL_MR3X20_GPIO_LED_SYSTEM, + .active_low = 1, + }, { -+ .name = "tl-wr941nd:red:qss", -+ .gpio = TL_WR941ND_GPIO_LED_QSS_RED, -+ }, { -+ .name = "tl-wr941nd:green:qss", -+ .gpio = TL_WR941ND_GPIO_LED_QSS_GREEN, ++ .name = "tl-mr3x20:green:qss", ++ .gpio = TL_MR3X20_GPIO_LED_QSS, ++ .active_low = 1, + }, { -+ .name = "tl-wr941nd:green:wlan", -+ .gpio = TL_WR941ND_GPIO_LED_WLAN, ++ .name = "tl-mr3x20:green:3g", ++ .gpio = TL_MR3X20_GPIO_LED_3G, + .active_low = 1, + } +}; + -+static struct gpio_keys_button tl_wr941nd_gpio_keys[] __initdata = { ++static struct gpio_keys_button tl_mr3x20_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR941ND_GPIO_BTN_RESET, ++ .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_MR3X20_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR941ND_GPIO_BTN_QSS, ++ .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_MR3X20_GPIO_BTN_QSS, + .active_low = 1, + } +}; + -+static struct dsa_chip_data tl_wr941nd_dsa_chip = { -+ .port_names[0] = "wan", -+ .port_names[1] = "lan1", -+ .port_names[2] = "lan2", -+ .port_names[3] = "lan3", -+ .port_names[4] = "lan4", -+ .port_names[5] = "cpu", -+}; -+ -+static struct dsa_platform_data tl_wr941nd_dsa_data = { -+ .nr_chips = 1, -+ .chip = &tl_wr941nd_dsa_chip, -+}; -+ -+static void __init tl_wr941nd_setup(void) ++static void __init tl_mr3x20_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_add_device_mdio(0x0); ++ /* enable power for the USB port */ ++ gpio_request(TL_MR3X20_GPIO_USB_POWER, "USB power"); ++ gpio_direction_output(TL_MR3X20_GPIO_USB_POWER, 1); ++ ++ ar71xx_add_device_m25p80(&tl_mr3x20_flash_data); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_mr3x20_leds_gpio), ++ tl_mr3x20_leds_gpio); + ++ ar71xx_register_gpio_keys_polled(-1, TL_MR3X20_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_mr3x20_gpio_keys), ++ tl_mr3x20_gpio_keys); ++ ++ ar71xx_eth1_data.has_ar7240_switch = 1; + ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ ++ /* WAN port */ + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = BIT(4); + -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_dsa(0, &tl_wr941nd_dsa_data); ++ /* LAN ports */ ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; + -+ ar71xx_add_device_m25p80(&tl_wr941nd_flash_data); ++ ar71xx_add_device_mdio(0x0); ++ ar71xx_add_device_eth(1); ++ ar71xx_add_device_eth(0); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio), -+ tl_wr941nd_leds_gpio); ++ ar71xx_add_device_usb(); + -+ ar71xx_register_gpio_keys_polled(-1, TL_WR941ND_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr941nd_gpio_keys), -+ tl_wr941nd_gpio_keys); -+ ar9xxx_add_device_wmac(eeprom, mac); ++ ap91_pci_init(ee, mac); +} + -+MIPS_MACHINE(AR71XX_MACH_TL_WR941ND, "TL-WR941ND", "TP-LINK TL-WR941ND", -+ tl_wr941nd_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/machtype.h linux-2.6.39/arch/mips/ar71xx/machtype.h ---- linux-2.6.39.orig/arch/mips/ar71xx/machtype.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/machtype.h 2011-08-24 02:41:55.597982750 +0200 -@@ -0,0 +1,75 @@ -+/* -+ * Atheros AR71xx machine type definitions -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _AR71XX_MACHTYPE_H -+#define _AR71XX_MACHTYPE_H ++static void __init tl_mr3220_setup(void) ++{ ++ tl_mr3x20_setup(); ++ ap91_pci_setup_wmac_led_pin(1); ++} + -+#include ++MIPS_MACHINE(AR71XX_MACH_TL_MR3220, "TL-MR3220", "TP-LINK TL-MR3220", ++ tl_mr3220_setup); + -+enum ar71xx_mach_type { -+ AR71XX_MACH_GENERIC = 0, -+ AR71XX_MACH_AP121, /* Atheros AP121 */ -+ AR71XX_MACH_AP121_MINI, /* Atheros AP121-MINI */ -+ AR71XX_MACH_AP81, /* Atheros AP81 */ -+ AR71XX_MACH_AP83, /* Atheros AP83 */ -+ AR71XX_MACH_AW_NR580, /* AzureWave AW-NR580 */ -+ AR71XX_MACH_DIR_600_A1, /* D-Link DIR-600 rev. A1 */ -+ AR71XX_MACH_DIR_615_C1, /* D-Link DIR-615 rev. C1 */ -+ AR71XX_MACH_DIR_825_B1, /* D-Link DIR-825 rev. B1 */ -+ AR71XX_MACH_JA76PF, /* jjPlus JA76PF */ -+ AR71XX_MACH_JWAP003, /* jjPlus JWAP003 */ -+ AR71XX_MACH_RB_411, /* MikroTik RouterBOARD 411/411A/411AH */ -+ AR71XX_MACH_RB_411U, /* MikroTik RouterBOARD 411U */ -+ AR71XX_MACH_RB_433, /* MikroTik RouterBOARD 433/433AH */ -+ AR71XX_MACH_RB_433U, /* MikroTik RouterBOARD 433UAH */ -+ AR71XX_MACH_RB_450, /* MikroTik RouterBOARD 450 */ -+ AR71XX_MACH_RB_450G, /* MikroTik RouterBOARD 450G */ -+ AR71XX_MACH_RB_493, /* Mikrotik RouterBOARD 493/493AH */ -+ AR71XX_MACH_RB_750, /* MikroTik RouterBOARD 750 */ -+ AR71XX_MACH_PB42, /* Atheros PB42 */ -+ AR71XX_MACH_PB44, /* Atheros PB44 */ -+ AR71XX_MACH_PB92, /* Atheros PB92 */ -+ AR71XX_MACH_MZK_W04NU, /* Planex MZK-W04NU */ -+ AR71XX_MACH_MZK_W300NH, /* Planex MZK-W300NH */ -+ AR71XX_MACH_NBG460N, /* Zyxel NBG460N/550N/550NH */ -+ AR71XX_MACH_TEW_632BRP, /* TRENDnet TEW-632BRP */ -+ AR71XX_MACH_TL_MR3220, /* TP-LINK TL-MR3220 */ -+ AR71XX_MACH_TL_MR3420, /* TP-LINK TL-MR3420 */ -+ AR71XX_MACH_TL_WA901ND, /* TP-LINK TL-WA901ND */ -+ AR71XX_MACH_TL_WA901ND_V2, /* TP-LINK TL-WA901ND v2 */ -+ AR71XX_MACH_TL_WR741ND, /* TP-LINK TL-WR741ND */ -+ AR71XX_MACH_TL_WR841N_V1, /* TP-LINK TL-WR841N v1 */ -+ AR71XX_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ -+ AR71XX_MACH_TL_WR1043ND, /* TP-LINK TL-WR1041ND */ -+ AR71XX_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */ -+ AR71XX_MACH_UBNT_LSX, /* Ubiquiti LSX */ -+ AR71XX_MACH_UBNT_RS, /* Ubiquiti RouterStation */ -+ AR71XX_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */ -+ AR71XX_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ -+ AR71XX_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */ -+ AR71XX_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */ -+ AR71XX_MACH_WNDR3700, /* NETGEAR WNDR3700 */ -+ AR71XX_MACH_WNDR3700V2, /* NETGEAR WNDR3700v2 */ -+ AR71XX_MACH_WNR2000, /* NETGEAR WNR2000 */ -+ AR71XX_MACH_WP543, /* Compex WP543 */ -+ AR71XX_MACH_WRT160NL, /* Linksys WRT160NL */ -+ AR71XX_MACH_WRT400N, /* Linksys WRT400N */ -+ AR71XX_MACH_WZR_HP_AG300H, /* Buffalo WZR-HP-AG300H */ -+ AR71XX_MACH_WZR_HP_G300NH, /* Buffalo WZR-HP-G300NH */ -+ AR71XX_MACH_EAP7660D, /* Senao EAP7660D */ -+ AR71XX_MACH_ZCN_1523H_2, /* Zcomax ZCN-1523H-2-xx */ -+ AR71XX_MACH_ZCN_1523H_5, /* Zcomax ZCN-1523H-5-xx */ -+ AR71XX_MACH_AP96, /* Atheros AP96 */ -+ AR71XX_MACH_UBNT_UNIFI, /* Unifi */ -+ AR71XX_MACH_DB120, /* Atheros DB120 (AR934x based) */ -+}; ++static void __init tl_mr3420_setup(void) ++{ ++ tl_mr3x20_setup(); ++ ap91_pci_setup_wmac_led_pin(0); ++} + -+#endif /* _AR71XX_MACHTYPE_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c 2011-08-24 02:41:55.597982750 +0200 -@@ -0,0 +1,333 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_MR3420, "TL-MR3420", "TP-LINK TL-MR3420", ++ tl_mr3420_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd-v2.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd-v2.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd-v2.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd-v2.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,132 @@ +/* -+ * Ubiquiti RouterStation support ++ * TP-LINK TL-WA901ND v2 board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2008 Ubiquiti ++ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2010 Pieter Hollants ++ * Copyright (C) 2011 Jonathan Bennett + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#include ++#include ++ +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ap91-pci.h" +#include "dev-gpio-buttons.h" -+#include "dev-pb42-pci.h" +#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+ -+#define UBNT_RS_GPIO_LED_RF 2 -+#define UBNT_RS_GPIO_SW4 8 -+ -+#define UBNT_LS_SR71_GPIO_LED_D25 0 -+#define UBNT_LS_SR71_GPIO_LED_D26 1 -+#define UBNT_LS_SR71_GPIO_LED_D24 2 -+#define UBNT_LS_SR71_GPIO_LED_D23 4 -+#define UBNT_LS_SR71_GPIO_LED_D22 5 -+#define UBNT_LS_SR71_GPIO_LED_D27 6 -+#define UBNT_LS_SR71_GPIO_LED_D28 7 ++#include "dev-ar9xxx-wmac.h" + -+#define UBNT_M_GPIO_LED_L1 0 -+#define UBNT_M_GPIO_LED_L2 1 -+#define UBNT_M_GPIO_LED_L3 11 -+#define UBNT_M_GPIO_LED_L4 7 -+#define UBNT_M_GPIO_BTN_RESET 12 ++#define TL_WA901ND_V2_GPIO_LED_QSS 4 ++#define TL_WA901ND_V2_GPIO_LED_SYSTEM 2 ++#define TL_WA901ND_V2_GPIO_LED_WLAN 9 + -+#define UBNT_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define UBNT_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_KEYS_POLL_INTERVAL) + -+static struct gpio_led ubnt_rs_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:green:rf", -+ .gpio = UBNT_RS_GPIO_LED_RF, -+ .active_low = 0, -+ } -+}; ++#define TL_WA901ND_V2_GPIO_BTN_RESET 3 ++#define TL_WA901ND_V2_GPIO_BTN_QSS 7 + -+static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = { ++#define TL_WA901ND_V2_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL \ ++ (3 * TL_WA901ND_V2_KEYS_POLL_INTERVAL) ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition tl_wa901nd_v2_partitions[] = { + { -+ .name = "ubnt:green:d22", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D22, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d23", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D23, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d24", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D24, -+ .active_low = 0, ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "ubnt:red:d25", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D25, -+ .active_low = 0, ++ .name = "kernel", ++ .offset = 0x020000, ++ .size = 0x140000, + }, { -+ .name = "ubnt:red:d26", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D26, -+ .active_low = 0, ++ .name = "rootfs", ++ .offset = 0x160000, ++ .size = 0x290000, + }, { -+ .name = "ubnt:green:d27", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D27, -+ .active_low = 0, ++ .name = "art", ++ .offset = 0x3f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "ubnt:green:d28", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D28, -+ .active_low = 0, ++ .name = "firmware", ++ .offset = 0x020000, ++ .size = 0x3d0000, + } +}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct gpio_led ubnt_m_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:red:link1", -+ .gpio = UBNT_M_GPIO_LED_L1, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:orange:link2", -+ .gpio = UBNT_M_GPIO_LED_L2, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:link3", -+ .gpio = UBNT_M_GPIO_LED_L3, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:link4", -+ .gpio = UBNT_M_GPIO_LED_L4, -+ .active_low = 0, -+ } ++static struct flash_platform_data tl_wa901nd_v2_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = tl_wa901nd_v2_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wa901nd_v2_partitions), ++#endif +}; + -+static struct gpio_keys_button ubnt_gpio_keys[] __initdata = { ++static struct gpio_led tl_wa901nd_v2_leds_gpio[] __initdata = { + { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = UBNT_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = UBNT_RS_GPIO_SW4, ++ .name = "tl-wa901nd-v2:green:system", ++ .gpio = TL_WA901ND_V2_GPIO_LED_SYSTEM, ++ .active_low = 1, ++ }, { ++ .name = "tl-wa901nd-v2:green:qss", ++ .gpio = TL_WA901ND_V2_GPIO_LED_QSS, ++ }, { ++ .name = "tl-wa901nd-v2:green:wlan", ++ .gpio = TL_WA901ND_V2_GPIO_LED_WLAN, + .active_low = 1, + } +}; + -+static struct gpio_keys_button ubnt_m_gpio_keys[] __initdata = { ++static struct gpio_keys_button tl_wa901nd_v2_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = UBNT_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = UBNT_M_GPIO_BTN_RESET, ++ .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WA901ND_V2_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "qss", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WA901ND_V2_GPIO_BTN_QSS, + .active_low = 1, + } +}; + -+static void __init ubnt_generic_setup(void) ++static void __init tl_wa901nd_v2_setup(void) +{ -+ ar71xx_add_device_m25p80(NULL); -+ -+ ar71xx_register_gpio_keys_polled(-1, UBNT_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_gpio_keys), -+ ubnt_gpio_keys); -+ -+ pb42_pci_init(); -+} -+ -+/* -+ * There is Secondary MAC address duplicate problem with some UBNT HW batches. -+ * Do not increase Secondary MAC address by 1 but do workaround -+ * with 'Locally Administrated' bit. -+ */ -+static void __init ubnt_init_secondary_mac(unsigned char *mac_base) -+{ -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac_base, 0); -+ ar71xx_eth1_data.mac_addr[0] |= 0x02; -+} -+ -+#define UBNT_RS_WAN_PHYMASK BIT(20) -+#define UBNT_RS_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19)) -+ -+static void __init ubnt_rs_setup(void) -+{ -+ ubnt_generic_setup(); -+ -+ ar71xx_add_device_mdio(~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK)); -+ -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK; -+ -+ ubnt_init_secondary_mac(ar71xx_mac_base); -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_100; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; -+ -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); -+ -+ ar71xx_add_device_usb(); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), -+ ubnt_rs_leds_gpio); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_UBNT_RS, "UBNT-RS", "Ubiquiti RouterStation", -+ ubnt_rs_setup); -+ -+#define UBNT_RSPRO_WAN_PHYMASK BIT(4) -+#define UBNT_RSPRO_LAN_PHYMASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) -+ -+static void __init ubnt_rspro_setup(void) -+{ -+ ubnt_generic_setup(); -+ -+ ar71xx_add_device_mdio(~(UBNT_RSPRO_WAN_PHYMASK | -+ UBNT_RSPRO_LAN_PHYMASK)); -+ -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.phy_mask = UBNT_RSPRO_WAN_PHYMASK; -+ -+ ubnt_init_secondary_mac(ar71xx_mac_base); -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = UBNT_RSPRO_LAN_PHYMASK; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; -+ -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); -+ -+ ar71xx_add_device_usb(); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), -+ ubnt_rs_leds_gpio); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_UBNT_RSPRO, "UBNT-RSPRO", "Ubiquiti RouterStation Pro", -+ ubnt_rspro_setup); -+ -+static void __init ubnt_lsx_setup(void) -+{ -+ ubnt_generic_setup(); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_UBNT_LSX, "UBNT-LSX", "Ubiquiti LSX", ubnt_lsx_setup); -+ -+#define UBNT_LSSR71_PHY_MASK BIT(1) -+ -+static void __init ubnt_lssr71_setup(void) -+{ -+ ubnt_generic_setup(); ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_add_device_mdio(~UBNT_LSSR71_PHY_MASK); ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK; -+ -+ ar71xx_add_device_eth(0); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio), -+ ubnt_ls_sr71_leds_gpio); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_UBNT_LSSR71, "UBNT-LS-SR71", "Ubiquiti LS-SR71", -+ ubnt_lssr71_setup); -+ -+#define UBNT_M_WAN_PHYMASK BIT(4) -+ -+static void __init ubnt_m_setup(void) -+{ -+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ar71xx_add_device_m25p80(NULL); -+ -+ ar71xx_add_device_mdio(~UBNT_M_WAN_PHYMASK); -+ -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac1, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac2, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.phy_mask = UBNT_M_WAN_PHYMASK; ++ ar71xx_eth0_data.phy_mask = 0x00001000; ++ ar71xx_add_device_mdio(0x0); + ++ ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC | ++ RESET_MODULE_GE0_PHY; + ar71xx_add_device_eth(0); + -+ ap91_pci_init(ee, NULL); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_m_leds_gpio), -+ ubnt_m_leds_gpio); -+ -+ ar71xx_register_gpio_keys_polled(-1, UBNT_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_m_gpio_keys), -+ ubnt_m_gpio_keys); -+} -+ -+static void __init ubnt_rocket_m_setup(void) -+{ -+ ubnt_m_setup(); -+ ar71xx_add_device_usb(); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_UBNT_BULLET_M, "UBNT-BM", "Ubiquiti Bullet M", -+ ubnt_m_setup); -+MIPS_MACHINE(AR71XX_MACH_UBNT_ROCKET_M, "UBNT-RM", "Ubiquiti Rocket M", -+ ubnt_rocket_m_setup); -+ -+/* TODO detect the second ethernet port and use one -+ init function for all Ubiquiti MIMO series products */ -+static void __init ubnt_nano_m_setup(void) -+{ -+ ubnt_m_setup(); -+ -+ ar71xx_eth1_data.has_ar7240_switch = 1; -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; -+ -+ ar71xx_add_device_eth(1); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_UBNT_NANO_M, "UBNT-NM", "Ubiquiti Nanostation M", -+ ubnt_nano_m_setup); -+ -+static struct gpio_led ubnt_unifi_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:orange:dome", -+ .gpio = 1, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:dome", -+ .gpio = 0, -+ .active_low = 0, -+ } -+}; -+ -+static void __init ubnt_unifi_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ar71xx_add_device_m25p80(NULL); -+ -+ ar71xx_add_device_mdio(~UBNT_M_WAN_PHYMASK); -+ -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.phy_mask = UBNT_M_WAN_PHYMASK; ++ ar71xx_add_device_m25p80(&tl_wa901nd_v2_flash_data); + -+ ar71xx_add_device_eth(0); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_v2_leds_gpio), ++ tl_wa901nd_v2_leds_gpio); + -+ ap91_pci_init(ee, NULL); ++ ar71xx_register_gpio_keys_polled(-1, TL_WA901ND_V2_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wa901nd_v2_gpio_keys), ++ tl_wa901nd_v2_gpio_keys); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_leds_gpio), -+ ubnt_unifi_leds_gpio); ++ ar9xxx_add_device_wmac(eeprom, mac); +} + -+MIPS_MACHINE(AR71XX_MACH_UBNT_UNIFI, "UBNT-XM", "Ubiquiti UniFi", -+ ubnt_unifi_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c 2011-08-24 02:41:55.607980283 +0200 -@@ -0,0 +1,290 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_WA901ND_V2, "TL-WA901ND-v2", ++ "TP-LINK TL-WA901ND v2", tl_wa901nd_v2_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wa901nd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wa901nd.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,130 @@ +/* -+ * Netgear WNDR3700 board support ++ * TP-LINK TL-WA901ND board support + * -+ * Copyright (C) 2009 Marco Porsch + * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2010 Pieter Hollants + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include +#include +#include -+#include -+#include + +#include + +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ap94-pci.h" ++#include "dev-ap91-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+ -+#define WNDR3700_GPIO_LED_WPS_ORANGE 0 -+#define WNDR3700_GPIO_LED_POWER_ORANGE 1 -+#define WNDR3700_GPIO_LED_POWER_GREEN 2 -+#define WNDR3700_GPIO_LED_WPS_GREEN 4 -+#define WNDR3700_GPIO_LED_WAN_GREEN 6 -+ -+#define WNDR3700_GPIO_BTN_WPS 3 -+#define WNDR3700_GPIO_BTN_RESET 8 -+#define WNDR3700_GPIO_BTN_WIFI 11 -+ -+#define WNDR3700_GPIO_RTL8366_SDA 5 -+#define WNDR3700_GPIO_RTL8366_SCK 7 + -+#define WNDR3700_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WNDR3700_KEYS_DEBOUNCE_INTERVAL (3 * WNDR3700_KEYS_POLL_INTERVAL) ++#define TL_WA901ND_GPIO_LED_QSS 0 ++#define TL_WA901ND_GPIO_LED_SYSTEM 1 + -+#define WNDR3700_ETH0_MAC_OFFSET 0 -+#define WNDR3700_ETH1_MAC_OFFSET 0x6 ++#define TL_WA901ND_GPIO_BTN_RESET 11 ++#define TL_WA901ND_GPIO_BTN_QSS 12 + -+#define WNDR3700_WMAC0_MAC_OFFSET 0 -+#define WNDR3700_WMAC1_MAC_OFFSET 0xc -+#define WNDR3700_CALDATA0_OFFSET 0x1000 -+#define WNDR3700_CALDATA1_OFFSET 0x5000 ++#define TL_WA901ND_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WA901ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WA901ND_KEYS_POLL_INTERVAL) + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wndr3700_partitions[] = { ++static struct mtd_partition tl_wa901nd_partitions[] = { + { -+ .name = "uboot", ++ .name = "u-boot", + .offset = 0, -+ .size = 0x050000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "env", -+ .offset = 0x050000, + .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "rootfs", -+ .offset = 0x070000, -+ .size = 0x720000, -+ }, { -+ .name = "config", -+ .offset = 0x790000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "kernel", ++ .offset = 0x020000, ++ .size = 0x140000, + }, { -+ .name = "config_bak", -+ .offset = 0x7a0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "rootfs", ++ .offset = 0x160000, ++ .size = 0x290000, + }, { -+ .name = "pot", -+ .offset = 0x7b0000, ++ .name = "art", ++ .offset = 0x3f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "traffic_meter", -+ .offset = 0x7c0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "firmware", ++ .offset = 0x020000, ++ .size = 0x3d0000, ++ } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ ++ ++static struct flash_platform_data tl_wa901nd_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = tl_wa901nd_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wa901nd_partitions), ++#endif ++}; ++ ++static struct gpio_led tl_wa901nd_leds_gpio[] __initdata = { ++ { ++ .name = "tl-wa901nd:green:system", ++ .gpio = TL_WA901ND_GPIO_LED_SYSTEM, ++ .active_low = 1, + }, { -+ .name = "language", -+ .offset = 0x7d0000, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "tl-wa901nd:green:qss", ++ .gpio = TL_WA901ND_GPIO_LED_QSS, ++ .active_low = 1, ++ } ++}; ++ ++static struct gpio_keys_button tl_wa901nd_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = BTN_0, ++ .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WA901ND_GPIO_BTN_RESET, ++ .active_low = 1, + }, { -+ .name = "caldata", -+ .offset = 0x7f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .desc = "qss", ++ .type = EV_KEY, ++ .code = BTN_1, ++ .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WA901ND_GPIO_BTN_QSS, ++ .active_low = 1, + } +}; + -+static struct mtd_partition wndr3700v2_partitions[] = { ++static void __init tl_wa901nd_setup(void) ++{ ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); ++ ++ /* ++ * ar71xx_eth0 would be the WAN port, but is not connected on ++ * the TL-WA901ND. ar71xx_eth1 connects to the internal switch chip, ++ * however we have a single LAN port only. ++ */ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 0); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_eth1_data.has_ar7240_switch = 1; ++ ++ ar71xx_add_device_mdio(0x0); ++ ar71xx_add_device_eth(1); ++ ++ ar71xx_add_device_m25p80(&tl_wa901nd_flash_data); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_leds_gpio), ++ tl_wa901nd_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, TL_WA901ND_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wa901nd_gpio_keys), ++ tl_wa901nd_gpio_keys); ++ ++ ap91_pci_init(ee, mac); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_TL_WA901ND, "TL-WA901ND", "TP-LINK TL-WA901ND", ++ tl_wa901nd_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr1043nd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr1043nd.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,156 @@ ++/* ++ * TP-LINK TL-WR1043ND board support ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "machtype.h" ++#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-ar9xxx-wmac.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-usb.h" ++ ++#define TL_WR1043ND_GPIO_LED_USB 1 ++#define TL_WR1043ND_GPIO_LED_SYSTEM 2 ++#define TL_WR1043ND_GPIO_LED_QSS 5 ++#define TL_WR1043ND_GPIO_LED_WLAN 9 ++ ++#define TL_WR1043ND_GPIO_BTN_RESET 3 ++#define TL_WR1043ND_GPIO_BTN_QSS 7 ++ ++#define TL_WR1043ND_GPIO_RTL8366_SDA 18 ++#define TL_WR1043ND_GPIO_RTL8366_SCK 19 ++ ++#define TL_WR1043ND_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR1043ND_KEYS_POLL_INTERVAL) ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition tl_wr1043nd_partitions[] = { + { -+ .name = "uboot", ++ .name = "u-boot", + .offset = 0, -+ .size = 0x050000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "env", -+ .offset = 0x050000, + .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "rootfs", -+ .offset = 0x070000, -+ .size = 0xe40000, -+ }, { -+ .name = "config", -+ .offset = 0xeb0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "config_bak", -+ .offset = 0xec0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "kernel", ++ .offset = 0x020000, ++ .size = 0x140000, + }, { -+ .name = "pot", -+ .offset = 0xed0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "rootfs", ++ .offset = 0x160000, ++ .size = 0x690000, + }, { -+ .name = "traffic_meter", -+ .offset = 0xee0000, ++ .name = "art", ++ .offset = 0x7f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "language", -+ .offset = 0xef0000, -+ .size = 0x100000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "caldata", -+ .offset = 0xff0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "firmware", ++ .offset = 0x020000, ++ .size = 0x7d0000, + } +}; -+#define wndr3700_num_partitions ARRAY_SIZE(wndr3700_partitions) -+#define wndr3700v2_num_partitions ARRAY_SIZE(wndr3700v2_partitions) -+#else -+#define wndr3700_partitions NULL -+#define wndr3700_num_partitions 0 -+#define wndr3700v2_partitions NULL -+#define wndr3700v2_num_partitions 0 +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data wndr3700_flash_data; ++static struct flash_platform_data tl_wr1043nd_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = tl_wr1043nd_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wr1043nd_partitions), ++#endif ++}; + -+static struct gpio_led wndr3700_leds_gpio[] __initdata = { ++static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = { + { -+ .name = "wndr3700:green:power", -+ .gpio = WNDR3700_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "wndr3700:orange:power", -+ .gpio = WNDR3700_GPIO_LED_POWER_ORANGE, ++ .name = "tl-wr1043nd:green:usb", ++ .gpio = TL_WR1043ND_GPIO_LED_USB, + .active_low = 1, + }, { -+ .name = "wndr3700:green:wps", -+ .gpio = WNDR3700_GPIO_LED_WPS_GREEN, ++ .name = "tl-wr1043nd:green:system", ++ .gpio = TL_WR1043ND_GPIO_LED_SYSTEM, + .active_low = 1, + }, { -+ .name = "wndr3700:orange:wps", -+ .gpio = WNDR3700_GPIO_LED_WPS_ORANGE, -+ .active_low = 1, ++ .name = "tl-wr1043nd:green:qss", ++ .gpio = TL_WR1043ND_GPIO_LED_QSS, ++ .active_low = 0, + }, { -+ .name = "wndr3700:green:wan", -+ .gpio = WNDR3700_GPIO_LED_WAN_GREEN, ++ .name = "tl-wr1043nd:green:wlan", ++ .gpio = TL_WR1043ND_GPIO_LED_WLAN, + .active_low = 1, + } +}; + -+static struct gpio_keys_button wndr3700_gpio_keys[] __initdata = { ++static struct gpio_keys_button tl_wr1043nd_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNDR3700_GPIO_BTN_RESET, ++ .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR1043ND_GPIO_BTN_RESET, + .active_low = 1, + }, { -+ .desc = "wps", ++ .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNDR3700_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, { -+ .desc = "wifi", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNDR3700_GPIO_BTN_WIFI, ++ .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR1043ND_GPIO_BTN_QSS, + .active_low = 1, + } +}; + -+static struct rtl8366_platform_data wndr3700_rtl8366s_data = { -+ .gpio_sda = WNDR3700_GPIO_RTL8366_SDA, -+ .gpio_sck = WNDR3700_GPIO_RTL8366_SCK, ++static struct rtl8366_platform_data tl_wr1043nd_rtl8366rb_data = { ++ .gpio_sda = TL_WR1043ND_GPIO_RTL8366_SDA, ++ .gpio_sck = TL_WR1043ND_GPIO_RTL8366_SCK, +}; + -+static struct platform_device wndr3700_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, ++static struct platform_device tl_wr1043nd_rtl8366rb_device = { ++ .name = RTL8366RB_DRIVER_NAME, + .id = -1, + .dev = { -+ .platform_data = &wndr3700_rtl8366s_data, ++ .platform_data = &tl_wr1043nd_rtl8366rb_data, + } +}; + -+static void __init wndr3700_common_setup(void) ++static void __init tl_wr1043nd_setup(void) +{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, -+ art + WNDR3700_ETH0_MAC_OFFSET, 0); -+ ar71xx_eth0_pll_data.pll_1000 = 0x11110000; -+ ar71xx_eth0_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_eth0_data.mii_bus_dev = &tl_wr1043nd_rtl8366rb_device.dev; + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ar71xx_eth0_data.speed = SPEED_1000; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, -+ art + WNDR3700_ETH1_MAC_OFFSET, 0); -+ ar71xx_eth1_pll_data.pll_1000 = 0x11110000; -+ ar71xx_eth1_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++ ar71xx_eth0_pll_data.pll_1000 = 0x1a000000; + + ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); + + ar71xx_add_device_usb(); + -+ ar71xx_add_device_m25p80(&wndr3700_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wndr3700_leds_gpio), -+ wndr3700_leds_gpio); -+ -+ ar71xx_register_gpio_keys_polled(-1, WNDR3700_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wndr3700_gpio_keys), -+ wndr3700_gpio_keys); -+ -+ platform_device_register(&wndr3700_rtl8366s_device); -+ platform_device_register_simple("wndr3700-led-usb", -1, NULL, 0); -+ -+ ap94_pci_setup_wmac_led_pin(0, 5); -+ ap94_pci_setup_wmac_led_pin(1, 5); -+ -+ /* 2.4 GHz uses the first fixed antenna group (1, 0, 1, 0) */ -+ ap94_pci_setup_wmac_gpio(0, (0xf << 6), (0xa << 6)); -+ -+ /* 5 GHz uses the second fixed antenna group (0, 1, 1, 0) */ -+ ap94_pci_setup_wmac_gpio(1, (0xf << 6), (0x6 << 6)); ++ ar71xx_add_device_m25p80(&tl_wr1043nd_flash_data); + -+ ap94_pci_init(art + WNDR3700_CALDATA0_OFFSET, -+ art + WNDR3700_WMAC0_MAC_OFFSET, -+ art + WNDR3700_CALDATA1_OFFSET, -+ art + WNDR3700_WMAC1_MAC_OFFSET); -+} ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr1043nd_leds_gpio), ++ tl_wr1043nd_leds_gpio); + -+static void __init wndr3700_setup(void) -+{ -+ wndr3700_flash_data.parts = wndr3700_partitions, -+ wndr3700_flash_data.nr_parts = wndr3700_num_partitions, -+ wndr3700_common_setup(); -+} ++ platform_device_register(&tl_wr1043nd_rtl8366rb_device); + -+MIPS_MACHINE(AR71XX_MACH_WNDR3700, "WNDR3700", "NETGEAR WNDR3700", -+ wndr3700_setup); ++ ar71xx_register_gpio_keys_polled(-1, TL_WR1043ND_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wr1043nd_gpio_keys), ++ tl_wr1043nd_gpio_keys); + -+static void __init wndr3700v2_setup(void) -+{ -+ wndr3700_flash_data.parts = wndr3700v2_partitions, -+ wndr3700_flash_data.nr_parts = wndr3700v2_num_partitions, -+ wndr3700_common_setup(); ++ ar9xxx_add_device_wmac(eeprom, mac); +} + -+MIPS_MACHINE(AR71XX_MACH_WNDR3700V2, "WNDR3700v2", "NETGEAR WNDR3700v2", -+ wndr3700v2_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c 2011-08-24 02:41:55.617990333 +0200 -@@ -0,0 +1,150 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_WR1043ND, "TL-WR1043ND", "TP-LINK TL-WR1043ND", ++ tl_wr1043nd_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr741nd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr741nd.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,135 @@ +/* -+ * NETGEAR WNR2000 board support ++ * TP-LINK TL-WR741ND board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2008-2009 Andy Boyett ++ * Copyright (C) 2009-2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -8719,145 +7710,131 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.39/arch/mi +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ar9xxx-wmac.h" ++#include "dev-ap91-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" + -+#define WNR2000_GPIO_LED_PWR_GREEN 14 -+#define WNR2000_GPIO_LED_PWR_AMBER 7 -+#define WNR2000_GPIO_LED_WPS 4 -+#define WNR2000_GPIO_LED_WLAN 6 -+#define WNR2000_GPIO_BTN_RESET 21 -+#define WNR2000_GPIO_BTN_WPS 8 ++#define TL_WR741ND_GPIO_LED_QSS 0 ++#define TL_WR741ND_GPIO_LED_SYSTEM 1 + -+#define WNR2000_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WNR2000_KEYS_DEBOUNCE_INTERVAL (3 * WNR2000_KEYS_POLL_INTERVAL) ++#define TL_WR741ND_GPIO_BTN_RESET 11 ++#define TL_WR741ND_GPIO_BTN_QSS 12 ++ ++#define TL_WR741ND_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WR741ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR741ND_KEYS_POLL_INTERVAL) + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wnr2000_partitions[] = { ++static struct mtd_partition tl_wr741nd_partitions[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x040000, ++ .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "u-boot-env", -+ .offset = 0x040000, -+ .size = 0x010000, ++ .name = "kernel", ++ .offset = 0x020000, ++ .size = 0x140000, + }, { + .name = "rootfs", -+ .offset = 0x050000, -+ .size = 0x240000, -+ }, { -+ .name = "user-config", -+ .offset = 0x290000, -+ .size = 0x010000, -+ }, { -+ .name = "uImage", -+ .offset = 0x2a0000, -+ .size = 0x120000, -+ }, { -+ .name = "language_table", -+ .offset = 0x3c0000, -+ .size = 0x020000, -+ }, { -+ .name = "rootfs_checksum", -+ .offset = 0x3e0000, -+ .size = 0x010000, ++ .offset = 0x160000, ++ .size = 0x290000, + }, { + .name = "art", + .offset = 0x3f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x020000, ++ .size = 0x3d0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data wnr2000_flash_data = { ++static struct flash_platform_data tl_wr741nd_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = wnr2000_partitions, -+ .nr_parts = ARRAY_SIZE(wnr2000_partitions), ++ .parts = tl_wr741nd_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wr741nd_partitions), +#endif +}; + -+static struct gpio_led wnr2000_leds_gpio[] __initdata = { ++static struct gpio_led tl_wr741nd_leds_gpio[] __initdata = { + { -+ .name = "wnr2000:green:power", -+ .gpio = WNR2000_GPIO_LED_PWR_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "wnr2000:amber:power", -+ .gpio = WNR2000_GPIO_LED_PWR_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "wnr2000:green:wps", -+ .gpio = WNR2000_GPIO_LED_WPS, ++ .name = "tl-wr741nd:green:system", ++ .gpio = TL_WR741ND_GPIO_LED_SYSTEM, + .active_low = 1, + }, { -+ .name = "wnr2000:blue:wlan", -+ .gpio = WNR2000_GPIO_LED_WLAN, ++ .name = "tl-wr741nd:green:qss", ++ .gpio = TL_WR741ND_GPIO_LED_QSS, + .active_low = 1, + } +}; + -+static struct gpio_keys_button wnr2000_gpio_keys[] __initdata = { ++static struct gpio_keys_button tl_wr741nd_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2000_GPIO_BTN_RESET, ++ .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR741ND_GPIO_BTN_RESET, ++ .active_low = 1, + }, { -+ .desc = "wps", ++ .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2000_GPIO_BTN_WPS, ++ .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR741ND_GPIO_BTN_QSS, ++ .active_low = 1, + } +}; + -+static void __init wnr2000_setup(void) ++static void __init tl_wr741nd_setup(void) +{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + -+ ar71xx_add_device_mdio(0x0); ++ ar71xx_add_device_m25p80(&tl_wr741nd_flash_data); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr741nd_leds_gpio), ++ tl_wr741nd_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, TL_WR741ND_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wr741nd_gpio_keys), ++ tl_wr741nd_gpio_keys); ++ ++ ar71xx_eth1_data.has_ar7240_switch = 1; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ ++ /* WAN port */ + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.has_ar8216 = 1; ++ ar71xx_eth0_data.phy_mask = BIT(4); + -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); ++ /* LAN ports */ + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; + -+ ar71xx_add_device_eth(0); ++ ar71xx_add_device_mdio(0x0); + ar71xx_add_device_eth(1); ++ ar71xx_add_device_eth(0); + -+ ar71xx_add_device_m25p80(&wnr2000_flash_data); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio), -+ wnr2000_leds_gpio); -+ -+ ar71xx_register_gpio_keys_polled(-1, WNR2000_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wnr2000_gpio_keys), -+ wnr2000_gpio_keys); -+ ++ ap91_pci_setup_wmac_led_pin(1); + -+ ar9xxx_add_device_wmac(eeprom, NULL); ++ ap91_pci_init(ee, mac); +} -+ -+MIPS_MACHINE(AR71XX_MACH_WNR2000, "WNR2000", "NETGEAR WNR2000", wnr2000_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.39/arch/mips/ar71xx/mach-wp543.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wp543.c 2011-08-24 02:41:55.617990333 +0200 -@@ -0,0 +1,101 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_WR741ND, "TL-WR741ND", "TP-LINK TL-WR741ND", ++ tl_wr741nd_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr841n.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr841n.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,144 @@ +/* -+ * Compex WP543/WPJ543 board support ++ * TP-LINK TL-WR841N board support + * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -8871,97 +7848,141 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.39/arch/mips + +#include "machtype.h" +#include "devices.h" ++#include "dev-dsa.h" +#include "dev-m25p80.h" -+#include "dev-pb42-pci.h" +#include "dev-gpio-buttons.h" ++#include "dev-pb42-pci.h" +#include "dev-leds-gpio.h" -+#include "dev-usb.h" + -+#define WP543_GPIO_SW6 2 -+#define WP543_GPIO_LED_1 3 -+#define WP543_GPIO_LED_2 4 -+#define WP543_GPIO_LED_WLAN 5 -+#define WP543_GPIO_LED_CONN 6 -+#define WP543_GPIO_LED_DIAG 7 -+#define WP543_GPIO_SW4 8 ++#define TL_WR841ND_V1_GPIO_LED_SYSTEM 2 ++#define TL_WR841ND_V1_GPIO_LED_QSS_GREEN 4 ++#define TL_WR841ND_V1_GPIO_LED_QSS_RED 5 + -+#define WP543_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WP543_KEYS_DEBOUNCE_INTERVAL (3 * WP543_KEYS_POLL_INTERVAL) ++#define TL_WR841ND_V1_GPIO_BTN_RESET 3 ++#define TL_WR841ND_V1_GPIO_BTN_QSS 7 + -+static struct gpio_led wp543_leds_gpio[] __initdata = { ++#define TL_WR841ND_V1_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL \ ++ (3 * TL_WR841ND_V1_KEYS_POLL_INTERVAL) ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition tl_wr841n_v1_partitions[] = { + { -+ .name = "wp543:green:led1", -+ .gpio = WP543_GPIO_LED_1, -+ .active_low = 1, ++ .name = "redboot", ++ .offset = 0, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "wp543:green:led2", -+ .gpio = WP543_GPIO_LED_2, -+ .active_low = 1, ++ .name = "kernel", ++ .offset = 0x020000, ++ .size = 0x140000, + }, { -+ .name = "wp543:green:wlan", -+ .gpio = WP543_GPIO_LED_WLAN, -+ .active_low = 1, ++ .name = "rootfs", ++ .offset = 0x160000, ++ .size = 0x280000, + }, { -+ .name = "wp543:green:conn", -+ .gpio = WP543_GPIO_LED_CONN, -+ .active_low = 1, ++ .name = "config", ++ .offset = 0x3e0000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "wp543:green:diag", -+ .gpio = WP543_GPIO_LED_DIAG, ++ .name = "firmware", ++ .offset = 0x020000, ++ .size = 0x3c0000, ++ } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ ++ ++static struct flash_platform_data tl_wr841n_v1_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = tl_wr841n_v1_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wr841n_v1_partitions), ++#endif ++}; ++ ++static struct gpio_led tl_wr841n_v1_leds_gpio[] __initdata = { ++ { ++ .name = "tl-wr841n:green:system", ++ .gpio = TL_WR841ND_V1_GPIO_LED_SYSTEM, + .active_low = 1, ++ }, { ++ .name = "tl-wr841n:red:qss", ++ .gpio = TL_WR841ND_V1_GPIO_LED_QSS_RED, ++ }, { ++ .name = "tl-wr841n:green:qss", ++ .gpio = TL_WR841ND_V1_GPIO_LED_QSS_GREEN, + } +}; + -+static struct gpio_keys_button wp543_gpio_keys[] __initdata = { ++static struct gpio_keys_button tl_wr841n_v1_gpio_keys[] __initdata = { + { -+ .desc = "sw6", ++ .desc = "reset", + .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WP543_GPIO_SW6, ++ .code = KEY_RESTART, ++ .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR841ND_V1_GPIO_BTN_RESET, ++ .active_low = 1, + }, { -+ .desc = "sw4", ++ .desc = "qss", + .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WP543_GPIO_SW4, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR841ND_V1_GPIO_BTN_QSS, ++ .active_low = 1, + } +}; + -+static void __init wp543_setup(void) ++static struct dsa_chip_data tl_wr841n_v1_dsa_chip = { ++ .port_names[0] = "wan", ++ .port_names[1] = "lan1", ++ .port_names[2] = "lan2", ++ .port_names[3] = "lan3", ++ .port_names[4] = "lan4", ++ .port_names[5] = "cpu", ++}; ++ ++static struct dsa_platform_data tl_wr841n_v1_dsa_data = { ++ .nr_chips = 1, ++ .chip = &tl_wr841n_v1_dsa_chip, ++}; ++ ++static void __init tl_wr841n_v1_setup(void) +{ -+ ar71xx_add_device_m25p80(NULL); ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + -+ ar71xx_add_device_mdio(0xfffffff7); ++ ar71xx_add_device_mdio(0x0); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = 0x08; -+ ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC | -+ RESET_MODULE_GE0_PHY; + ar71xx_add_device_eth(0); + -+ ar71xx_add_device_usb(); ++ ar71xx_add_device_dsa(0, &tl_wr841n_v1_dsa_data); + -+ pb42_pci_init(); ++ ar71xx_add_device_m25p80(&tl_wr841n_v1_flash_data); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio), -+ wp543_leds_gpio); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v1_leds_gpio), ++ tl_wr841n_v1_leds_gpio); + -+ ar71xx_register_gpio_keys_polled(-1, WP543_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wp543_gpio_keys), -+ wp543_gpio_keys); ++ ar71xx_register_gpio_keys_polled(-1, TL_WR841ND_V1_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wr841n_v1_gpio_keys), ++ tl_wr841n_v1_gpio_keys); ++ ++ pb42_pci_init(); +} + -+MIPS_MACHINE(AR71XX_MACH_WP543, "WP543", "Compex WP543", wp543_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c 2011-08-24 02:41:55.617990333 +0200 -@@ -0,0 +1,161 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_WR841N_V1, "TL-WR841N-v1.5", "TP-LINK TL-WR841N v1", ++ tl_wr841n_v1_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-tl-wr941nd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-tl-wr941nd.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,147 @@ +/* -+ * Linksys WRT160NL board support ++ * TP-LINK TL-WR941ND board support + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2009-2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -8975,326 +7996,482 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c linux-2.6.39/arch/m + +#include "machtype.h" +#include "devices.h" ++#include "dev-dsa.h" +#include "dev-m25p80.h" +#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+#include "nvram.h" -+ -+#define WRT160NL_GPIO_LED_POWER 14 -+#define WRT160NL_GPIO_LED_WPS_AMBER 9 -+#define WRT160NL_GPIO_LED_WPS_BLUE 8 -+#define WRT160NL_GPIO_LED_WLAN 6 + -+#define WRT160NL_GPIO_BTN_WPS 7 -+#define WRT160NL_GPIO_BTN_RESET 21 ++#define TL_WR941ND_GPIO_LED_SYSTEM 2 ++#define TL_WR941ND_GPIO_LED_QSS_RED 4 ++#define TL_WR941ND_GPIO_LED_QSS_GREEN 5 ++#define TL_WR941ND_GPIO_LED_WLAN 9 + -+#define WRT160NL_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WRT160NL_KEYS_DEBOUNCE_INTERVAL (3 * WRT160NL_KEYS_POLL_INTERVAL) ++#define TL_WR941ND_GPIO_BTN_RESET 3 ++#define TL_WR941ND_GPIO_BTN_QSS 7 + -+#define WRT160NL_NVRAM_ADDR 0x1f7e0000 -+#define WRT160NL_NVRAM_SIZE 0x10000 ++#define TL_WR941ND_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define TL_WR941ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR941ND_KEYS_POLL_INTERVAL) + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wrt160nl_partitions[] = { ++static struct mtd_partition tl_wr941nd_partitions[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x040000, ++ .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", -+ .offset = 0x040000, -+ .size = 0x0e0000, -+ }, { -+ .name = "filesytem", -+ .offset = 0x120000, -+ .size = 0x6c0000, ++ .offset = 0x020000, ++ .size = 0x140000, + }, { -+ .name = "nvram", -+ .offset = 0x7e0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "rootfs", ++ .offset = 0x160000, ++ .size = 0x290000, + }, { -+ .name = "ART", -+ .offset = 0x7f0000, ++ .name = "art", ++ .offset = 0x3f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", -+ .offset = 0x040000, -+ .size = 0x7a0000, ++ .offset = 0x020000, ++ .size = 0x3d0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data wrt160nl_flash_data = { ++static struct flash_platform_data tl_wr941nd_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = wrt160nl_partitions, -+ .nr_parts = ARRAY_SIZE(wrt160nl_partitions), ++ .parts = tl_wr941nd_partitions, ++ .nr_parts = ARRAY_SIZE(tl_wr941nd_partitions), +#endif +}; + -+static struct gpio_led wrt160nl_leds_gpio[] __initdata = { ++static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = { + { -+ .name = "wrt160nl:blue:power", -+ .gpio = WRT160NL_GPIO_LED_POWER, ++ .name = "tl-wr941nd:green:system", ++ .gpio = TL_WR941ND_GPIO_LED_SYSTEM, + .active_low = 1, -+ .default_trigger = "default-on", + }, { -+ .name = "wrt160nl:amber:wps", -+ .gpio = WRT160NL_GPIO_LED_WPS_AMBER, -+ .active_low = 1, ++ .name = "tl-wr941nd:red:qss", ++ .gpio = TL_WR941ND_GPIO_LED_QSS_RED, + }, { -+ .name = "wrt160nl:blue:wps", -+ .gpio = WRT160NL_GPIO_LED_WPS_BLUE, -+ .active_low = 1, ++ .name = "tl-wr941nd:green:qss", ++ .gpio = TL_WR941ND_GPIO_LED_QSS_GREEN, + }, { -+ .name = "wrt160nl:blue:wlan", -+ .gpio = WRT160NL_GPIO_LED_WLAN, ++ .name = "tl-wr941nd:green:wlan", ++ .gpio = TL_WR941ND_GPIO_LED_WLAN, + .active_low = 1, + } +}; + -+static struct gpio_keys_button wrt160nl_gpio_keys[] __initdata = { ++static struct gpio_keys_button tl_wr941nd_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WRT160NL_GPIO_BTN_RESET, ++ .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR941ND_GPIO_BTN_RESET, + .active_low = 1, + }, { -+ .desc = "wps", ++ .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WRT160NL_GPIO_BTN_WPS, ++ .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = TL_WR941ND_GPIO_BTN_QSS, + .active_low = 1, + } +}; + -+static void __init wrt160nl_setup(void) ++static struct dsa_chip_data tl_wr941nd_dsa_chip = { ++ .port_names[0] = "wan", ++ .port_names[1] = "lan1", ++ .port_names[2] = "lan2", ++ .port_names[3] = "lan3", ++ .port_names[4] = "lan4", ++ .port_names[5] = "cpu", ++}; ++ ++static struct dsa_platform_data tl_wr941nd_dsa_data = { ++ .nr_chips = 1, ++ .chip = &tl_wr941nd_dsa_chip, ++}; ++ ++static void __init tl_wr941nd_setup(void) +{ -+ const char *nvram = (char *) KSEG1ADDR(WRT160NL_NVRAM_ADDR); ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[6]; -+ -+ if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, -+ "lan_hwaddr=", mac) == 0) { -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); -+ } + + ar71xx_add_device_mdio(0x0); + ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.phy_mask = 0x01; -+ -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + + ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); -+ -+ ar71xx_add_device_m25p80(&wrt160nl_flash_data); -+ -+ ar71xx_add_device_usb(); -+ -+ if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, -+ "wl0_hwaddr=", mac) == 0) -+ ar9xxx_add_device_wmac(eeprom, mac); -+ else -+ ar9xxx_add_device_wmac(eeprom, NULL); ++ ar71xx_add_device_dsa(0, &tl_wr941nd_dsa_data); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt160nl_leds_gpio), -+ wrt160nl_leds_gpio); ++ ar71xx_add_device_m25p80(&tl_wr941nd_flash_data); + -+ ar71xx_register_gpio_keys_polled(-1, WRT160NL_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wrt160nl_gpio_keys), -+ wrt160nl_gpio_keys); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio), ++ tl_wr941nd_leds_gpio); + ++ ar71xx_register_gpio_keys_polled(-1, TL_WR941ND_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(tl_wr941nd_gpio_keys), ++ tl_wr941nd_gpio_keys); ++ ar9xxx_add_device_wmac(eeprom, mac); +} + -+MIPS_MACHINE(AR71XX_MACH_WRT160NL, "WRT160NL", "Linksys WRT160NL", -+ wrt160nl_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c 2011-08-24 02:41:55.617990333 +0200 -@@ -0,0 +1,164 @@ ++MIPS_MACHINE(AR71XX_MACH_TL_WR941ND, "TL-WR941ND", "TP-LINK TL-WR941ND", ++ tl_wr941nd_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-ubnt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-ubnt.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,333 @@ +/* -+ * Linksys WRT400N board support ++ * Ubiquiti RouterStation support + * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * Copyright (C) 2009 Imre Kaloz ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2008 Ubiquiti + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+ +#include + +#include "machtype.h" +#include "devices.h" -+#include "dev-ap94-pci.h" +#include "dev-m25p80.h" ++#include "dev-ap91-pci.h" +#include "dev-gpio-buttons.h" ++#include "dev-pb42-pci.h" +#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+#define WRT400N_GPIO_LED_ORANGE 5 -+#define WRT400N_GPIO_LED_GREEN 4 -+#define WRT400N_GPIO_LED_POWER 1 -+#define WRT400N_GPIO_LED_WLAN 0 ++#define UBNT_RS_GPIO_LED_RF 2 ++#define UBNT_RS_GPIO_SW4 8 + -+#define WRT400N_GPIO_BTN_RESET 8 -+#define WRT400N_GPIO_BTN_WLSEC 3 ++#define UBNT_LS_SR71_GPIO_LED_D25 0 ++#define UBNT_LS_SR71_GPIO_LED_D26 1 ++#define UBNT_LS_SR71_GPIO_LED_D24 2 ++#define UBNT_LS_SR71_GPIO_LED_D23 4 ++#define UBNT_LS_SR71_GPIO_LED_D22 5 ++#define UBNT_LS_SR71_GPIO_LED_D27 6 ++#define UBNT_LS_SR71_GPIO_LED_D28 7 + -+#define WRT400N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WRT400N_KEYS_DEBOUNE_INTERVAL (3 * WRT400N_KEYS_POLL_INTERVAL) ++#define UBNT_M_GPIO_LED_L1 0 ++#define UBNT_M_GPIO_LED_L2 1 ++#define UBNT_M_GPIO_LED_L3 11 ++#define UBNT_M_GPIO_LED_L4 7 ++#define UBNT_M_GPIO_BTN_RESET 12 + -+#define WRT400N_MAC_ADDR_OFFSET 0x120c -+#define WRT400N_CALDATA0_OFFSET 0x1000 -+#define WRT400N_CALDATA1_OFFSET 0x5000 ++#define UBNT_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define UBNT_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_KEYS_POLL_INTERVAL) + -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wrt400n_partitions[] = { ++static struct gpio_led ubnt_rs_leds_gpio[] __initdata = { + { -+ .name = "uboot", -+ .offset = 0, -+ .size = 0x030000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "env", -+ .offset = 0x030000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "linux", -+ .offset = 0x040000, -+ .size = 0x140000, ++ .name = "ubnt:green:rf", ++ .gpio = UBNT_RS_GPIO_LED_RF, ++ .active_low = 0, ++ } ++}; ++ ++static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = { ++ { ++ .name = "ubnt:green:d22", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D22, ++ .active_low = 0, + }, { -+ .name = "rootfs", -+ .offset = 0x180000, -+ .size = 0x630000, ++ .name = "ubnt:green:d23", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D23, ++ .active_low = 0, + }, { -+ .name = "nvram", -+ .offset = 0x7b0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "ubnt:green:d24", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D24, ++ .active_low = 0, + }, { -+ .name = "factory", -+ .offset = 0x7c0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "ubnt:red:d25", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D25, ++ .active_low = 0, + }, { -+ .name = "language", -+ .offset = 0x7d0000, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "ubnt:red:d26", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D26, ++ .active_low = 0, + }, { -+ .name = "caldata", -+ .offset = 0x7f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "ubnt:green:d27", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D27, ++ .active_low = 0, + }, { -+ .name = "firmware", -+ .offset = 0x040000, -+ .size = 0x770000, ++ .name = "ubnt:green:d28", ++ .gpio = UBNT_LS_SR71_GPIO_LED_D28, ++ .active_low = 0, + } +}; -+#endif /* CONFIG_MTD_PARTITIONS */ -+ -+static struct flash_platform_data wrt400n_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = wrt400n_partitions, -+ .nr_parts = ARRAY_SIZE(wrt400n_partitions), -+#endif -+}; + -+static struct gpio_led wrt400n_leds_gpio[] __initdata = { ++static struct gpio_led ubnt_m_leds_gpio[] __initdata = { + { -+ .name = "wrt400n:green:status", -+ .gpio = WRT400N_GPIO_LED_GREEN, -+ .active_low = 1, ++ .name = "ubnt:red:link1", ++ .gpio = UBNT_M_GPIO_LED_L1, ++ .active_low = 0, + }, { -+ .name = "wrt400n:amber:aoss", -+ .gpio = WRT400N_GPIO_LED_ORANGE, -+ .active_low = 1, ++ .name = "ubnt:orange:link2", ++ .gpio = UBNT_M_GPIO_LED_L2, ++ .active_low = 0, + }, { -+ .name = "wrt400n:green:wlan", -+ .gpio = WRT400N_GPIO_LED_WLAN, -+ .active_low = 1, ++ .name = "ubnt:green:link3", ++ .gpio = UBNT_M_GPIO_LED_L3, ++ .active_low = 0, + }, { -+ .name = "wrt400n:green:power", -+ .gpio = WRT400N_GPIO_LED_POWER, -+ .active_low = 1, ++ .name = "ubnt:green:link4", ++ .gpio = UBNT_M_GPIO_LED_L4, ++ .active_low = 0, + } +}; + -+static struct gpio_keys_button wrt400n_gpio_keys[] __initdata = { ++static struct gpio_keys_button ubnt_gpio_keys[] __initdata = { + { -+ .desc = "reset", ++ .desc = "sw4", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL, -+ .gpio = WRT400N_GPIO_BTN_RESET, ++ .debounce_interval = UBNT_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = UBNT_RS_GPIO_SW4, + .active_low = 1, -+ }, { -+ .desc = "wlsec", ++ } ++}; ++ ++static struct gpio_keys_button ubnt_m_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", + .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL, -+ .gpio = WRT400N_GPIO_BTN_WLSEC, ++ .code = KEY_RESTART, ++ .debounce_interval = UBNT_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = UBNT_M_GPIO_BTN_RESET, + .active_low = 1, + } +}; + -+static void __init wrt400n_setup(void) ++static void __init ubnt_generic_setup(void) +{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac = art + WRT400N_MAC_ADDR_OFFSET; ++ ar71xx_add_device_m25p80(NULL); + -+ ar71xx_add_device_mdio(0x0); ++ ar71xx_register_gpio_keys_polled(-1, UBNT_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ubnt_gpio_keys), ++ ubnt_gpio_keys); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 1); -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ pb42_pci_init(); ++} + -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 2); ++/* ++ * There is Secondary MAC address duplicate problem with some UBNT HW batches. ++ * Do not increase Secondary MAC address by 1 but do workaround ++ * with 'Locally Administrated' bit. ++ */ ++static void __init ubnt_init_secondary_mac(unsigned char *mac_base) ++{ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac_base, 0); ++ ar71xx_eth1_data.mac_addr[0] |= 0x02; ++} ++ ++#define UBNT_RS_WAN_PHYMASK BIT(20) ++#define UBNT_RS_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19)) ++ ++static void __init ubnt_rs_setup(void) ++{ ++ ubnt_generic_setup(); ++ ++ ar71xx_add_device_mdio(~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK)); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK; ++ ++ ubnt_init_secondary_mac(ar71xx_mac_base); + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++ ar71xx_eth1_data.speed = SPEED_100; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; + + ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + -+ ar71xx_add_device_m25p80(&wrt400n_flash_data); ++ ar71xx_add_device_usb(); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt400n_leds_gpio), -+ wrt400n_leds_gpio); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), ++ ubnt_rs_leds_gpio); ++} + -+ ar71xx_register_gpio_keys_polled(-1, WRT400N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wrt400n_gpio_keys), -+ wrt400n_gpio_keys); ++MIPS_MACHINE(AR71XX_MACH_UBNT_RS, "UBNT-RS", "Ubiquiti RouterStation", ++ ubnt_rs_setup); + -+ ap94_pci_init(art + WRT400N_CALDATA0_OFFSET, NULL, -+ art + WRT400N_CALDATA1_OFFSET, NULL); ++#define UBNT_RSPRO_WAN_PHYMASK BIT(4) ++#define UBNT_RSPRO_LAN_PHYMASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) ++ ++static void __init ubnt_rspro_setup(void) ++{ ++ ubnt_generic_setup(); ++ ++ ar71xx_add_device_mdio(~(UBNT_RSPRO_WAN_PHYMASK | ++ UBNT_RSPRO_LAN_PHYMASK)); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.phy_mask = UBNT_RSPRO_WAN_PHYMASK; ++ ++ ubnt_init_secondary_mac(ar71xx_mac_base); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = UBNT_RSPRO_LAN_PHYMASK; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); ++ ++ ar71xx_add_device_usb(); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), ++ ubnt_rs_leds_gpio); +} + -+MIPS_MACHINE(AR71XX_MACH_WRT400N, "WRT400N", "Linksys WRT400N", wrt400n_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-ag300h.c linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-ag300h.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-ag300h.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-ag300h.c 2011-08-24 02:41:55.628193451 +0200 -@@ -0,0 +1,231 @@ ++MIPS_MACHINE(AR71XX_MACH_UBNT_RSPRO, "UBNT-RSPRO", "Ubiquiti RouterStation Pro", ++ ubnt_rspro_setup); ++ ++static void __init ubnt_lsx_setup(void) ++{ ++ ubnt_generic_setup(); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_UBNT_LSX, "UBNT-LSX", "Ubiquiti LSX", ubnt_lsx_setup); ++ ++#define UBNT_LSSR71_PHY_MASK BIT(1) ++ ++static void __init ubnt_lssr71_setup(void) ++{ ++ ubnt_generic_setup(); ++ ++ ar71xx_add_device_mdio(~UBNT_LSSR71_PHY_MASK); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK; ++ ++ ar71xx_add_device_eth(0); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio), ++ ubnt_ls_sr71_leds_gpio); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_UBNT_LSSR71, "UBNT-LS-SR71", "Ubiquiti LS-SR71", ++ ubnt_lssr71_setup); ++ ++#define UBNT_M_WAN_PHYMASK BIT(4) ++ ++static void __init ubnt_m_setup(void) ++{ ++ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); ++ ++ ar71xx_add_device_m25p80(NULL); ++ ++ ar71xx_add_device_mdio(~UBNT_M_WAN_PHYMASK); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac1, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac2, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = UBNT_M_WAN_PHYMASK; ++ ++ ar71xx_add_device_eth(0); ++ ++ ap91_pci_init(ee, NULL); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_m_leds_gpio), ++ ubnt_m_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, UBNT_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ubnt_m_gpio_keys), ++ ubnt_m_gpio_keys); ++} ++ ++static void __init ubnt_rocket_m_setup(void) ++{ ++ ubnt_m_setup(); ++ ar71xx_add_device_usb(); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_UBNT_BULLET_M, "UBNT-BM", "Ubiquiti Bullet M", ++ ubnt_m_setup); ++MIPS_MACHINE(AR71XX_MACH_UBNT_ROCKET_M, "UBNT-RM", "Ubiquiti Rocket M", ++ ubnt_rocket_m_setup); ++ ++/* TODO detect the second ethernet port and use one ++ init function for all Ubiquiti MIMO series products */ ++static void __init ubnt_nano_m_setup(void) ++{ ++ ubnt_m_setup(); ++ ++ ar71xx_eth1_data.has_ar7240_switch = 1; ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ++ ar71xx_add_device_eth(1); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_UBNT_NANO_M, "UBNT-NM", "Ubiquiti Nanostation M", ++ ubnt_nano_m_setup); ++ ++static struct gpio_led ubnt_unifi_leds_gpio[] __initdata = { ++ { ++ .name = "ubnt:orange:dome", ++ .gpio = 1, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:green:dome", ++ .gpio = 0, ++ .active_low = 0, ++ } ++}; ++ ++static void __init ubnt_unifi_setup(void) ++{ ++ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); ++ ++ ar71xx_add_device_m25p80(NULL); ++ ++ ar71xx_add_device_mdio(~UBNT_M_WAN_PHYMASK); ++ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = UBNT_M_WAN_PHYMASK; ++ ++ ar71xx_add_device_eth(0); ++ ++ ap91_pci_init(ee, NULL); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_leds_gpio), ++ ubnt_unifi_leds_gpio); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_UBNT_UNIFI, "UBNT-XM", "Ubiquiti UniFi", ++ ubnt_unifi_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wndr3700.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wndr3700.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,290 @@ +/* -+ * Buffalo WZR-HP-AG300H board support ++ * Netgear WNDR3700 board support + * -+ * Copyright (C) 2011 Felix Fietkau ++ * Copyright (C) 2009 Marco Porsch ++ * Copyright (C) 2009-2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -9304,528 +8481,549 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-ag300h.c linux-2.6.39/a +#include +#include +#include -+#include ++#include ++#include + -+#include +#include -+#include + +#include "machtype.h" +#include "devices.h" ++#include "dev-m25p80.h" +#include "dev-ap94-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" +#include "dev-usb.h" + -+#define WZRHPAG300H_MAC_OFFSET 0x20c -+#define WZRHPAG300H_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPAG300H_KEYS_POLL_INTERVAL) ++#define WNDR3700_GPIO_LED_WPS_ORANGE 0 ++#define WNDR3700_GPIO_LED_POWER_ORANGE 1 ++#define WNDR3700_GPIO_LED_POWER_GREEN 2 ++#define WNDR3700_GPIO_LED_WPS_GREEN 4 ++#define WNDR3700_GPIO_LED_WAN_GREEN 6 ++ ++#define WNDR3700_GPIO_BTN_WPS 3 ++#define WNDR3700_GPIO_BTN_RESET 8 ++#define WNDR3700_GPIO_BTN_WIFI 11 ++ ++#define WNDR3700_GPIO_RTL8366_SDA 5 ++#define WNDR3700_GPIO_RTL8366_SCK 7 ++ ++#define WNDR3700_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WNDR3700_KEYS_DEBOUNCE_INTERVAL (3 * WNDR3700_KEYS_POLL_INTERVAL) ++ ++#define WNDR3700_ETH0_MAC_OFFSET 0 ++#define WNDR3700_ETH1_MAC_OFFSET 0x6 ++ ++#define WNDR3700_WMAC0_MAC_OFFSET 0 ++#define WNDR3700_WMAC1_MAC_OFFSET 0xc ++#define WNDR3700_CALDATA0_OFFSET 0x1000 ++#define WNDR3700_CALDATA1_OFFSET 0x5000 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wzrhpag300h_flash_partitions[] = { ++static struct mtd_partition wndr3700_partitions[] = { + { -+ .name = "u-boot", ++ .name = "uboot", + .offset = 0, -+ .size = 0x0040000, ++ .size = 0x050000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "u-boot-env", -+ .offset = 0x0040000, -+ .size = 0x0010000, ++ .name = "env", ++ .offset = 0x050000, ++ .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "art", -+ .offset = 0x0050000, -+ .size = 0x0010000, ++ .name = "rootfs", ++ .offset = 0x070000, ++ .size = 0x720000, ++ }, { ++ .name = "config", ++ .offset = 0x790000, ++ .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "kernel", -+ .offset = 0x0060000, -+ .size = 0x0100000, ++ .name = "config_bak", ++ .offset = 0x7a0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "rootfs", -+ .offset = 0x0160000, -+ .size = 0x1e90000, ++ .name = "pot", ++ .offset = 0x7b0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "user_property", -+ .offset = 0x1ff0000, -+ .size = 0x0010000, ++ .name = "traffic_meter", ++ .offset = 0x7c0000, ++ .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "firmware", -+ .offset = 0x0060000, -+ .size = 0x1f90000, -+ } -+}; -+ -+#endif /* CONFIG_MTD_PARTITIONS */ -+ -+static struct mtd_info *concat_devs[2] = { NULL, NULL }; -+static struct work_struct mtd_concat_work; -+ -+static void mtd_concat_add_work(struct work_struct *work) -+{ -+ struct mtd_info *mtd; -+ -+ mtd = mtd_concat_create(concat_devs, ARRAY_SIZE(concat_devs), "flash"); ++ .name = "language", ++ .offset = 0x7d0000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "caldata", ++ .offset = 0x7f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ } ++}; + -+#ifdef CONFIG_MTD_PARTITIONS -+ add_mtd_partitions(mtd, wzrhpag300h_flash_partitions, -+ ARRAY_SIZE(wzrhpag300h_flash_partitions)); ++static struct mtd_partition wndr3700v2_partitions[] = { ++ { ++ .name = "uboot", ++ .offset = 0, ++ .size = 0x050000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "env", ++ .offset = 0x050000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "rootfs", ++ .offset = 0x070000, ++ .size = 0xe40000, ++ }, { ++ .name = "config", ++ .offset = 0xeb0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "config_bak", ++ .offset = 0xec0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "pot", ++ .offset = 0xed0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "traffic_meter", ++ .offset = 0xee0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "language", ++ .offset = 0xef0000, ++ .size = 0x100000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "caldata", ++ .offset = 0xff0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ } ++}; ++#define wndr3700_num_partitions ARRAY_SIZE(wndr3700_partitions) ++#define wndr3700v2_num_partitions ARRAY_SIZE(wndr3700v2_partitions) +#else -+ add_mtd_device(mtd); -+#endif -+} -+ -+static void mtd_concat_add(struct mtd_info *mtd) -+{ -+ static bool registered = false; -+ -+ if (registered) -+ return; -+ -+ if (!strcmp(mtd->name, "spi0.0")) -+ concat_devs[0] = mtd; -+ else if (!strcmp(mtd->name, "spi0.1")) -+ concat_devs[1] = mtd; -+ else -+ return; -+ -+ if (!concat_devs[0] || !concat_devs[1]) -+ return; -+ -+ registered = true; -+ INIT_WORK(&mtd_concat_work, mtd_concat_add_work); -+ schedule_work(&mtd_concat_work); -+} -+ -+static void mtd_concat_remove(struct mtd_info *mtd) -+{ -+} -+ -+static void add_mtd_concat_notifier(void) -+{ -+ static struct mtd_notifier not = { -+ .add = mtd_concat_add, -+ .remove = mtd_concat_remove, -+ }; ++#define wndr3700_partitions NULL ++#define wndr3700_num_partitions 0 ++#define wndr3700v2_partitions NULL ++#define wndr3700v2_num_partitions 0 ++#endif /* CONFIG_MTD_PARTITIONS */ + -+ register_mtd_user(¬); -+} ++static struct flash_platform_data wndr3700_flash_data; + -+static struct gpio_led wzrhpag300h_leds_gpio[] __initdata = { ++static struct gpio_led wndr3700_leds_gpio[] __initdata = { + { -+ .name = "wzr-hp-ag300h:red:diag", -+ .gpio = 1, ++ .name = "wndr3700:green:power", ++ .gpio = WNDR3700_GPIO_LED_POWER_GREEN, + .active_low = 1, -+ }, ++ }, { ++ .name = "wndr3700:orange:power", ++ .gpio = WNDR3700_GPIO_LED_POWER_ORANGE, ++ .active_low = 1, ++ }, { ++ .name = "wndr3700:green:wps", ++ .gpio = WNDR3700_GPIO_LED_WPS_GREEN, ++ .active_low = 1, ++ }, { ++ .name = "wndr3700:orange:wps", ++ .gpio = WNDR3700_GPIO_LED_WPS_ORANGE, ++ .active_low = 1, ++ }, { ++ .name = "wndr3700:green:wan", ++ .gpio = WNDR3700_GPIO_LED_WAN_GREEN, ++ .active_low = 1, ++ } +}; + -+ -+static struct gpio_keys_button wzrhpag300h_gpio_keys[] __initdata = { ++static struct gpio_keys_button wndr3700_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 11, -+ .active_low = 1, -+ }, { -+ .desc = "usb", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 3, ++ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNDR3700_GPIO_BTN_RESET, + .active_low = 1, + }, { -+ .desc = "aoss", ++ .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 5, -+ .active_low = 1, -+ }, { -+ .desc = "router_auto", -+ .type = EV_KEY, -+ .code = BTN_6, -+ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 6, ++ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNDR3700_GPIO_BTN_WPS, + .active_low = 1, + }, { -+ .desc = "router_off", ++ .desc = "wifi", + .type = EV_KEY, -+ .code = BTN_5, -+ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 7, ++ .code = BTN_2, ++ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNDR3700_GPIO_BTN_WIFI, + .active_low = 1, + } +}; + -+static struct spi_board_info ar71xx_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ }, -+ { -+ .bus_num = 0, -+ .chip_select = 1, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", ++static struct rtl8366_platform_data wndr3700_rtl8366s_data = { ++ .gpio_sda = WNDR3700_GPIO_RTL8366_SDA, ++ .gpio_sck = WNDR3700_GPIO_RTL8366_SCK, ++}; ++ ++static struct platform_device wndr3700_rtl8366s_device = { ++ .name = RTL8366S_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &wndr3700_rtl8366s_data, + } +}; + -+static void __init wzrhpag300h_setup(void) ++static void __init wndr3700_common_setup(void) +{ -+ u8 *eeprom1 = (u8 *) KSEG1ADDR(0x1f051000); -+ u8 *eeprom2 = (u8 *) KSEG1ADDR(0x1f055000); -+ u8 *mac1 = eeprom1 + WZRHPAG300H_MAC_OFFSET; -+ u8 *mac2 = eeprom2 + WZRHPAG300H_MAC_OFFSET; -+ -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac1, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac2, 1); -+ -+ ar71xx_add_device_mdio(~(BIT(0) | BIT(4))); ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ++ art + WNDR3700_ETH0_MAC_OFFSET, 0); ++ ar71xx_eth0_pll_data.pll_1000 = 0x11110000; ++ ar71xx_eth0_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ar71xx_eth0_data.speed = SPEED_1000; + ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ ar71xx_eth0_data.phy_mask = BIT(0); + ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, ++ art + WNDR3700_ETH1_MAC_OFFSET, 0); ++ ar71xx_eth1_pll_data.pll_1000 = 0x11110000; ++ ar71xx_eth1_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = BIT(4); ++ ar71xx_eth1_data.phy_mask = 0x10; + + ar71xx_add_device_eth(0); + ar71xx_add_device_eth(1); + + ar71xx_add_device_usb(); -+ gpio_request(2, "usb"); -+ gpio_direction_output(2, 1); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpag300h_leds_gpio), -+ wzrhpag300h_leds_gpio); ++ ar71xx_add_device_m25p80(&wndr3700_flash_data); + -+ ar71xx_register_gpio_keys_polled(-1, WZRHPAG300H_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wzrhpag300h_gpio_keys), -+ wzrhpag300h_gpio_keys); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wndr3700_leds_gpio), ++ wndr3700_leds_gpio); + -+ ar71xx_add_device_spi(NULL, ar71xx_spi_info, -+ ARRAY_SIZE(ar71xx_spi_info)); ++ ar71xx_register_gpio_keys_polled(-1, WNDR3700_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wndr3700_gpio_keys), ++ wndr3700_gpio_keys); + -+ add_mtd_concat_notifier(); ++ platform_device_register(&wndr3700_rtl8366s_device); ++ platform_device_register_simple("wndr3700-led-usb", -1, NULL, 0); + -+ ap94_pci_init(eeprom1, mac1, eeprom2, mac2); -+} ++ ap94_pci_setup_wmac_led_pin(0, 5); ++ ap94_pci_setup_wmac_led_pin(1, 5); + -+MIPS_MACHINE(AR71XX_MACH_WZR_HP_AG300H, "WZR-HP-AG300H", -+ "Buffalo WZR-HP-AG300H", wzrhpag300h_setup); ++ /* 2.4 GHz uses the first fixed antenna group (1, 0, 1, 0) */ ++ ap94_pci_setup_wmac_gpio(0, (0xf << 6), (0xa << 6)); + -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 2011-08-24 02:41:55.649418561 +0200 -@@ -0,0 +1,292 @@ -+/* -+ * Buffalo WZR-HP-G300NH board support -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ /* 5 GHz uses the second fixed antenna group (0, 1, 1, 0) */ ++ ap94_pci_setup_wmac_gpio(1, (0xf << 6), (0x6 << 6)); ++ ++ ap94_pci_init(art + WNDR3700_CALDATA0_OFFSET, ++ art + WNDR3700_WMAC0_MAC_OFFSET, ++ art + WNDR3700_CALDATA1_OFFSET, ++ art + WNDR3700_WMAC1_MAC_OFFSET); ++} ++ ++static void __init wndr3700_setup(void) ++{ ++ wndr3700_flash_data.parts = wndr3700_partitions, ++ wndr3700_flash_data.nr_parts = wndr3700_num_partitions, ++ wndr3700_common_setup(); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_WNDR3700, "WNDR3700", "NETGEAR WNDR3700", ++ wndr3700_setup); ++ ++static void __init wndr3700v2_setup(void) ++{ ++ wndr3700_flash_data.parts = wndr3700v2_partitions, ++ wndr3700_flash_data.nr_parts = wndr3700v2_num_partitions, ++ wndr3700_common_setup(); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_WNDR3700V2, "WNDR3700v2", "NETGEAR WNDR3700v2", ++ wndr3700v2_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wnr2000.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wnr2000.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,150 @@ ++/* ++ * NETGEAR WNR2000 board support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2008-2009 Andy Boyett ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+#include +#include +#include -+#include -+#include + -+#include +#include -+#include + +#include "machtype.h" +#include "devices.h" ++#include "dev-m25p80.h" +#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+ -+#define WZRHPG300NH_GPIO_LED_USB 0 -+#define WZRHPG300NH_GPIO_LED_DIAG 1 -+#define WZRHPG300NH_GPIO_LED_WIRELESS 6 -+#define WZRHPG300NH_GPIO_LED_SECURITY 17 -+#define WZRHPG300NH_GPIO_LED_ROUTER 18 -+ -+#define WZRHPG300NH_GPIO_RTL8366_SDA 19 -+#define WZRHPG300NH_GPIO_RTL8366_SCK 20 -+ -+#define WZRHPG300NH_GPIO_74HC153_S0 9 -+#define WZRHPG300NH_GPIO_74HC153_S1 11 -+#define WZRHPG300NH_GPIO_74HC153_1Y 12 -+#define WZRHPG300NH_GPIO_74HC153_2Y 14 -+ -+#define WZRHPG300NH_GPIO_EXP_BASE 32 -+#define WZRHPG300NH_GPIO_BTN_AOSS (WZRHPG300NH_GPIO_EXP_BASE + 0) -+#define WZRHPG300NH_GPIO_BTN_RESET (WZRHPG300NH_GPIO_EXP_BASE + 1) -+#define WZRHPG300NH_GPIO_BTN_ROUTER_ON (WZRHPG300NH_GPIO_EXP_BASE + 2) -+#define WZRHPG300NH_GPIO_BTN_QOS_ON (WZRHPG300NH_GPIO_EXP_BASE + 3) -+#define WZRHPG300NH_GPIO_BTN_USB (WZRHPG300NH_GPIO_EXP_BASE + 5) -+#define WZRHPG300NH_GPIO_BTN_ROUTER_AUTO (WZRHPG300NH_GPIO_EXP_BASE + 6) -+#define WZRHPG300NH_GPIO_BTN_QOS_OFF (WZRHPG300NH_GPIO_EXP_BASE + 7) + -+#define WZRHPG300NH_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPG300NH_KEYS_POLL_INTERVAL) ++#define WNR2000_GPIO_LED_PWR_GREEN 14 ++#define WNR2000_GPIO_LED_PWR_AMBER 7 ++#define WNR2000_GPIO_LED_WPS 4 ++#define WNR2000_GPIO_LED_WLAN 6 ++#define WNR2000_GPIO_BTN_RESET 21 ++#define WNR2000_GPIO_BTN_WPS 8 + -+#define WZRHPG300NH_MAC_OFFSET 0x20c ++#define WNR2000_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WNR2000_KEYS_DEBOUNCE_INTERVAL (3 * WNR2000_KEYS_POLL_INTERVAL) + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wzrhpg300nh_flash_partitions[] = { ++static struct mtd_partition wnr2000_partitions[] = { + { + .name = "u-boot", + .offset = 0, -+ .size = 0x0040000, ++ .size = 0x040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "u-boot-env", -+ .offset = 0x0040000, -+ .size = 0x0020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "kernel", -+ .offset = 0x0060000, -+ .size = 0x0100000, ++ .offset = 0x040000, ++ .size = 0x010000, + }, { + .name = "rootfs", -+ .offset = 0x0160000, -+ .size = 0x1e60000, ++ .offset = 0x050000, ++ .size = 0x240000, + }, { -+ .name = "user_property", -+ .offset = 0x1fc0000, -+ .size = 0x0020000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "user-config", ++ .offset = 0x290000, ++ .size = 0x010000, ++ }, { ++ .name = "uImage", ++ .offset = 0x2a0000, ++ .size = 0x120000, ++ }, { ++ .name = "language_table", ++ .offset = 0x3c0000, ++ .size = 0x020000, ++ }, { ++ .name = "rootfs_checksum", ++ .offset = 0x3e0000, ++ .size = 0x010000, + }, { + .name = "art", -+ .offset = 0x1fe0000, -+ .size = 0x0020000, ++ .offset = 0x3f0000, ++ .size = 0x010000, + .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x0060000, -+ .size = 0x1f60000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct ar91xx_flash_platform_data wzrhpg300nh_flash_data = { -+ .width = 2, ++static struct flash_platform_data wnr2000_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = wzrhpg300nh_flash_partitions, -+ .nr_parts = ARRAY_SIZE(wzrhpg300nh_flash_partitions), ++ .parts = wnr2000_partitions, ++ .nr_parts = ARRAY_SIZE(wnr2000_partitions), +#endif +}; + -+#define WZRHPG300NH_FLASH_BASE 0x1e000000 -+#define WZRHPG300NH_FLASH_SIZE (32 * 1024 * 1024) -+ -+static struct resource wzrhpg300nh_flash_resources[] = { -+ [0] = { -+ .start = WZRHPG300NH_FLASH_BASE, -+ .end = WZRHPG300NH_FLASH_BASE + WZRHPG300NH_FLASH_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+static struct platform_device wzrhpg300nh_flash_device = { -+ .name = "ar91xx-flash", -+ .id = -1, -+ .resource = wzrhpg300nh_flash_resources, -+ .num_resources = ARRAY_SIZE(wzrhpg300nh_flash_resources), -+ .dev = { -+ .platform_data = &wzrhpg300nh_flash_data, -+ } -+}; -+ -+static struct gpio_led wzrhpg300nh_leds_gpio[] __initdata = { ++static struct gpio_led wnr2000_leds_gpio[] __initdata = { + { -+ .name = "wzr-hp-g300nh:orange:security", -+ .gpio = WZRHPG300NH_GPIO_LED_SECURITY, -+ .active_low = 1, -+ }, { -+ .name = "wzr-hp-g300nh:green:wireless", -+ .gpio = WZRHPG300NH_GPIO_LED_WIRELESS, ++ .name = "wnr2000:green:power", ++ .gpio = WNR2000_GPIO_LED_PWR_GREEN, + .active_low = 1, + }, { -+ .name = "wzr-hp-g300nh:green:router", -+ .gpio = WZRHPG300NH_GPIO_LED_ROUTER, ++ .name = "wnr2000:amber:power", ++ .gpio = WNR2000_GPIO_LED_PWR_AMBER, + .active_low = 1, + }, { -+ .name = "wzr-hp-g300nh:red:diag", -+ .gpio = WZRHPG300NH_GPIO_LED_DIAG, ++ .name = "wnr2000:green:wps", ++ .gpio = WNR2000_GPIO_LED_WPS, + .active_low = 1, + }, { -+ .name = "wzr-hp-g300nh:blue:usb", -+ .gpio = WZRHPG300NH_GPIO_LED_USB, ++ .name = "wnr2000:blue:wlan", ++ .gpio = WNR2000_GPIO_LED_WLAN, + .active_low = 1, + } +}; + -+static struct gpio_keys_button wzrhpg300nh_gpio_keys[] __initdata = { ++static struct gpio_keys_button wnr2000_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_RESET, -+ .active_low = 1, ++ .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNR2000_GPIO_BTN_RESET, + }, { -+ .desc = "aoss", ++ .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_AOSS, -+ .active_low = 1, -+ }, { -+ .desc = "usb", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_USB, -+ .active_low = 1, -+ }, { -+ .desc = "qos_on", -+ .type = EV_KEY, -+ .code = BTN_3, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_QOS_ON, -+ .active_low = 0, -+ }, { -+ .desc = "qos_off", -+ .type = EV_KEY, -+ .code = BTN_4, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_QOS_OFF, -+ .active_low = 0, -+ }, { -+ .desc = "router_on", -+ .type = EV_KEY, -+ .code = BTN_5, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_ON, -+ .active_low = 0, -+ }, { -+ .desc = "router_auto", -+ .type = EV_KEY, -+ .code = BTN_6, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_AUTO, -+ .active_low = 0, ++ .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNR2000_GPIO_BTN_WPS, + } +}; + -+static struct nxp_74hc153_platform_data wzrhpg300nh_74hc153_data = { -+ .gpio_base = WZRHPG300NH_GPIO_EXP_BASE, -+ .gpio_pin_s0 = WZRHPG300NH_GPIO_74HC153_S0, -+ .gpio_pin_s1 = WZRHPG300NH_GPIO_74HC153_S1, -+ .gpio_pin_1y = WZRHPG300NH_GPIO_74HC153_1Y, -+ .gpio_pin_2y = WZRHPG300NH_GPIO_74HC153_2Y, -+}; ++static void __init wnr2000_setup(void) ++{ ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + -+static struct platform_device wzrhpg300nh_74hc153_device = { -+ .name = NXP_74HC153_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &wzrhpg300nh_74hc153_data, -+ } -+}; ++ ar71xx_add_device_mdio(0x0); + -+static struct rtl8366_platform_data wzrhpg300nh_rtl8366_data = { -+ .gpio_sda = WZRHPG300NH_GPIO_RTL8366_SDA, -+ .gpio_sck = WZRHPG300NH_GPIO_RTL8366_SCK, -+}; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, eeprom, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.has_ar8216 = 1; + -+static struct platform_device wzrhpg300nh_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &wzrhpg300nh_rtl8366_data, -+ } -+}; ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, eeprom, 1); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = 0x10; + -+static struct platform_device wzrhpg300nh_rtl8366rb_device = { -+ .name = RTL8366RB_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &wzrhpg300nh_rtl8366_data, -+ } -+}; ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+static void __init wzrhpg300nh_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 *mac = eeprom + WZRHPG300NH_MAC_OFFSET; -+ bool hasrtl8366rb = false; ++ ar71xx_add_device_m25p80(&wnr2000_flash_data); + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio), ++ wnr2000_leds_gpio); + -+ if (rtl8366_smi_detect(&wzrhpg300nh_rtl8366_data) == RTL8366_TYPE_RB) -+ hasrtl8366rb = true; ++ ar71xx_register_gpio_keys_polled(-1, WNR2000_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wnr2000_gpio_keys), ++ wnr2000_gpio_keys); + -+ if (hasrtl8366rb) { -+ ar71xx_eth0_pll_data.pll_1000 = 0x1f000000; -+ ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev; -+ ar71xx_eth1_pll_data.pll_1000 = 0x100; -+ ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev; -+ } else { -+ ar71xx_eth0_pll_data.pll_1000 = 0x1e000100; -+ ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; -+ ar71xx_eth1_pll_data.pll_1000 = 0x1e000100; -+ ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; ++ ++ ar9xxx_add_device_wmac(eeprom, NULL); ++} ++ ++MIPS_MACHINE(AR71XX_MACH_WNR2000, "WNR2000", "NETGEAR WNR2000", wnr2000_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.39/arch/mips/ar71xx/mach-wp543.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wp543.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wp543.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,101 @@ ++/* ++ * Compex WP543/WPJ543 board support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++ ++#include ++ ++#include "machtype.h" ++#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-pb42-pci.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-usb.h" ++ ++#define WP543_GPIO_SW6 2 ++#define WP543_GPIO_LED_1 3 ++#define WP543_GPIO_LED_2 4 ++#define WP543_GPIO_LED_WLAN 5 ++#define WP543_GPIO_LED_CONN 6 ++#define WP543_GPIO_LED_DIAG 7 ++#define WP543_GPIO_SW4 8 ++ ++#define WP543_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WP543_KEYS_DEBOUNCE_INTERVAL (3 * WP543_KEYS_POLL_INTERVAL) ++ ++static struct gpio_led wp543_leds_gpio[] __initdata = { ++ { ++ .name = "wp543:green:led1", ++ .gpio = WP543_GPIO_LED_1, ++ .active_low = 1, ++ }, { ++ .name = "wp543:green:led2", ++ .gpio = WP543_GPIO_LED_2, ++ .active_low = 1, ++ }, { ++ .name = "wp543:green:wlan", ++ .gpio = WP543_GPIO_LED_WLAN, ++ .active_low = 1, ++ }, { ++ .name = "wp543:green:conn", ++ .gpio = WP543_GPIO_LED_CONN, ++ .active_low = 1, ++ }, { ++ .name = "wp543:green:diag", ++ .gpio = WP543_GPIO_LED_DIAG, ++ .active_low = 1, + } ++}; + -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth0_data.speed = SPEED_1000; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++static struct gpio_keys_button wp543_gpio_keys[] __initdata = { ++ { ++ .desc = "sw6", ++ .type = EV_KEY, ++ .code = BTN_0, ++ .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WP543_GPIO_SW6, ++ }, { ++ .desc = "sw4", ++ .type = EV_KEY, ++ .code = BTN_1, ++ .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WP543_GPIO_SW4, ++ } ++}; + -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ar71xx_eth1_data.phy_mask = 0x10; ++static void __init wp543_setup(void) ++{ ++ ar71xx_add_device_m25p80(NULL); ++ ++ ar71xx_add_device_mdio(0xfffffff7); + ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 0); ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ++ ar71xx_eth0_data.phy_mask = 0x08; ++ ar71xx_eth0_data.reset_bit = RESET_MODULE_GE0_MAC | ++ RESET_MODULE_GE0_PHY; + ar71xx_add_device_eth(0); -+ ar71xx_add_device_eth(1); + + ar71xx_add_device_usb(); -+ ar9xxx_add_device_wmac(eeprom, NULL); -+ -+ platform_device_register(&wzrhpg300nh_74hc153_device); -+ platform_device_register(&wzrhpg300nh_flash_device); -+ -+ if (hasrtl8366rb) -+ platform_device_register(&wzrhpg300nh_rtl8366rb_device); -+ else -+ platform_device_register(&wzrhpg300nh_rtl8366s_device); + -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh_leds_gpio), -+ wzrhpg300nh_leds_gpio); ++ pb42_pci_init(); + -+ ar71xx_register_gpio_keys_polled(-1, WZRHPG300NH_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wzrhpg300nh_gpio_keys), -+ wzrhpg300nh_gpio_keys); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio), ++ wp543_leds_gpio); + ++ ar71xx_register_gpio_keys_polled(-1, WP543_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wp543_gpio_keys), ++ wp543_gpio_keys); +} + -+MIPS_MACHINE(AR71XX_MACH_WZR_HP_G300NH, "WZR-HP-G300NH", -+ "Buffalo WZR-HP-G300NH", wzrhpg300nh_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-zcn-1523h.c linux-2.6.39/arch/mips/ar71xx/mach-zcn-1523h.c ---- linux-2.6.39.orig/arch/mips/ar71xx/mach-zcn-1523h.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/mach-zcn-1523h.c 2011-08-24 02:41:55.649418561 +0200 -@@ -0,0 +1,214 @@ ++MIPS_MACHINE(AR71XX_MACH_WP543, "WP543", "Compex WP543", wp543_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt160nl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wrt160nl.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,161 @@ +/* -+ * Zcomax ZCN-1523H-2-8/5-16 board support ++ * Linksys WRT160NL board support + * -+ * Copyright (C) 2010 Gabor Juhos ++ * Copyright (C) 2009 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published @@ -9840,8385 +9038,7312 @@ diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-zcn-1523h.c linux-2.6.39/arch/ +#include "machtype.h" +#include "devices.h" +#include "dev-m25p80.h" -+#include "dev-ap91-pci.h" ++#include "dev-ar9xxx-wmac.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" ++#include "dev-usb.h" ++#include "nvram.h" + -+#define ZCN_1523H_GPIO_BTN_RESET 0 -+#define ZCN_1523H_GPIO_LED_INIT 11 -+#define ZCN_1523H_GPIO_LED_LAN1 17 ++#define WRT160NL_GPIO_LED_POWER 14 ++#define WRT160NL_GPIO_LED_WPS_AMBER 9 ++#define WRT160NL_GPIO_LED_WPS_BLUE 8 ++#define WRT160NL_GPIO_LED_WLAN 6 + -+#define ZCN_1523H_2_GPIO_LED_WEAK 13 -+#define ZCN_1523H_2_GPIO_LED_MEDIUM 14 -+#define ZCN_1523H_2_GPIO_LED_STRONG 15 ++#define WRT160NL_GPIO_BTN_WPS 7 ++#define WRT160NL_GPIO_BTN_RESET 21 + -+#define ZCN_1523H_5_GPIO_LED_UNKNOWN 1 -+#define ZCN_1523H_5_GPIO_LED_LAN2 13 -+#define ZCN_1523H_5_GPIO_LED_WEAK 14 -+#define ZCN_1523H_5_GPIO_LED_MEDIUM 15 -+#define ZCN_1523H_5_GPIO_LED_STRONG 16 ++#define WRT160NL_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WRT160NL_KEYS_DEBOUNCE_INTERVAL (3 * WRT160NL_KEYS_POLL_INTERVAL) + -+#define ZCN_1523H_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ZCN_1523H_KEYS_DEBOUNCE_INTERVAL (3 * ZCN_1523H_KEYS_POLL_INTERVAL) ++#define WRT160NL_NVRAM_ADDR 0x1f7e0000 ++#define WRT160NL_NVRAM_SIZE 0x10000 + +#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition zcn_1523h_partitions[] = { ++static struct mtd_partition wrt160nl_partitions[] = { + { + .name = "u-boot", + .offset = 0, + .size = 0x040000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "u-boot-env", -+ .offset = 0x040000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "rootfs", -+ .offset = 0x050000, -+ .size = 0x610000, -+ }, { + .name = "kernel", -+ .offset = 0x660000, -+ .size = 0x170000, ++ .offset = 0x040000, ++ .size = 0x0e0000, + }, { -+ .name = "configure", -+ .offset = 0x7d0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, ++ .name = "filesytem", ++ .offset = 0x120000, ++ .size = 0x6c0000, + }, { -+ .name = "mfg", ++ .name = "nvram", + .offset = 0x7e0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "eeprom", ++ .name = "ART", + .offset = 0x7f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", -+ .offset = 0x050000, -+ .size = 0x780000, ++ .offset = 0x040000, ++ .size = 0x7a0000, + } +}; +#endif /* CONFIG_MTD_PARTITIONS */ + -+static struct flash_platform_data zcn_1523h_flash_data = { ++static struct flash_platform_data wrt160nl_flash_data = { +#ifdef CONFIG_MTD_PARTITIONS -+ .parts = zcn_1523h_partitions, -+ .nr_parts = ARRAY_SIZE(zcn_1523h_partitions), ++ .parts = wrt160nl_partitions, ++ .nr_parts = ARRAY_SIZE(wrt160nl_partitions), +#endif +}; + -+static struct gpio_keys_button zcn_1523h_gpio_keys[] __initdata = { ++static struct gpio_led wrt160nl_leds_gpio[] __initdata = { + { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ZCN_1523H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ZCN_1523H_GPIO_BTN_RESET, ++ .name = "wrt160nl:blue:power", ++ .gpio = WRT160NL_GPIO_LED_POWER, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, { ++ .name = "wrt160nl:amber:wps", ++ .gpio = WRT160NL_GPIO_LED_WPS_AMBER, ++ .active_low = 1, ++ }, { ++ .name = "wrt160nl:blue:wps", ++ .gpio = WRT160NL_GPIO_LED_WPS_BLUE, ++ .active_low = 1, ++ }, { ++ .name = "wrt160nl:blue:wlan", ++ .gpio = WRT160NL_GPIO_LED_WLAN, + .active_low = 1, + } +}; + -+static struct gpio_led zcn_1523h_leds_gpio[] __initdata = { ++static struct gpio_keys_button wrt160nl_gpio_keys[] __initdata = { + { -+ .name = "zcn-1523h:amber:init", -+ .gpio = ZCN_1523H_GPIO_LED_INIT, ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WRT160NL_GPIO_BTN_RESET, + .active_low = 1, + }, { -+ .name = "zcn-1523h:green:lan1", -+ .gpio = ZCN_1523H_GPIO_LED_LAN1, ++ .desc = "wps", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WRT160NL_GPIO_BTN_WPS, + .active_low = 1, + } +}; + -+static struct gpio_led zcn_1523h_2_leds_gpio[] __initdata = { ++static void __init wrt160nl_setup(void) ++{ ++ const char *nvram = (char *) KSEG1ADDR(WRT160NL_NVRAM_ADDR); ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 mac[6]; ++ ++ if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, ++ "lan_hwaddr=", mac) == 0) { ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ } ++ ++ ar71xx_add_device_mdio(0x0); ++ ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.phy_mask = 0x01; ++ ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.phy_mask = 0x10; ++ ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); ++ ++ ar71xx_add_device_m25p80(&wrt160nl_flash_data); ++ ++ ar71xx_add_device_usb(); ++ ++ if (nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, ++ "wl0_hwaddr=", mac) == 0) ++ ar9xxx_add_device_wmac(eeprom, mac); ++ else ++ ar9xxx_add_device_wmac(eeprom, NULL); ++ ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt160nl_leds_gpio), ++ wrt160nl_leds_gpio); ++ ++ ar71xx_register_gpio_keys_polled(-1, WRT160NL_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wrt160nl_gpio_keys), ++ wrt160nl_gpio_keys); ++ ++} ++ ++MIPS_MACHINE(AR71XX_MACH_WRT160NL, "WRT160NL", "Linksys WRT160NL", ++ wrt160nl_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wrt400n.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wrt400n.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,164 @@ ++/* ++ * Linksys WRT400N board support ++ * ++ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2009 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++ ++#include ++ ++#include "machtype.h" ++#include "devices.h" ++#include "dev-ap94-pci.h" ++#include "dev-m25p80.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++ ++#define WRT400N_GPIO_LED_ORANGE 5 ++#define WRT400N_GPIO_LED_GREEN 4 ++#define WRT400N_GPIO_LED_POWER 1 ++#define WRT400N_GPIO_LED_WLAN 0 ++ ++#define WRT400N_GPIO_BTN_RESET 8 ++#define WRT400N_GPIO_BTN_WLSEC 3 ++ ++#define WRT400N_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WRT400N_KEYS_DEBOUNE_INTERVAL (3 * WRT400N_KEYS_POLL_INTERVAL) ++ ++#define WRT400N_MAC_ADDR_OFFSET 0x120c ++#define WRT400N_CALDATA0_OFFSET 0x1000 ++#define WRT400N_CALDATA1_OFFSET 0x5000 ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition wrt400n_partitions[] = { + { -+ .name = "zcn-1523h:red:weak", -+ .gpio = ZCN_1523H_2_GPIO_LED_WEAK, -+ .active_low = 1, ++ .name = "uboot", ++ .offset = 0, ++ .size = 0x030000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "zcn-1523h:amber:medium", -+ .gpio = ZCN_1523H_2_GPIO_LED_MEDIUM, -+ .active_low = 1, ++ .name = "env", ++ .offset = 0x030000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, + }, { -+ .name = "zcn-1523h:green:strong", -+ .gpio = ZCN_1523H_2_GPIO_LED_STRONG, -+ .active_low = 1, ++ .name = "linux", ++ .offset = 0x040000, ++ .size = 0x140000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x180000, ++ .size = 0x630000, ++ }, { ++ .name = "nvram", ++ .offset = 0x7b0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "factory", ++ .offset = 0x7c0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "language", ++ .offset = 0x7d0000, ++ .size = 0x020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "caldata", ++ .offset = 0x7f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x040000, ++ .size = 0x770000, + } +}; ++#endif /* CONFIG_MTD_PARTITIONS */ ++ ++static struct flash_platform_data wrt400n_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = wrt400n_partitions, ++ .nr_parts = ARRAY_SIZE(wrt400n_partitions), ++#endif ++}; + -+static struct gpio_led zcn_1523h_5_leds_gpio[] __initdata = { ++static struct gpio_led wrt400n_leds_gpio[] __initdata = { + { -+ .name = "zcn-1523h:red:weak", -+ .gpio = ZCN_1523H_5_GPIO_LED_WEAK, ++ .name = "wrt400n:green:status", ++ .gpio = WRT400N_GPIO_LED_GREEN, + .active_low = 1, + }, { -+ .name = "zcn-1523h:amber:medium", -+ .gpio = ZCN_1523H_5_GPIO_LED_MEDIUM, ++ .name = "wrt400n:amber:aoss", ++ .gpio = WRT400N_GPIO_LED_ORANGE, + .active_low = 1, + }, { -+ .name = "zcn-1523h:green:strong", -+ .gpio = ZCN_1523H_5_GPIO_LED_STRONG, ++ .name = "wrt400n:green:wlan", ++ .gpio = WRT400N_GPIO_LED_WLAN, + .active_low = 1, + }, { -+ .name = "zcn-1523h:green:lan2", -+ .gpio = ZCN_1523H_5_GPIO_LED_LAN2, ++ .name = "wrt400n:green:power", ++ .gpio = WRT400N_GPIO_LED_POWER, ++ .active_low = 1, ++ } ++}; ++ ++static struct gpio_keys_button wrt400n_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL, ++ .gpio = WRT400N_GPIO_BTN_RESET, + .active_low = 1, + }, { -+ .name = "zcn-1523h:amber:unknown", -+ .gpio = ZCN_1523H_5_GPIO_LED_UNKNOWN, ++ .desc = "wlsec", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL, ++ .gpio = WRT400N_GPIO_BTN_WLSEC, ++ .active_low = 1, + } +}; + -+static void __init zcn_1523h_generic_setup(void) ++static void __init wrt400n_setup(void) +{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f7e0004); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ar71xx_add_device_m25p80(&zcn_1523h_flash_data); -+ -+ ar71xx_add_device_leds_gpio(0, ARRAY_SIZE(zcn_1523h_leds_gpio), -+ zcn_1523h_leds_gpio); -+ -+ ar71xx_register_gpio_keys_polled(-1, ZCN_1523H_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(zcn_1523h_gpio_keys), -+ zcn_1523h_gpio_keys); -+ -+ ap91_pci_init(ee, mac); ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *mac = art + WRT400N_MAC_ADDR_OFFSET; + -+ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); -+ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); ++ ar71xx_add_device_mdio(0x0); + -+ /* LAN1 port */ ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 1); + ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ar71xx_eth0_data.speed = SPEED_100; + ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+ /* LAN2 port */ ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 2); + ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.speed = SPEED_1000; -+ ar71xx_eth1_data.duplex = DUPLEX_FULL; ++ ar71xx_eth1_data.phy_mask = 0x10; + -+ ar71xx_add_device_mdio(0x0); + ar71xx_add_device_eth(0); -+} ++ ar71xx_add_device_eth(1); + -+static void __init zcn_1523h_2_setup(void) -+{ -+ zcn_1523h_generic_setup(); -+ ap91_pci_setup_wmac_gpio(BIT(9), 0); ++ ar71xx_add_device_m25p80(&wrt400n_flash_data); + -+ ar71xx_add_device_leds_gpio(1, ARRAY_SIZE(zcn_1523h_2_leds_gpio), -+ zcn_1523h_2_leds_gpio); -+} ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wrt400n_leds_gpio), ++ wrt400n_leds_gpio); + -+MIPS_MACHINE(AR71XX_MACH_ZCN_1523H_2, "ZCN-1523H-2", "Zcomax ZCN-1523H-2", -+ zcn_1523h_2_setup); ++ ar71xx_register_gpio_keys_polled(-1, WRT400N_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wrt400n_gpio_keys), ++ wrt400n_gpio_keys); + -+static void __init zcn_1523h_5_setup(void) -+{ -+ zcn_1523h_generic_setup(); -+ ap91_pci_setup_wmac_gpio(BIT(8), 0); ++ ap94_pci_init(art + WRT400N_CALDATA0_OFFSET, NULL, ++ art + WRT400N_CALDATA1_OFFSET, NULL); ++} + -+ ar71xx_add_device_leds_gpio(1, ARRAY_SIZE(zcn_1523h_5_leds_gpio), -+ zcn_1523h_5_leds_gpio); -+ ar71xx_add_device_eth(1); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_ZCN_1523H_5, "ZCN-1523H-5", "Zcomax ZCN-1523H-5", -+ zcn_1523h_5_setup); -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/Makefile linux-2.6.39/arch/mips/ar71xx/Makefile ---- linux-2.6.39.orig/arch/mips/ar71xx/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/Makefile 2011-08-24 02:41:55.677990354 +0200 -@@ -0,0 +1,67 @@ -+# -+# Makefile for the Atheros AR71xx SoC specific parts of the kernel -+# -+# Copyright (C) 2008-2009 Gabor Juhos -+# Copyright (C) 2008 Imre Kaloz -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License version 2 as published -+# by the Free Software Foundation. -+ -+obj-y := prom.o irq.o setup.o devices.o gpio.o ar71xx.o -+ -+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -+obj-$(CONFIG_PCI) += pci.o -+ -+obj-$(CONFIG_AR71XX_DEV_AP91_PCI) += dev-ap91-pci.o -+obj-$(CONFIG_AR71XX_DEV_AP94_PCI) += dev-ap94-pci.o -+obj-$(CONFIG_AR71XX_DEV_AR9XXX_WMAC) += dev-ar9xxx-wmac.o -+obj-$(CONFIG_AR71XX_DEV_DB120_PCI) += dev-db120-pci.o -+obj-$(CONFIG_AR71XX_DEV_DSA) += dev-dsa.o -+obj-$(CONFIG_AR71XX_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o -+obj-$(CONFIG_AR71XX_DEV_LEDS_GPIO) += dev-leds-gpio.o -+obj-$(CONFIG_AR71XX_DEV_M25P80) += dev-m25p80.o -+obj-$(CONFIG_AR71XX_DEV_PB42_PCI) += dev-pb42-pci.o -+obj-$(CONFIG_AR71XX_DEV_PB9X_PCI) += dev-pb9x-pci.o -+obj-$(CONFIG_AR71XX_DEV_USB) += dev-usb.o -+ -+obj-$(CONFIG_AR71XX_NVRAM) += nvram.o -+obj-$(CONFIG_AR71XX_PCI_ATH9K_FIXUP) += pci-ath9k-fixup.o -+ -+obj-$(CONFIG_AR71XX_MACH_AP121) += mach-ap121.o -+obj-$(CONFIG_AR71XX_MACH_AP81) += mach-ap81.o -+obj-$(CONFIG_AR71XX_MACH_AP83) += mach-ap83.o -+obj-$(CONFIG_AR71XX_MACH_AP96) += mach-ap96.o -+obj-$(CONFIG_AR71XX_MACH_AW_NR580) += mach-aw-nr580.o -+obj-$(CONFIG_AR71XX_MACH_DB120) += mach-db120.o -+obj-$(CONFIG_AR71XX_MACH_DIR_600_A1) += mach-dir-600-a1.o -+obj-$(CONFIG_AR71XX_MACH_DIR_615_C1) += mach-dir-615-c1.o -+obj-$(CONFIG_AR71XX_MACH_DIR_825_B1) += mach-dir-825-b1.o -+obj-$(CONFIG_AR71XX_MACH_EAP7660D) += mach-eap7660d.o -+obj-$(CONFIG_AR71XX_MACH_JA76PF) += mach-ja76pf.o -+obj-$(CONFIG_AR71XX_MACH_JWAP003) += mach-jwap003.o -+obj-$(CONFIG_AR71XX_MACH_MZK_W04NU) += mach-mzk-w04nu.o -+obj-$(CONFIG_AR71XX_MACH_MZK_W300NH) += mach-mzk-w300nh.o -+obj-$(CONFIG_AR71XX_MACH_NBG460N) += mach-nbg460n.o -+obj-$(CONFIG_AR71XX_MACH_PB42) += mach-pb42.o -+obj-$(CONFIG_AR71XX_MACH_PB44) += mach-pb44.o -+obj-$(CONFIG_AR71XX_MACH_PB92) += mach-pb92.o -+obj-$(CONFIG_AR71XX_MACH_RB4XX) += mach-rb4xx.o -+obj-$(CONFIG_AR71XX_MACH_RB750) += mach-rb750.o -+obj-$(CONFIG_AR71XX_MACH_TEW_632BRP) += mach-tew-632brp.o -+obj-$(CONFIG_AR71XX_MACH_TL_MR3X20) += mach-tl-mr3x20.o -+obj-$(CONFIG_AR71XX_MACH_TL_WA901ND) += mach-tl-wa901nd.o -+obj-$(CONFIG_AR71XX_MACH_TL_WA901ND_V2) += mach-tl-wa901nd-v2.o -+obj-$(CONFIG_AR71XX_MACH_TL_WR741ND) += mach-tl-wr741nd.o -+obj-$(CONFIG_AR71XX_MACH_TL_WR841N_V1) += mach-tl-wr841n.o -+obj-$(CONFIG_AR71XX_MACH_TL_WR941ND) += mach-tl-wr941nd.o -+obj-$(CONFIG_AR71XX_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o -+obj-$(CONFIG_AR71XX_MACH_UBNT) += mach-ubnt.o -+obj-$(CONFIG_AR71XX_MACH_WNDR3700) += mach-wndr3700.o -+obj-$(CONFIG_AR71XX_MACH_WNR2000) += mach-wnr2000.o -+obj-$(CONFIG_AR71XX_MACH_WP543) += mach-wp543.o -+obj-$(CONFIG_AR71XX_MACH_WRT160NL) += mach-wrt160nl.o -+obj-$(CONFIG_AR71XX_MACH_WRT400N) += mach-wrt400n.o -+obj-$(CONFIG_AR71XX_MACH_WZR_HP_G300NH) += mach-wzr-hp-g300nh.o -+obj-$(CONFIG_AR71XX_MACH_WZR_HP_AG300H) += mach-wzr-hp-ag300h.o -+obj-$(CONFIG_AR71XX_MACH_ZCN_1523H) += mach-zcn-1523h.o -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.c linux-2.6.39/arch/mips/ar71xx/nvram.c ---- linux-2.6.39.orig/arch/mips/ar71xx/nvram.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/nvram.c 2011-08-24 02:41:55.677990354 +0200 -@@ -0,0 +1,75 @@ ++MIPS_MACHINE(AR71XX_MACH_WRT400N, "WRT400N", "Linksys WRT400N", wrt400n_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-ag300h.c linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-ag300h.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-ag300h.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-ag300h.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,231 @@ +/* -+ * Atheros AR71xx minimal nvram support ++ * Buffalo WZR-HP-AG300H board support + * -+ * Copyright (C) 2009 Gabor Juhos ++ * Copyright (C) 2011 Felix Fietkau + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+#include -+#include ++#include ++#include ++#include ++#include + -+#include "nvram.h" ++#include ++#include ++#include + -+char *nvram_find_var(const char *name, const char *buf, unsigned buf_len) -+{ -+ unsigned len = strlen(name); -+ char *cur, *last; ++#include "machtype.h" ++#include "devices.h" ++#include "dev-ap94-pci.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-m25p80.h" ++#include "dev-usb.h" + -+ if (buf_len == 0 || len == 0) -+ return NULL; ++#define WZRHPAG300H_MAC_OFFSET 0x20c ++#define WZRHPAG300H_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPAG300H_KEYS_POLL_INTERVAL) + -+ if (buf_len < len) -+ return NULL; ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition wzrhpag300h_flash_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x0040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "u-boot-env", ++ .offset = 0x0040000, ++ .size = 0x0010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "art", ++ .offset = 0x0050000, ++ .size = 0x0010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "kernel", ++ .offset = 0x0060000, ++ .size = 0x0100000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x0160000, ++ .size = 0x1e90000, ++ }, { ++ .name = "user_property", ++ .offset = 0x1ff0000, ++ .size = 0x0010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x0060000, ++ .size = 0x1f90000, ++ } ++}; + -+ if (len == 1) -+ return memchr(buf, (int) *name, buf_len); ++#endif /* CONFIG_MTD_PARTITIONS */ + -+ last = (char *) buf + buf_len - len; -+ for (cur = (char *) buf; cur <= last; cur++) -+ if (cur[0] == name[0] && memcmp(cur, name, len) == 0) -+ return cur + len; ++static struct mtd_info *concat_devs[2] = { NULL, NULL }; ++static struct work_struct mtd_concat_work; + -+ return NULL; ++static void mtd_concat_add_work(struct work_struct *work) ++{ ++ struct mtd_info *mtd; ++ ++ mtd = mtd_concat_create(concat_devs, ARRAY_SIZE(concat_devs), "flash"); ++ ++#ifdef CONFIG_MTD_PARTITIONS ++ add_mtd_partitions(mtd, wzrhpag300h_flash_partitions, ++ ARRAY_SIZE(wzrhpag300h_flash_partitions)); ++#else ++ add_mtd_device(mtd); ++#endif +} + -+int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, -+ const char *name, char *mac) ++static void mtd_concat_add(struct mtd_info *mtd) +{ -+ char *buf; -+ char *mac_str; -+ int ret; -+ int t; ++ static bool registered = false; + -+ buf = vmalloc(nvram_len); -+ if (!buf) -+ return -ENOMEM; ++ if (registered) ++ return; + -+ memcpy(buf, nvram, nvram_len); -+ buf[nvram_len - 1] = '\0'; ++ if (!strcmp(mtd->name, "spi0.0")) ++ concat_devs[0] = mtd; ++ else if (!strcmp(mtd->name, "spi0.1")) ++ concat_devs[1] = mtd; ++ else ++ return; + -+ mac_str = nvram_find_var(name, buf, nvram_len); -+ if (!mac_str) { -+ ret = -EINVAL; -+ goto free; -+ } ++ if (!concat_devs[0] || !concat_devs[1]) ++ return; + -+ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); ++ registered = true; ++ INIT_WORK(&mtd_concat_work, mtd_concat_add_work); ++ schedule_work(&mtd_concat_work); ++} + -+ if (t != 6) { -+ ret = -EINVAL; -+ goto free; -+ } ++static void mtd_concat_remove(struct mtd_info *mtd) ++{ ++} + -+ ret = 0; ++static void add_mtd_concat_notifier(void) ++{ ++ static struct mtd_notifier not = { ++ .add = mtd_concat_add, ++ .remove = mtd_concat_remove, ++ }; + -+free: -+ vfree(buf); -+ return ret; ++ register_mtd_user(¬); +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.h linux-2.6.39/arch/mips/ar71xx/nvram.h ---- linux-2.6.39.orig/arch/mips/ar71xx/nvram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/nvram.h 2011-08-24 02:41:55.687991145 +0200 -@@ -0,0 +1,19 @@ -+/* -+ * Atheros AR71xx minimal nvram support -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ + -+#ifndef _AR71XX_NVRAM_H -+#define _AR71XX_NVRAM_H ++static struct gpio_led wzrhpag300h_leds_gpio[] __initdata = { ++ { ++ .name = "wzr-hp-ag300h:red:diag", ++ .gpio = 1, ++ .active_low = 1, ++ }, ++}; + -+char *nvram_find_var(const char *name, const char *buf, -+ unsigned buf_len) __init; -+int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, -+ const char *name, char *mac) __init; + -+#endif /* _AR71XX_NVRAM_H */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.c linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.c ---- linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.c 2011-08-24 02:41:55.697990606 +0200 -@@ -0,0 +1,123 @@ -+/* -+ * Atheros AP94 reference board PCI initialization -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+struct ath9k_fixup { -+ u16 *cal_data; -+ unsigned slot; -+}; -+ -+static int ath9k_num_fixups; -+static struct ath9k_fixup ath9k_fixups[2]; -+ -+static void ath9k_pci_fixup(struct pci_dev *dev) -+{ -+ void __iomem *mem; -+ u16 *cal_data = NULL; -+ u16 cmd; -+ u32 bar0; -+ u32 val; -+ unsigned i; -+ -+ for (i = 0; i < ath9k_num_fixups; i++) { -+ if (ath9k_fixups[i].cal_data == NULL) -+ continue; -+ -+ if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn)) -+ continue; -+ -+ cal_data = ath9k_fixups[i].cal_data; -+ break; -+ } -+ -+ if (cal_data == NULL) -+ return; -+ -+ if (*cal_data != 0xa55a) { -+ pr_err("pci %s: invalid calibration data\n", pci_name(dev)); -+ return; ++static struct gpio_keys_button wzrhpag300h_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = 11, ++ .active_low = 1, ++ }, { ++ .desc = "usb", ++ .type = EV_KEY, ++ .code = BTN_2, ++ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = 3, ++ .active_low = 1, ++ }, { ++ .desc = "aoss", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = 5, ++ .active_low = 1, ++ }, { ++ .desc = "router_auto", ++ .type = EV_KEY, ++ .code = BTN_6, ++ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = 6, ++ .active_low = 1, ++ }, { ++ .desc = "router_off", ++ .type = EV_KEY, ++ .code = BTN_5, ++ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = 7, ++ .active_low = 1, + } ++}; + -+ pr_info("pci %s: fixup device configuration\n", pci_name(dev)); -+ -+ mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000); -+ if (!mem) { -+ pr_err("pci %s: ioremap error\n", pci_name(dev)); -+ return; ++static struct spi_board_info ar71xx_spi_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "m25p80", ++ }, ++ { ++ .bus_num = 0, ++ .chip_select = 1, ++ .max_speed_hz = 25000000, ++ .modalias = "m25p80", + } ++}; + -+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); -+ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7161: -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, -+ AR71XX_PCI_MEM_BASE); -+ break; -+ case AR71XX_SOC_AR7240: -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff); -+ break; -+ -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff); -+ break; ++static void __init wzrhpag300h_setup(void) ++{ ++ u8 *eeprom1 = (u8 *) KSEG1ADDR(0x1f051000); ++ u8 *eeprom2 = (u8 *) KSEG1ADDR(0x1f055000); ++ u8 *mac1 = eeprom1 + WZRHPAG300H_MAC_OFFSET; ++ u8 *mac2 = eeprom2 + WZRHPAG300H_MAC_OFFSET; + -+ default: -+ BUG(); -+ } ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac1, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac2, 1); + -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; -+ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ ar71xx_add_device_mdio(~(BIT(0) | BIT(4))); + -+ /* set pointer to first reg address */ -+ cal_data += 3; -+ while (*cal_data != 0xffff) { -+ u32 reg; -+ reg = *cal_data++; -+ val = *cal_data++; -+ val |= (*cal_data++) << 16; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; ++ ar71xx_eth0_data.phy_mask = BIT(0); + -+ __raw_writel(val, mem + reg); -+ udelay(100); -+ } ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = BIT(4); + -+ pci_read_config_dword(dev, PCI_VENDOR_ID, &val); -+ dev->vendor = val & 0xffff; -+ dev->device = (val >> 16) & 0xffff; ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); -+ dev->revision = val & 0xff; -+ dev->class = val >> 8; /* upper 3 bytes */ ++ ar71xx_add_device_usb(); ++ gpio_request(2, "usb"); ++ gpio_direction_output(2, 1); + -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); -+ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpag300h_leds_gpio), ++ wzrhpag300h_leds_gpio); + -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); ++ ar71xx_register_gpio_keys_polled(-1, WZRHPAG300H_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wzrhpag300h_gpio_keys), ++ wzrhpag300h_gpio_keys); + -+ iounmap(mem); -+} -+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup); ++ ar71xx_add_device_spi(NULL, ar71xx_spi_info, ++ ARRAY_SIZE(ar71xx_spi_info)); + -+void __init pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) -+{ -+ if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups)) -+ return; ++ add_mtd_concat_notifier(); + -+ ath9k_fixups[ath9k_num_fixups].slot = slot; -+ ath9k_fixups[ath9k_num_fixups].cal_data = cal_data; -+ ath9k_num_fixups++; ++ ap94_pci_init(eeprom1, mac1, eeprom2, mac2); +} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.h linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.h ---- linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.h 2011-08-24 02:41:55.697990606 +0200 -@@ -0,0 +1,6 @@ -+#ifndef _PCI_ATH9K_FIXUP -+#define _PCI_ATH9K_FIXUP + -+void pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) __init; ++MIPS_MACHINE(AR71XX_MACH_WZR_HP_AG300H, "WZR-HP-AG300H", ++ "Buffalo WZR-HP-AG300H", wzrhpag300h_setup); + -+#endif /* _PCI_ATH9K_FIXUP */ -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci.c linux-2.6.39/arch/mips/ar71xx/pci.c ---- linux-2.6.39.orig/arch/mips/ar71xx/pci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/pci.c 2011-08-24 02:41:55.697990606 +0200 -@@ -0,0 +1,97 @@ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-wzr-hp-g300nh.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,292 @@ +/* -+ * Atheros AR71xx PCI setup code -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Buffalo WZR-HP-G300NH board support + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Copyright (C) 2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+ -+#include ++#include ++#include ++#include ++#include ++#include + ++#include +#include -+#include ++#include + -+unsigned ar71xx_pci_nr_irqs __initdata; -+struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata; ++#include "machtype.h" ++#include "devices.h" ++#include "dev-ar9xxx-wmac.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-usb.h" + -+int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev); ++#define WZRHPG300NH_GPIO_LED_USB 0 ++#define WZRHPG300NH_GPIO_LED_DIAG 1 ++#define WZRHPG300NH_GPIO_LED_WIRELESS 6 ++#define WZRHPG300NH_GPIO_LED_SECURITY 17 ++#define WZRHPG300NH_GPIO_LED_ROUTER 18 + -+static int ar71xx_be_handler(struct pt_regs *regs, int is_fixup) -+{ -+ int err = 0; ++#define WZRHPG300NH_GPIO_RTL8366_SDA 19 ++#define WZRHPG300NH_GPIO_RTL8366_SCK 20 + -+ err = ar71xx_pci_be_handler(is_fixup); ++#define WZRHPG300NH_GPIO_74HC153_S0 9 ++#define WZRHPG300NH_GPIO_74HC153_S1 11 ++#define WZRHPG300NH_GPIO_74HC153_1Y 12 ++#define WZRHPG300NH_GPIO_74HC153_2Y 14 + -+ return (is_fixup && !err) ? MIPS_BE_FIXUP : MIPS_BE_FATAL; -+} ++#define WZRHPG300NH_GPIO_EXP_BASE 32 ++#define WZRHPG300NH_GPIO_BTN_AOSS (WZRHPG300NH_GPIO_EXP_BASE + 0) ++#define WZRHPG300NH_GPIO_BTN_RESET (WZRHPG300NH_GPIO_EXP_BASE + 1) ++#define WZRHPG300NH_GPIO_BTN_ROUTER_ON (WZRHPG300NH_GPIO_EXP_BASE + 2) ++#define WZRHPG300NH_GPIO_BTN_QOS_ON (WZRHPG300NH_GPIO_EXP_BASE + 3) ++#define WZRHPG300NH_GPIO_BTN_USB (WZRHPG300NH_GPIO_EXP_BASE + 5) ++#define WZRHPG300NH_GPIO_BTN_ROUTER_AUTO (WZRHPG300NH_GPIO_EXP_BASE + 6) ++#define WZRHPG300NH_GPIO_BTN_QOS_OFF (WZRHPG300NH_GPIO_EXP_BASE + 7) + -+int pcibios_plat_dev_init(struct pci_dev *dev) -+{ -+ if (ar71xx_pci_plat_dev_init) -+ return ar71xx_pci_plat_dev_init(dev); -+ -+ return 0; -+} -+ -+int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) -+{ -+ int ret = 0; -+ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ ret = ar71xx_pcibios_map_irq(dev, slot, pin); -+ break; ++#define WZRHPG300NH_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPG300NH_KEYS_POLL_INTERVAL) + -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ case AR71XX_SOC_AR9342: -+ case AR71XX_SOC_AR9344: -+ ret = ar724x_pcibios_map_irq(dev, slot, pin); -+ break; ++#define WZRHPG300NH_MAC_OFFSET 0x20c + -+ default: -+ break; ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition wzrhpg300nh_flash_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x0040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "u-boot-env", ++ .offset = 0x0040000, ++ .size = 0x0020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "kernel", ++ .offset = 0x0060000, ++ .size = 0x0100000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x0160000, ++ .size = 0x1e60000, ++ }, { ++ .name = "user_property", ++ .offset = 0x1fc0000, ++ .size = 0x0020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "art", ++ .offset = 0x1fe0000, ++ .size = 0x0020000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x0060000, ++ .size = 0x1f60000, + } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+ return ret; -+} ++static struct ar91xx_flash_platform_data wzrhpg300nh_flash_data = { ++ .width = 2, ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = wzrhpg300nh_flash_partitions, ++ .nr_parts = ARRAY_SIZE(wzrhpg300nh_flash_partitions), ++#endif ++}; + -+int __init ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) -+{ -+ int ret = 0; ++#define WZRHPG300NH_FLASH_BASE 0x1e000000 ++#define WZRHPG300NH_FLASH_SIZE (32 * 1024 * 1024) + -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ board_be_handler = ar71xx_be_handler; -+ ret = ar71xx_pcibios_init(); -+ break; ++static struct resource wzrhpg300nh_flash_resources[] = { ++ [0] = { ++ .start = WZRHPG300NH_FLASH_BASE, ++ .end = WZRHPG300NH_FLASH_BASE + WZRHPG300NH_FLASH_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; + -+ case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ case AR71XX_SOC_AR9342: -+ case AR71XX_SOC_AR9344: -+ ret = ar724x_pcibios_init(); -+ break; ++static struct platform_device wzrhpg300nh_flash_device = { ++ .name = "ar91xx-flash", ++ .id = -1, ++ .resource = wzrhpg300nh_flash_resources, ++ .num_resources = ARRAY_SIZE(wzrhpg300nh_flash_resources), ++ .dev = { ++ .platform_data = &wzrhpg300nh_flash_data, ++ } ++}; + -+ default: -+ return 0; ++static struct gpio_led wzrhpg300nh_leds_gpio[] __initdata = { ++ { ++ .name = "wzr-hp-g300nh:orange:security", ++ .gpio = WZRHPG300NH_GPIO_LED_SECURITY, ++ .active_low = 1, ++ }, { ++ .name = "wzr-hp-g300nh:green:wireless", ++ .gpio = WZRHPG300NH_GPIO_LED_WIRELESS, ++ .active_low = 1, ++ }, { ++ .name = "wzr-hp-g300nh:green:router", ++ .gpio = WZRHPG300NH_GPIO_LED_ROUTER, ++ .active_low = 1, ++ }, { ++ .name = "wzr-hp-g300nh:red:diag", ++ .gpio = WZRHPG300NH_GPIO_LED_DIAG, ++ .active_low = 1, ++ }, { ++ .name = "wzr-hp-g300nh:blue:usb", ++ .gpio = WZRHPG300NH_GPIO_LED_USB, ++ .active_low = 1, + } ++}; + -+ ar71xx_pci_nr_irqs = nr_irqs; -+ ar71xx_pci_irq_map = map; ++static struct gpio_keys_button wzrhpg300nh_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "aoss", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_AOSS, ++ .active_low = 1, ++ }, { ++ .desc = "usb", ++ .type = EV_KEY, ++ .code = BTN_2, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_USB, ++ .active_low = 1, ++ }, { ++ .desc = "qos_on", ++ .type = EV_KEY, ++ .code = BTN_3, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_QOS_ON, ++ .active_low = 0, ++ }, { ++ .desc = "qos_off", ++ .type = EV_KEY, ++ .code = BTN_4, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_QOS_OFF, ++ .active_low = 0, ++ }, { ++ .desc = "router_on", ++ .type = EV_KEY, ++ .code = BTN_5, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_ON, ++ .active_low = 0, ++ }, { ++ .desc = "router_auto", ++ .type = EV_KEY, ++ .code = BTN_6, ++ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_AUTO, ++ .active_low = 0, ++ } ++}; + -+ return ret; -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/prom.c linux-2.6.39/arch/mips/ar71xx/prom.c ---- linux-2.6.39.orig/arch/mips/ar71xx/prom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/prom.c 2011-08-24 02:41:55.737990425 +0200 -@@ -0,0 +1,189 @@ -+/* -+ * Atheros AR71xx SoC specific prom routines -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++static struct nxp_74hc153_platform_data wzrhpg300nh_74hc153_data = { ++ .gpio_base = WZRHPG300NH_GPIO_EXP_BASE, ++ .gpio_pin_s0 = WZRHPG300NH_GPIO_74HC153_S0, ++ .gpio_pin_s1 = WZRHPG300NH_GPIO_74HC153_S1, ++ .gpio_pin_1y = WZRHPG300NH_GPIO_74HC153_1Y, ++ .gpio_pin_2y = WZRHPG300NH_GPIO_74HC153_2Y, ++}; + -+#include -+#include -+#include -+#include ++static struct platform_device wzrhpg300nh_74hc153_device = { ++ .name = NXP_74HC153_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &wzrhpg300nh_74hc153_data, ++ } ++}; + -+#include -+#include -+#include ++static struct rtl8366_platform_data wzrhpg300nh_rtl8366_data = { ++ .gpio_sda = WZRHPG300NH_GPIO_RTL8366_SDA, ++ .gpio_sck = WZRHPG300NH_GPIO_RTL8366_SCK, ++}; + -+#include ++static struct platform_device wzrhpg300nh_rtl8366s_device = { ++ .name = RTL8366S_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &wzrhpg300nh_rtl8366_data, ++ } ++}; + -+static inline int is_valid_ram_addr(void *addr) ++static struct platform_device wzrhpg300nh_rtl8366rb_device = { ++ .name = RTL8366RB_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &wzrhpg300nh_rtl8366_data, ++ } ++}; ++ ++static void __init wzrhpg300nh_setup(void) +{ -+ if (((u32) addr > KSEG0) && -+ ((u32) addr < (KSEG0 + AR71XX_MEM_SIZE_MAX))) -+ return 1; ++ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); ++ u8 *mac = eeprom + WZRHPG300NH_MAC_OFFSET; ++ bool hasrtl8366rb = false; + -+ if (((u32) addr > KSEG1) && -+ ((u32) addr < (KSEG1 + AR71XX_MEM_SIZE_MAX))) -+ return 1; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); + -+ return 0; -+} -+ -+static void __init ar71xx_prom_append_cmdline(const char *name, -+ const char *value) -+{ -+ char buf[COMMAND_LINE_SIZE]; -+ -+ snprintf(buf, sizeof(buf), " %s=%s", name, value); -+ strlcat(arcs_cmdline, buf, sizeof(arcs_cmdline)); -+} -+ -+static const char * __init ar71xx_prom_find_env(char **envp, const char *name) -+{ -+ const char *ret = NULL; -+ int len; -+ char **p; -+ -+ if (!is_valid_ram_addr(envp)) -+ return NULL; -+ -+ len = strlen(name); -+ for (p = envp; is_valid_ram_addr(*p); p++) { -+ if (strncmp(name, *p, len) == 0 && (*p)[len] == '=') { -+ ret = *p + len + 1; -+ break; -+ } -+ -+ /* RedBoot env comes in pointer pairs - key, value */ -+ if (strncmp(name, *p, len) == 0 && (*p)[len] == 0) -+ if (is_valid_ram_addr(*(++p))) { -+ ret = *p; -+ break; -+ } -+ } -+ -+ return ret; -+} -+ -+static int __init ar71xx_prom_init_myloader(void) -+{ -+ struct myloader_info *mylo; -+ char mac_buf[32]; -+ char *mac; -+ -+ mylo = myloader_get_info(); -+ if (!mylo) -+ return 0; -+ -+ switch (mylo->did) { -+ case DEVID_COMPEX_WP543: -+ ar71xx_prom_append_cmdline("board", "WP543"); -+ break; -+ default: -+ printk(KERN_WARNING "prom: unknown device id: %x\n", -+ mylo->did); -+ return 0; -+ } -+ -+ mac = mylo->macs[0]; -+ snprintf(mac_buf, sizeof(mac_buf), "%02x:%02x:%02x:%02x:%02x:%02x", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -+ -+ ar71xx_prom_append_cmdline("ethaddr", mac_buf); -+ -+ return 1; -+} -+ -+#ifdef CONFIG_IMAGE_CMDLINE_HACK -+extern char __image_cmdline[]; -+ -+static int __init ar71xx_use__image_cmdline(void) -+{ -+ char *p = __image_cmdline; -+ int replace = 0; -+ -+ if (*p == '-') { -+ replace = 1; -+ p++; -+ } -+ -+ if (*p == '\0') -+ return 0; ++ if (rtl8366_smi_detect(&wzrhpg300nh_rtl8366_data) == RTL8366_TYPE_RB) ++ hasrtl8366rb = true; + -+ if (replace) { -+ strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline)); ++ if (hasrtl8366rb) { ++ ar71xx_eth0_pll_data.pll_1000 = 0x1f000000; ++ ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev; ++ ar71xx_eth1_pll_data.pll_1000 = 0x100; ++ ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev; + } else { -+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); -+ strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); ++ ar71xx_eth0_pll_data.pll_1000 = 0x1e000100; ++ ar71xx_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; ++ ar71xx_eth1_pll_data.pll_1000 = 0x1e000100; ++ ar71xx_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; + } + -+ return 1; -+} -+#else -+static inline int ar71xx_use__image_cmdline(void) { return 0; } -+#endif -+ -+static __init void ar71xx_prom_init_cmdline(int argc, char **argv) -+{ -+ int i; -+ -+ if (ar71xx_use__image_cmdline()) -+ return; -+ -+ if (!is_valid_ram_addr(argv)) -+ return; -+ -+ for (i = 0; i < argc; i++) -+ if (is_valid_ram_addr(argv[i])) { -+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); -+ strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline)); -+ } -+} -+ -+void __init prom_init(void) -+{ -+ const char *env; -+ char **envp; ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth0_data.speed = SPEED_1000; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+ printk(KERN_DEBUG "prom: fw_arg0=%08x, fw_arg1=%08x, " -+ "fw_arg2=%08x, fw_arg3=%08x\n", -+ (unsigned int)fw_arg0, (unsigned int)fw_arg1, -+ (unsigned int)fw_arg2, (unsigned int)fw_arg3); ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ar71xx_eth1_data.phy_mask = 0x10; + ++ ar71xx_add_device_eth(0); ++ ar71xx_add_device_eth(1); + -+ if (ar71xx_prom_init_myloader()) -+ return; ++ ar71xx_add_device_usb(); ++ ar9xxx_add_device_wmac(eeprom, NULL); + -+ ar71xx_prom_init_cmdline(fw_arg0, (char **)fw_arg1); ++ platform_device_register(&wzrhpg300nh_74hc153_device); ++ platform_device_register(&wzrhpg300nh_flash_device); + -+ envp = (char **)fw_arg2; -+ if (!strstr(arcs_cmdline, "ethaddr=")) { -+ env = ar71xx_prom_find_env(envp, "ethaddr"); -+ if (env) -+ ar71xx_prom_append_cmdline("ethaddr", env); -+ } ++ if (hasrtl8366rb) ++ platform_device_register(&wzrhpg300nh_rtl8366rb_device); ++ else ++ platform_device_register(&wzrhpg300nh_rtl8366s_device); + -+ if (!strstr(arcs_cmdline, "board=")) { -+ env = ar71xx_prom_find_env(envp, "board"); -+ if (env) { -+ /* Workaround for buggy bootloaders */ -+ if (strcmp(env, "RouterStation") == 0 || -+ strcmp(env, "Ubiquiti AR71xx-based board") == 0) -+ env = "UBNT-RS"; ++ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh_leds_gpio), ++ wzrhpg300nh_leds_gpio); + -+ if (strcmp(env, "RouterStation PRO") == 0) -+ env = "UBNT-RSPRO"; ++ ar71xx_register_gpio_keys_polled(-1, WZRHPG300NH_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(wzrhpg300nh_gpio_keys), ++ wzrhpg300nh_gpio_keys); + -+ ar71xx_prom_append_cmdline("board", env); -+ } -+ } +} + -+void __init prom_free_prom_memory(void) -+{ -+ /* We do not have to prom memory to free */ -+} -diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/setup.c linux-2.6.39/arch/mips/ar71xx/setup.c ---- linux-2.6.39.orig/arch/mips/ar71xx/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/ar71xx/setup.c 2011-08-24 02:41:55.737990425 +0200 -@@ -0,0 +1,446 @@ ++MIPS_MACHINE(AR71XX_MACH_WZR_HP_G300NH, "WZR-HP-G300NH", ++ "Buffalo WZR-HP-G300NH", wzrhpg300nh_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/mach-zcn-1523h.c linux-2.6.39/arch/mips/ar71xx/mach-zcn-1523h.c +--- linux-2.6.39.orig/arch/mips/ar71xx/mach-zcn-1523h.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/mach-zcn-1523h.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,214 @@ +/* -+ * Atheros AR71xx SoC specific setup -+ * -+ * Copyright (C) 2010-2011 Jaiganesh Narayanan -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * Zcomax ZCN-1523H-2-8/5-16 board support + * -+ * Parts of this file are based on Atheros 2.6.15 BSP -+ * Parts of this file are based on Atheros 2.6.31 BSP ++ * Copyright (C) 2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#include -+#include -+#include -+ -+#include -+#include /* for mips_hpt_frequency */ -+#include /* for _machine_{restart,halt} */ -+#include ++#include ++#include + +#include + +#include "machtype.h" +#include "devices.h" ++#include "dev-m25p80.h" ++#include "dev-ap91-pci.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" + -+#define AR71XX_SYS_TYPE_LEN 64 -+ -+u32 ar71xx_cpu_freq; -+EXPORT_SYMBOL_GPL(ar71xx_cpu_freq); -+ -+u32 ar71xx_ahb_freq; -+EXPORT_SYMBOL_GPL(ar71xx_ahb_freq); -+ -+u32 ar71xx_ddr_freq; -+EXPORT_SYMBOL_GPL(ar71xx_ddr_freq); -+ -+u32 ar71xx_ref_freq; -+EXPORT_SYMBOL_GPL(ar71xx_ref_freq); -+ -+enum ar71xx_soc_type ar71xx_soc; -+EXPORT_SYMBOL_GPL(ar71xx_soc); -+ -+u32 ar71xx_soc_rev; -+EXPORT_SYMBOL_GPL(ar71xx_soc_rev); -+ -+static char ar71xx_sys_type[AR71XX_SYS_TYPE_LEN]; ++#define ZCN_1523H_GPIO_BTN_RESET 0 ++#define ZCN_1523H_GPIO_LED_INIT 11 ++#define ZCN_1523H_GPIO_LED_LAN1 17 + -+static void ar71xx_restart(char *command) -+{ -+ ar71xx_device_stop(RESET_MODULE_FULL_CHIP); -+ for (;;) -+ if (cpu_wait) -+ cpu_wait(); -+} ++#define ZCN_1523H_2_GPIO_LED_WEAK 13 ++#define ZCN_1523H_2_GPIO_LED_MEDIUM 14 ++#define ZCN_1523H_2_GPIO_LED_STRONG 15 + -+static void ar71xx_halt(void) -+{ -+ while (1) -+ cpu_wait(); -+} ++#define ZCN_1523H_5_GPIO_LED_UNKNOWN 1 ++#define ZCN_1523H_5_GPIO_LED_LAN2 13 ++#define ZCN_1523H_5_GPIO_LED_WEAK 14 ++#define ZCN_1523H_5_GPIO_LED_MEDIUM 15 ++#define ZCN_1523H_5_GPIO_LED_STRONG 16 + -+static void __init ar71xx_detect_mem_size(void) -+{ -+ unsigned long size; ++#define ZCN_1523H_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define ZCN_1523H_KEYS_DEBOUNCE_INTERVAL (3 * ZCN_1523H_KEYS_POLL_INTERVAL) + -+ for (size = AR71XX_MEM_SIZE_MIN; size < AR71XX_MEM_SIZE_MAX; -+ size <<= 1) { -+ if (!memcmp(ar71xx_detect_mem_size, -+ ar71xx_detect_mem_size + size, 1024)) -+ break; ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition zcn_1523h_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "rootfs", ++ .offset = 0x050000, ++ .size = 0x610000, ++ }, { ++ .name = "kernel", ++ .offset = 0x660000, ++ .size = 0x170000, ++ }, { ++ .name = "configure", ++ .offset = 0x7d0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "mfg", ++ .offset = 0x7e0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "eeprom", ++ .offset = 0x7f0000, ++ .size = 0x010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "firmware", ++ .offset = 0x050000, ++ .size = 0x780000, + } ++}; ++#endif /* CONFIG_MTD_PARTITIONS */ + -+ add_memory_region(0, size, BOOT_MEM_RAM); -+} -+ -+static void __init ar71xx_detect_sys_type(void) -+{ -+ char *chip = "????"; -+ u32 id; -+ u32 major; -+ u32 minor; -+ u32 rev = 0; -+ -+ id = ar71xx_reset_rr(AR71XX_RESET_REG_REV_ID); -+ major = id & REV_ID_MAJOR_MASK; -+ -+ switch (major) { -+ case REV_ID_MAJOR_AR71XX: -+ minor = id & AR71XX_REV_ID_MINOR_MASK; -+ rev = id >> AR71XX_REV_ID_REVISION_SHIFT; -+ rev &= AR71XX_REV_ID_REVISION_MASK; -+ switch (minor) { -+ case AR71XX_REV_ID_MINOR_AR7130: -+ ar71xx_soc = AR71XX_SOC_AR7130; -+ chip = "7130"; -+ break; ++static struct flash_platform_data zcn_1523h_flash_data = { ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = zcn_1523h_partitions, ++ .nr_parts = ARRAY_SIZE(zcn_1523h_partitions), ++#endif ++}; + -+ case AR71XX_REV_ID_MINOR_AR7141: -+ ar71xx_soc = AR71XX_SOC_AR7141; -+ chip = "7141"; -+ break; ++static struct gpio_keys_button zcn_1523h_gpio_keys[] __initdata = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = ZCN_1523H_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = ZCN_1523H_GPIO_BTN_RESET, ++ .active_low = 1, ++ } ++}; + -+ case AR71XX_REV_ID_MINOR_AR7161: -+ ar71xx_soc = AR71XX_SOC_AR7161; -+ chip = "7161"; -+ break; -+ } -+ break; ++static struct gpio_led zcn_1523h_leds_gpio[] __initdata = { ++ { ++ .name = "zcn-1523h:amber:init", ++ .gpio = ZCN_1523H_GPIO_LED_INIT, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:green:lan1", ++ .gpio = ZCN_1523H_GPIO_LED_LAN1, ++ .active_low = 1, ++ } ++}; + -+ case REV_ID_MAJOR_AR7240: -+ ar71xx_soc = AR71XX_SOC_AR7240; -+ chip = "7240"; -+ rev = id & AR724X_REV_ID_REVISION_MASK; -+ break; ++static struct gpio_led zcn_1523h_2_leds_gpio[] __initdata = { ++ { ++ .name = "zcn-1523h:red:weak", ++ .gpio = ZCN_1523H_2_GPIO_LED_WEAK, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:amber:medium", ++ .gpio = ZCN_1523H_2_GPIO_LED_MEDIUM, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:green:strong", ++ .gpio = ZCN_1523H_2_GPIO_LED_STRONG, ++ .active_low = 1, ++ } ++}; + -+ case REV_ID_MAJOR_AR7241: -+ ar71xx_soc = AR71XX_SOC_AR7241; -+ chip = "7241"; -+ rev = id & AR724X_REV_ID_REVISION_MASK; -+ break; ++static struct gpio_led zcn_1523h_5_leds_gpio[] __initdata = { ++ { ++ .name = "zcn-1523h:red:weak", ++ .gpio = ZCN_1523H_5_GPIO_LED_WEAK, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:amber:medium", ++ .gpio = ZCN_1523H_5_GPIO_LED_MEDIUM, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:green:strong", ++ .gpio = ZCN_1523H_5_GPIO_LED_STRONG, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:green:lan2", ++ .gpio = ZCN_1523H_5_GPIO_LED_LAN2, ++ .active_low = 1, ++ }, { ++ .name = "zcn-1523h:amber:unknown", ++ .gpio = ZCN_1523H_5_GPIO_LED_UNKNOWN, ++ } ++}; + -+ case REV_ID_MAJOR_AR7242: -+ ar71xx_soc = AR71XX_SOC_AR7242; -+ chip = "7242"; -+ rev = id & AR724X_REV_ID_REVISION_MASK; -+ break; ++static void __init zcn_1523h_generic_setup(void) ++{ ++ u8 *mac = (u8 *) KSEG1ADDR(0x1f7e0004); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + -+ case REV_ID_MAJOR_AR913X: -+ minor = id & AR91XX_REV_ID_MINOR_MASK; -+ rev = id >> AR91XX_REV_ID_REVISION_SHIFT; -+ rev &= AR91XX_REV_ID_REVISION_MASK; -+ switch (minor) { -+ case AR91XX_REV_ID_MINOR_AR9130: -+ ar71xx_soc = AR71XX_SOC_AR9130; -+ chip = "9130"; -+ break; ++ ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + -+ case AR91XX_REV_ID_MINOR_AR9132: -+ ar71xx_soc = AR71XX_SOC_AR9132; -+ chip = "9132"; -+ break; -+ } -+ break; ++ ar71xx_add_device_m25p80(&zcn_1523h_flash_data); + -+ case REV_ID_MAJOR_AR9330: -+ ar71xx_soc = AR71XX_SOC_AR9330; -+ chip = "9330"; -+ rev = id & AR933X_REV_ID_REVISION_MASK; -+ break; ++ ar71xx_add_device_leds_gpio(0, ARRAY_SIZE(zcn_1523h_leds_gpio), ++ zcn_1523h_leds_gpio); + -+ case REV_ID_MAJOR_AR9331: -+ ar71xx_soc = AR71XX_SOC_AR9331; -+ chip = "9331"; -+ rev = id & AR933X_REV_ID_REVISION_MASK; -+ break; ++ ar71xx_register_gpio_keys_polled(-1, ZCN_1523H_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(zcn_1523h_gpio_keys), ++ zcn_1523h_gpio_keys); + -+ case REV_ID_MAJOR_AR9342: -+ ar71xx_soc = AR71XX_SOC_AR9342; -+ chip = "9342"; -+ rev = id & AR934X_REV_ID_REVISION_MASK; -+ break; ++ ap91_pci_init(ee, mac); + -+ case REV_ID_MAJOR_AR9344: -+ ar71xx_soc = AR71XX_SOC_AR9344; -+ chip = "9344"; -+ rev = id & AR934X_REV_ID_REVISION_MASK; -+ break; ++ ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac, 0); ++ ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac, 1); + -+ default: -+ panic("ar71xx: unknown chip id:0x%08x\n", id); -+ } ++ /* LAN1 port */ ++ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth0_data.speed = SPEED_100; ++ ar71xx_eth0_data.duplex = DUPLEX_FULL; + -+ ar71xx_soc_rev = rev; ++ /* LAN2 port */ ++ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ar71xx_eth1_data.speed = SPEED_1000; ++ ar71xx_eth1_data.duplex = DUPLEX_FULL; + -+ sprintf(ar71xx_sys_type, "Atheros AR%s rev %u", chip, rev); -+ pr_info("SoC: %s\n", ar71xx_sys_type); ++ ar71xx_add_device_mdio(0x0); ++ ar71xx_add_device_eth(0); +} + -+static void __init ar934x_detect_sys_frequency(void) ++static void __init zcn_1523h_2_setup(void) +{ -+ u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; ++ zcn_1523h_generic_setup(); ++ ap91_pci_setup_wmac_gpio(BIT(9), 0); + -+ if (ar71xx_reset_rr(AR934X_RESET_REG_BOOTSTRAP) & AR934X_REF_CLK_40) -+ ar71xx_ref_freq = 40 * 1000 * 1000; -+ else -+ ar71xx_ref_freq = 25 * 1000 * 1000; ++ ar71xx_add_device_leds_gpio(1, ARRAY_SIZE(zcn_1523h_2_leds_gpio), ++ zcn_1523h_2_leds_gpio); ++} + -+ clk_ctrl = ar71xx_pll_rr(AR934X_PLL_REG_DDR_CTRL_CLOCK); ++MIPS_MACHINE(AR71XX_MACH_ZCN_1523H_2, "ZCN-1523H-2", "Zcomax ZCN-1523H-2", ++ zcn_1523h_2_setup); + -+ pll = ar71xx_pll_rr(AR934X_PLL_REG_CPU_CONFIG); -+ out_div = AR934X_CPU_PLL_CFG_OUTDIV_GET(pll); -+ ref_div = AR934X_CPU_PLL_CFG_REFDIV_GET(pll); -+ nint = AR934X_CPU_PLL_CFG_NINT_GET(pll); -+ frac = AR934X_CPU_PLL_CFG_NFRAC_GET(pll); -+ postdiv = AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_GET(clk_ctrl); -+ ar71xx_cpu_freq = ((nint * ar71xx_ref_freq / ref_div) >> out_div) / -+ (postdiv + 1); -+ -+ out_div = AR934X_DDR_PLL_CFG_OUTDIV_GET(pll); -+ ref_div = AR934X_DDR_PLL_CFG_REFDIV_GET(pll); -+ nint = AR934X_DDR_PLL_CFG_NINT_GET(pll); -+ frac = AR934X_DDR_PLL_CFG_NFRAC_GET(pll); -+ postdiv = AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_GET(clk_ctrl); -+ ar71xx_ddr_freq = ((nint * ar71xx_ref_freq / ref_div) >> out_div) / -+ (postdiv + 1); -+ -+ postdiv = AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_GET(clk_ctrl); -+ -+ if (AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_GET(clk_ctrl)) { -+ ar71xx_ahb_freq = ar71xx_ddr_freq / (postdiv + 1); -+ } else { -+ ar71xx_ahb_freq = ar71xx_cpu_freq / (postdiv + 1); -+ } ++static void __init zcn_1523h_5_setup(void) ++{ ++ zcn_1523h_generic_setup(); ++ ap91_pci_setup_wmac_gpio(BIT(8), 0); + ++ ar71xx_add_device_leds_gpio(1, ARRAY_SIZE(zcn_1523h_5_leds_gpio), ++ zcn_1523h_5_leds_gpio); ++ ar71xx_add_device_eth(1); +} + -+static void __init ar91xx_detect_sys_frequency(void) -+{ -+ u32 pll; -+ u32 freq; -+ u32 div; ++MIPS_MACHINE(AR71XX_MACH_ZCN_1523H_5, "ZCN-1523H-5", "Zcomax ZCN-1523H-5", ++ zcn_1523h_5_setup); +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/machtype.h linux-2.6.39/arch/mips/ar71xx/machtype.h +--- linux-2.6.39.orig/arch/mips/ar71xx/machtype.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/machtype.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,75 @@ ++/* ++ * Atheros AR71xx machine type definitions ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ ar71xx_ref_freq = 5 * 1000 * 1000; ++#ifndef _AR71XX_MACHTYPE_H ++#define _AR71XX_MACHTYPE_H + -+ pll = ar71xx_pll_rr(AR91XX_PLL_REG_CPU_CONFIG); ++#include + -+ div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK); -+ freq = div * ar71xx_ref_freq; ++enum ar71xx_mach_type { ++ AR71XX_MACH_GENERIC = 0, ++ AR71XX_MACH_AP121, /* Atheros AP121 */ ++ AR71XX_MACH_AP121_MINI, /* Atheros AP121-MINI */ ++ AR71XX_MACH_AP81, /* Atheros AP81 */ ++ AR71XX_MACH_AP83, /* Atheros AP83 */ ++ AR71XX_MACH_AW_NR580, /* AzureWave AW-NR580 */ ++ AR71XX_MACH_DIR_600_A1, /* D-Link DIR-600 rev. A1 */ ++ AR71XX_MACH_DIR_615_C1, /* D-Link DIR-615 rev. C1 */ ++ AR71XX_MACH_DIR_825_B1, /* D-Link DIR-825 rev. B1 */ ++ AR71XX_MACH_JA76PF, /* jjPlus JA76PF */ ++ AR71XX_MACH_JWAP003, /* jjPlus JWAP003 */ ++ AR71XX_MACH_RB_411, /* MikroTik RouterBOARD 411/411A/411AH */ ++ AR71XX_MACH_RB_411U, /* MikroTik RouterBOARD 411U */ ++ AR71XX_MACH_RB_433, /* MikroTik RouterBOARD 433/433AH */ ++ AR71XX_MACH_RB_433U, /* MikroTik RouterBOARD 433UAH */ ++ AR71XX_MACH_RB_450, /* MikroTik RouterBOARD 450 */ ++ AR71XX_MACH_RB_450G, /* MikroTik RouterBOARD 450G */ ++ AR71XX_MACH_RB_493, /* Mikrotik RouterBOARD 493/493AH */ ++ AR71XX_MACH_RB_750, /* MikroTik RouterBOARD 750 */ ++ AR71XX_MACH_PB42, /* Atheros PB42 */ ++ AR71XX_MACH_PB44, /* Atheros PB44 */ ++ AR71XX_MACH_PB92, /* Atheros PB92 */ ++ AR71XX_MACH_MZK_W04NU, /* Planex MZK-W04NU */ ++ AR71XX_MACH_MZK_W300NH, /* Planex MZK-W300NH */ ++ AR71XX_MACH_NBG460N, /* Zyxel NBG460N/550N/550NH */ ++ AR71XX_MACH_TEW_632BRP, /* TRENDnet TEW-632BRP */ ++ AR71XX_MACH_TL_MR3220, /* TP-LINK TL-MR3220 */ ++ AR71XX_MACH_TL_MR3420, /* TP-LINK TL-MR3420 */ ++ AR71XX_MACH_TL_WA901ND, /* TP-LINK TL-WA901ND */ ++ AR71XX_MACH_TL_WA901ND_V2, /* TP-LINK TL-WA901ND v2 */ ++ AR71XX_MACH_TL_WR741ND, /* TP-LINK TL-WR741ND */ ++ AR71XX_MACH_TL_WR841N_V1, /* TP-LINK TL-WR841N v1 */ ++ AR71XX_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ ++ AR71XX_MACH_TL_WR1043ND, /* TP-LINK TL-WR1041ND */ ++ AR71XX_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */ ++ AR71XX_MACH_UBNT_LSX, /* Ubiquiti LSX */ ++ AR71XX_MACH_UBNT_RS, /* Ubiquiti RouterStation */ ++ AR71XX_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */ ++ AR71XX_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ ++ AR71XX_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */ ++ AR71XX_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */ ++ AR71XX_MACH_WNDR3700, /* NETGEAR WNDR3700 */ ++ AR71XX_MACH_WNDR3700V2, /* NETGEAR WNDR3700v2 */ ++ AR71XX_MACH_WNR2000, /* NETGEAR WNR2000 */ ++ AR71XX_MACH_WP543, /* Compex WP543 */ ++ AR71XX_MACH_WRT160NL, /* Linksys WRT160NL */ ++ AR71XX_MACH_WRT400N, /* Linksys WRT400N */ ++ AR71XX_MACH_WZR_HP_AG300H, /* Buffalo WZR-HP-AG300H */ ++ AR71XX_MACH_WZR_HP_G300NH, /* Buffalo WZR-HP-G300NH */ ++ AR71XX_MACH_EAP7660D, /* Senao EAP7660D */ ++ AR71XX_MACH_ZCN_1523H_2, /* Zcomax ZCN-1523H-2-xx */ ++ AR71XX_MACH_ZCN_1523H_5, /* Zcomax ZCN-1523H-5-xx */ ++ AR71XX_MACH_AP96, /* Atheros AP96 */ ++ AR71XX_MACH_UBNT_UNIFI, /* Unifi */ ++ AR71XX_MACH_DB120, /* Atheros DB120 (AR934x based) */ ++}; + -+ ar71xx_cpu_freq = freq; ++#endif /* _AR71XX_MACHTYPE_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.c linux-2.6.39/arch/mips/ar71xx/nvram.c +--- linux-2.6.39.orig/arch/mips/ar71xx/nvram.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/nvram.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,75 @@ ++/* ++ * Atheros AR71xx minimal nvram support ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ div = ((pll >> AR91XX_DDR_DIV_SHIFT) & AR91XX_DDR_DIV_MASK) + 1; -+ ar71xx_ddr_freq = freq / div; ++#include ++#include ++#include ++#include ++#include + -+ div = (((pll >> AR91XX_AHB_DIV_SHIFT) & AR91XX_AHB_DIV_MASK) + 1) * 2; -+ ar71xx_ahb_freq = ar71xx_cpu_freq / div; -+} ++#include "nvram.h" + -+static void __init ar71xx_detect_sys_frequency(void) ++char *nvram_find_var(const char *name, const char *buf, unsigned buf_len) +{ -+ u32 pll; -+ u32 freq; -+ u32 div; -+ -+ ar71xx_ref_freq = 40 * 1000 * 1000; ++ unsigned len = strlen(name); ++ char *cur, *last; + -+ pll = ar71xx_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); ++ if (buf_len == 0 || len == 0) ++ return NULL; + -+ div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; -+ freq = div * ar71xx_ref_freq; ++ if (buf_len < len) ++ return NULL; + -+ div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; -+ ar71xx_cpu_freq = freq / div; ++ if (len == 1) ++ return memchr(buf, (int) *name, buf_len); + -+ div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; -+ ar71xx_ddr_freq = freq / div; ++ last = (char *) buf + buf_len - len; ++ for (cur = (char *) buf; cur <= last; cur++) ++ if (cur[0] == name[0] && memcmp(cur, name, len) == 0) ++ return cur + len; + -+ div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; -+ ar71xx_ahb_freq = ar71xx_cpu_freq / div; ++ return NULL; +} + -+static void __init ar724x_detect_sys_frequency(void) ++int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, ++ const char *name, char *mac) +{ -+ u32 pll; -+ u32 freq; -+ u32 div; ++ char *buf; ++ char *mac_str; ++ int ret; ++ int t; + -+ ar71xx_ref_freq = 5 * 1000 * 1000; ++ buf = vmalloc(nvram_len); ++ if (!buf) ++ return -ENOMEM; + -+ pll = ar71xx_pll_rr(AR724X_PLL_REG_CPU_CONFIG); ++ memcpy(buf, nvram, nvram_len); ++ buf[nvram_len - 1] = '\0'; + -+ div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); -+ freq = div * ar71xx_ref_freq; ++ mac_str = nvram_find_var(name, buf, nvram_len); ++ if (!mac_str) { ++ ret = -EINVAL; ++ goto free; ++ } + -+ div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); -+ freq *= div; ++ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", ++ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); + -+ ar71xx_cpu_freq = freq; ++ if (t != 6) { ++ ret = -EINVAL; ++ goto free; ++ } + -+ div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; -+ ar71xx_ddr_freq = freq / div; ++ ret = 0; + -+ div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; -+ ar71xx_ahb_freq = ar71xx_cpu_freq / div; ++free: ++ vfree(buf); ++ return ret; +} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/nvram.h linux-2.6.39/arch/mips/ar71xx/nvram.h +--- linux-2.6.39.orig/arch/mips/ar71xx/nvram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/nvram.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,19 @@ ++/* ++ * Atheros AR71xx minimal nvram support ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+static void __init ar933x_detect_sys_frequency(void) -+{ -+ u32 clock_ctrl; -+ u32 cpu_config; -+ u32 freq; -+ u32 t; ++#ifndef _AR71XX_NVRAM_H ++#define _AR71XX_NVRAM_H + -+ t = ar71xx_reset_rr(AR933X_RESET_REG_BOOTSTRAP); -+ if (t & AR933X_BOOTSTRAP_REF_CLK_40) -+ ar71xx_ref_freq = (40 * 1000 * 1000); -+ else -+ ar71xx_ref_freq = (25 * 1000 * 1000); ++char *nvram_find_var(const char *name, const char *buf, ++ unsigned buf_len) __init; ++int nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, ++ const char *name, char *mac) __init; + -+ clock_ctrl = ar71xx_pll_rr(AR933X_PLL_CLOCK_CTRL_REG); -+ if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { -+ ar71xx_cpu_freq = ar71xx_ref_freq; -+ ar71xx_ahb_freq = ar71xx_ref_freq; -+ ar71xx_ddr_freq = ar71xx_ref_freq; -+ } else { -+ cpu_config = ar71xx_pll_rr(AR933X_PLL_CPU_CONFIG_REG); ++#endif /* _AR71XX_NVRAM_H */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.c linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.c +--- linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,123 @@ ++/* ++ * Atheros AP94 reference board PCI initialization ++ * ++ * Copyright (C) 2009-2010 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & -+ AR933X_PLL_CPU_CONFIG_REFDIV_MASK; -+ freq = ar71xx_ref_freq / t; ++#include ++#include + -+ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & -+ AR933X_PLL_CPU_CONFIG_NINT_MASK; -+ freq *= t; ++#include ++#include + -+ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & -+ AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; -+ if (t == 0) -+ t = 1; ++struct ath9k_fixup { ++ u16 *cal_data; ++ unsigned slot; ++}; + -+ freq >>= t; ++static int ath9k_num_fixups; ++static struct ath9k_fixup ath9k_fixups[2]; + -+ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & -+ AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; -+ ar71xx_cpu_freq = freq / t; ++static void ath9k_pci_fixup(struct pci_dev *dev) ++{ ++ void __iomem *mem; ++ u16 *cal_data = NULL; ++ u16 cmd; ++ u32 bar0; ++ u32 val; ++ unsigned i; + -+ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & -+ AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; -+ ar71xx_ddr_freq = freq / t; ++ for (i = 0; i < ath9k_num_fixups; i++) { ++ if (ath9k_fixups[i].cal_data == NULL) ++ continue; + -+ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & -+ AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; -+ ar71xx_ahb_freq = freq / t; ++ if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn)) ++ continue; ++ ++ cal_data = ath9k_fixups[i].cal_data; ++ break; + } -+} + -+static void __init detect_sys_frequency(void) -+{ ++ if (cal_data == NULL) ++ return; ++ ++ if (*cal_data != 0xa55a) { ++ pr_err("pci %s: invalid calibration data\n", pci_name(dev)); ++ return; ++ } ++ ++ pr_info("pci %s: fixup device configuration\n", pci_name(dev)); ++ ++ mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000); ++ if (!mem) { ++ pr_err("pci %s: ioremap error\n", pci_name(dev)); ++ return; ++ } ++ ++ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); ++ + switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: + case AR71XX_SOC_AR7161: -+ ar71xx_detect_sys_frequency(); ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, ++ AR71XX_PCI_MEM_BASE); + break; -+ + case AR71XX_SOC_AR7240: -+ case AR71XX_SOC_AR7241: -+ case AR71XX_SOC_AR7242: -+ ar724x_detect_sys_frequency(); -+ break; -+ -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ ar91xx_detect_sys_frequency(); ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff); + break; + -+ case AR71XX_SOC_AR9330: -+ case AR71XX_SOC_AR9331: -+ ar933x_detect_sys_frequency(); ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff); + break; + -+ case AR71XX_SOC_AR9341: -+ case AR71XX_SOC_AR9342: -+ case AR71XX_SOC_AR9344: -+ ar934x_detect_sys_frequency(); -+ break; + default: + BUG(); + } -+} + -+const char *get_system_type(void) -+{ -+ return ar71xx_sys_type; ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ ++ /* set pointer to first reg address */ ++ cal_data += 3; ++ while (*cal_data != 0xffff) { ++ u32 reg; ++ reg = *cal_data++; ++ val = *cal_data++; ++ val |= (*cal_data++) << 16; ++ ++ __raw_writel(val, mem + reg); ++ udelay(100); ++ } ++ ++ pci_read_config_dword(dev, PCI_VENDOR_ID, &val); ++ dev->vendor = val & 0xffff; ++ dev->device = (val >> 16) & 0xffff; ++ ++ pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); ++ dev->revision = val & 0xff; ++ dev->class = val >> 8; /* upper 3 bytes */ ++ ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); ++ ++ iounmap(mem); +} ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup); + -+unsigned int __cpuinit get_c0_compare_irq(void) ++void __init pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) +{ -+ return CP0_LEGACY_COMPARE_IRQ; ++ if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups)) ++ return; ++ ++ ath9k_fixups[ath9k_num_fixups].slot = slot; ++ ath9k_fixups[ath9k_num_fixups].cal_data = cal_data; ++ ath9k_num_fixups++; +} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.h linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.h +--- linux-2.6.39.orig/arch/mips/ar71xx/pci-ath9k-fixup.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/pci-ath9k-fixup.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,6 @@ ++#ifndef _PCI_ATH9K_FIXUP ++#define _PCI_ATH9K_FIXUP + -+void __init plat_mem_setup(void) -+{ -+ set_io_port_base(KSEG1); ++void pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) __init; + -+ ar71xx_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, -+ AR71XX_DDR_CTRL_SIZE); ++#endif /* _PCI_ATH9K_FIXUP */ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/pci.c linux-2.6.39/arch/mips/ar71xx/pci.c +--- linux-2.6.39.orig/arch/mips/ar71xx/pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/pci.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,97 @@ ++/* ++ * Atheros AR71xx PCI setup code ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ ar71xx_pll_base = ioremap_nocache(AR71XX_PLL_BASE, -+ AR71XX_PLL_SIZE); ++#include + -+ ar71xx_reset_base = ioremap_nocache(AR71XX_RESET_BASE, -+ AR71XX_RESET_SIZE); ++#include + -+ ar71xx_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); ++#include ++#include + -+ ar71xx_usb_ctrl_base = ioremap_nocache(AR71XX_USB_CTRL_BASE, -+ AR71XX_USB_CTRL_SIZE); ++unsigned ar71xx_pci_nr_irqs __initdata; ++struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata; + -+ ar71xx_detect_mem_size(); -+ ar71xx_detect_sys_type(); -+ detect_sys_frequency(); ++int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev); + -+ pr_info("Clocks: CPU:%u.%03uMHz, DDR:%u.%03uMHz, AHB:%u.%03uMHz, " -+ "Ref:%u.%03uMHz", -+ ar71xx_cpu_freq / 1000000, (ar71xx_cpu_freq / 1000) % 1000, -+ ar71xx_ddr_freq / 1000000, (ar71xx_ddr_freq / 1000) % 1000, -+ ar71xx_ahb_freq / 1000000, (ar71xx_ahb_freq / 1000) % 1000, -+ ar71xx_ref_freq / 1000000, (ar71xx_ref_freq / 1000) % 1000); ++static int ar71xx_be_handler(struct pt_regs *regs, int is_fixup) ++{ ++ int err = 0; + -+ _machine_restart = ar71xx_restart; -+ _machine_halt = ar71xx_halt; -+ pm_power_off = ar71xx_halt; ++ err = ar71xx_pci_be_handler(is_fixup); ++ ++ return (is_fixup && !err) ? MIPS_BE_FIXUP : MIPS_BE_FATAL; +} + -+void __init plat_time_init(void) ++int pcibios_plat_dev_init(struct pci_dev *dev) +{ -+ mips_hpt_frequency = ar71xx_cpu_freq / 2; -+} ++ if (ar71xx_pci_plat_dev_init) ++ return ar71xx_pci_plat_dev_init(dev); + -+__setup("board=", mips_machtype_setup); ++ return 0; ++} + -+static int __init ar71xx_machine_setup(void) ++int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) +{ -+ ar71xx_gpio_init(); ++ int ret = 0; + -+ ar71xx_add_device_uart(); -+ ar71xx_add_device_wdt(); ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ ret = ar71xx_pcibios_map_irq(dev, slot, pin); ++ break; + -+ mips_machine_setup(); -+ return 0; -+} ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ret = ar724x_pcibios_map_irq(dev, slot, pin); ++ break; + -+arch_initcall(ar71xx_machine_setup); ++ default: ++ break; ++ } + -+static void __init ar71xx_generic_init(void) -+{ -+ /* Nothing to do */ ++ return ret; +} + -+MIPS_MACHINE(AR71XX_MACH_GENERIC, "Generic", "Generic AR71xx board", -+ ar71xx_generic_init); -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/checksum.h linux-2.6.39/arch/mips/include/asm/checksum.h ---- linux-2.6.39.orig/arch/mips/include/asm/checksum.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/include/asm/checksum.h 2011-08-24 05:53:21.109231561 +0200 -@@ -12,6 +12,7 @@ - #define _ASM_CHECKSUM_H - - #include -+#include - - #include - -@@ -104,26 +105,30 @@ - const unsigned int *stop = word + ihl; - unsigned int csum; - int carry; -+ unsigned int w; - -- csum = word[0]; -- csum += word[1]; -- carry = (csum < word[1]); -+ csum = __get_unaligned_cpu32(word++); ++int __init ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) ++{ ++ int ret = 0; + -+ w = __get_unaligned_cpu32(word++); -+ csum += w; -+ carry = (csum < w); - csum += carry; - -- csum += word[2]; -- carry = (csum < word[2]); -+ w = __get_unaligned_cpu32(word++); -+ csum += w; -+ carry = (csum < w); - csum += carry; - -- csum += word[3]; -- carry = (csum < word[3]); -+ w = __get_unaligned_cpu32(word++); -+ csum += w; -+ carry = (csum < w); - csum += carry; - -- word += 4; - do { -- csum += *word; -- carry = (csum < *word); -+ w = __get_unaligned_cpu32(word++); -+ csum += w; -+ carry = (csum < w); - csum += carry; -- word++; - } while (word != stop); - - return csum_fold(csum); -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/fw/myloader/myloader.h linux-2.6.39/arch/mips/include/asm/fw/myloader/myloader.h ---- linux-2.6.39.orig/arch/mips/include/asm/fw/myloader/myloader.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/fw/myloader/myloader.h 2011-04-27 12:19:21.887662064 +0200 -@@ -0,0 +1,34 @@ -+/* -+ * Compex's MyLoader specific definitions -+ * -+ * Copyright (C) 2006-2008 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ board_be_handler = ar71xx_be_handler; ++ ret = ar71xx_pcibios_init(); ++ break; + -+#ifndef _ASM_MIPS_FW_MYLOADER_H -+#define _ASM_MIPS_FW_MYLOADER_H ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ret = ar724x_pcibios_init(); ++ break; + -+#include ++ default: ++ return 0; ++ } + -+struct myloader_info { -+ uint32_t vid; -+ uint32_t did; -+ uint32_t svid; -+ uint32_t sdid; -+ uint8_t macs[MYLO_ETHADDR_COUNT][6]; -+}; ++ ar71xx_pci_nr_irqs = nr_irqs; ++ ar71xx_pci_irq_map = map; + -+#ifdef CONFIG_MYLOADER -+extern struct myloader_info *myloader_get_info(void) __init; -+#else -+static inline struct myloader_info *myloader_get_info(void) -+{ -+ return NULL; ++ return ret; +} -+#endif /* CONFIG_MYLOADER */ -+ -+#endif /* _ASM_MIPS_FW_MYLOADER_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h 2011-08-06 09:32:36.758018150 +0200 -@@ -0,0 +1,769 @@ +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/prom.c linux-2.6.39/arch/mips/ar71xx/prom.c +--- linux-2.6.39.orig/arch/mips/ar71xx/prom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/prom.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,189 @@ +/* -+ * Atheros AR71xx SoC specific definitions ++ * Atheros AR71xx SoC specific prom routines + * -+ * Copyright (C) 2010-2011 Jaiganesh Narayanan -+ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * -+ * Parts of this file are based on Atheros 2.6.15 BSP -+ * Parts of this file are based on Atheros 2.6.31 BSP -+ * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#ifndef __ASM_MACH_AR71XX_H -+#define __ASM_MACH_AR71XX_H -+ -+#include ++#include +#include +#include -+#include ++#include + -+#ifndef __ASSEMBLER__ ++#include ++#include ++#include + -+#define AR71XX_PCI_MEM_BASE 0x10000000 -+#define AR71XX_PCI_MEM_SIZE 0x08000000 -+#define AR71XX_APB_BASE 0x18000000 -+#define AR71XX_GE0_BASE 0x19000000 -+#define AR71XX_GE0_SIZE 0x01000000 -+#define AR71XX_GE1_BASE 0x1a000000 -+#define AR71XX_GE1_SIZE 0x01000000 -+#define AR71XX_EHCI_BASE 0x1b000000 -+#define AR71XX_EHCI_SIZE 0x01000000 -+#define AR71XX_OHCI_BASE 0x1c000000 -+#define AR71XX_OHCI_SIZE 0x01000000 -+#define AR7240_OHCI_BASE 0x1b000000 -+#define AR7240_OHCI_SIZE 0x01000000 -+#define AR71XX_SPI_BASE 0x1f000000 -+#define AR71XX_SPI_SIZE 0x01000000 ++#include + -+#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000) -+#define AR71XX_DDR_CTRL_SIZE 0x10000 -+#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000) -+#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000) -+#define AR71XX_UART_SIZE 0x10000 -+#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) -+#define AR71XX_USB_CTRL_SIZE 0x10000 -+#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000) -+#define AR71XX_GPIO_SIZE 0x10000 -+#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000) -+#define AR71XX_PLL_SIZE 0x10000 -+#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) -+#define AR71XX_RESET_SIZE 0x10000 -+#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000) -+#define AR71XX_MII_SIZE 0x10000 -+#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000) -+#define AR71XX_SLIC_SIZE 0x10000 -+#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000) -+#define AR71XX_DMA_SIZE 0x10000 -+#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000) -+#define AR71XX_STEREO_SIZE 0x10000 ++static inline int is_valid_ram_addr(void *addr) ++{ ++ if (((u32) addr > KSEG0) && ++ ((u32) addr < (KSEG0 + AR71XX_MEM_SIZE_MAX))) ++ return 1; + -+#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000) -+#define AR724X_PCI_CRP_SIZE 0x100 ++ if (((u32) addr > KSEG1) && ++ ((u32) addr < (KSEG1 + AR71XX_MEM_SIZE_MAX))) ++ return 1; + -+#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000) -+#define AR724X_PCI_CTRL_SIZE 0x100 ++ return 0; ++} + -+#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000) -+#define AR91XX_WMAC_SIZE 0x30000 ++static void __init ar71xx_prom_append_cmdline(const char *name, ++ const char *value) ++{ ++ char buf[COMMAND_LINE_SIZE]; + -+#define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000) -+#define AR933X_UART_SIZE 0x14 -+#define AR933X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) -+#define AR933X_WMAC_SIZE 0x20000 ++ snprintf(buf, sizeof(buf), " %s=%s", name, value); ++ strlcat(arcs_cmdline, buf, sizeof(arcs_cmdline)); ++} + -+#define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) -+#define AR934X_WMAC_SIZE 0x20000 ++static const char * __init ar71xx_prom_find_env(char **envp, const char *name) ++{ ++ const char *ret = NULL; ++ int len; ++ char **p; + -+#define AR71XX_MEM_SIZE_MIN 0x0200000 -+#define AR71XX_MEM_SIZE_MAX 0x10000000 ++ if (!is_valid_ram_addr(envp)) ++ return NULL; + -+#define AR71XX_CPU_IRQ_BASE 0 -+#define AR71XX_MISC_IRQ_BASE 8 -+#define AR71XX_MISC_IRQ_COUNT 32 -+#define AR71XX_GPIO_IRQ_BASE 40 -+#define AR71XX_GPIO_IRQ_COUNT 32 -+#define AR71XX_PCI_IRQ_BASE 72 -+#define AR71XX_PCI_IRQ_COUNT 8 ++ len = strlen(name); ++ for (p = envp; is_valid_ram_addr(*p); p++) { ++ if (strncmp(name, *p, len) == 0 && (*p)[len] == '=') { ++ ret = *p + len + 1; ++ break; ++ } + -+#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2) -+#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3) -+#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4) -+#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5) -+#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6) -+#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7) ++ /* RedBoot env comes in pointer pairs - key, value */ ++ if (strncmp(name, *p, len) == 0 && (*p)[len] == 0) ++ if (is_valid_ram_addr(*(++p))) { ++ ret = *p; ++ break; ++ } ++ } + -+#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0) -+#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1) -+#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2) -+#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3) -+#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4) -+#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5) -+#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6) -+#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7) -+#define AR71XX_MISC_IRQ_TIMER2 (AR71XX_MISC_IRQ_BASE + 8) -+#define AR71XX_MISC_IRQ_TIMER3 (AR71XX_MISC_IRQ_BASE + 9) -+#define AR71XX_MISC_IRQ_TIMER4 (AR71XX_MISC_IRQ_BASE + 10) -+#define AR71XX_MISC_IRQ_DDR_PERF (AR71XX_MISC_IRQ_BASE + 11) -+#define AR71XX_MISC_IRQ_ENET_LINK (AR71XX_MISC_IRQ_BASE + 12) ++ return ret; ++} + -+#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x)) ++static int __init ar71xx_prom_init_myloader(void) ++{ ++ struct myloader_info *mylo; ++ char mac_buf[32]; ++ char *mac; + -+#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0) -+#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1) -+#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2) -+#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4) ++ mylo = myloader_get_info(); ++ if (!mylo) ++ return 0; + -+extern u32 ar71xx_ahb_freq; -+extern u32 ar71xx_cpu_freq; -+extern u32 ar71xx_ddr_freq; -+extern u32 ar71xx_ref_freq; ++ switch (mylo->did) { ++ case DEVID_COMPEX_WP543: ++ ar71xx_prom_append_cmdline("board", "WP543"); ++ break; ++ default: ++ printk(KERN_WARNING "prom: unknown device id: %x\n", ++ mylo->did); ++ return 0; ++ } + -+enum ar71xx_soc_type { -+ AR71XX_SOC_UNKNOWN, -+ AR71XX_SOC_AR7130, -+ AR71XX_SOC_AR7141, -+ AR71XX_SOC_AR7161, -+ AR71XX_SOC_AR7240, -+ AR71XX_SOC_AR7241, -+ AR71XX_SOC_AR7242, -+ AR71XX_SOC_AR9130, -+ AR71XX_SOC_AR9132, -+ AR71XX_SOC_AR9330, -+ AR71XX_SOC_AR9331, -+ AR71XX_SOC_AR9341, -+ AR71XX_SOC_AR9342, -+ AR71XX_SOC_AR9344, -+}; -+extern u32 ar71xx_soc_rev; ++ mac = mylo->macs[0]; ++ snprintf(mac_buf, sizeof(mac_buf), "%02x:%02x:%02x:%02x:%02x:%02x", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + -+extern enum ar71xx_soc_type ar71xx_soc; ++ ar71xx_prom_append_cmdline("ethaddr", mac_buf); + -+/* -+ * PLL block -+ */ -+#define AR71XX_PLL_REG_CPU_CONFIG 0x00 -+#define AR71XX_PLL_REG_SEC_CONFIG 0x04 -+#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 -+#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 ++ return 1; ++} + -+#define AR71XX_PLL_DIV_SHIFT 3 -+#define AR71XX_PLL_DIV_MASK 0x1f -+#define AR71XX_CPU_DIV_SHIFT 16 -+#define AR71XX_CPU_DIV_MASK 0x3 -+#define AR71XX_DDR_DIV_SHIFT 18 -+#define AR71XX_DDR_DIV_MASK 0x3 -+#define AR71XX_AHB_DIV_SHIFT 20 -+#define AR71XX_AHB_DIV_MASK 0x7 ++#ifdef CONFIG_IMAGE_CMDLINE_HACK ++extern char __image_cmdline[]; + -+#define AR71XX_ETH0_PLL_SHIFT 17 -+#define AR71XX_ETH1_PLL_SHIFT 19 ++static int __init ar71xx_use__image_cmdline(void) ++{ ++ char *p = __image_cmdline; ++ int replace = 0; + -+#define AR724X_PLL_REG_CPU_CONFIG 0x00 -+#define AR724X_PLL_REG_PCIE_CONFIG 0x18 ++ if (*p == '-') { ++ replace = 1; ++ p++; ++ } + -+#define AR724X_PLL_DIV_SHIFT 0 -+#define AR724X_PLL_DIV_MASK 0x3ff -+#define AR724X_PLL_REF_DIV_SHIFT 10 -+#define AR724X_PLL_REF_DIV_MASK 0xf -+#define AR724X_AHB_DIV_SHIFT 19 -+#define AR724X_AHB_DIV_MASK 0x1 -+#define AR724X_DDR_DIV_SHIFT 22 -+#define AR724X_DDR_DIV_MASK 0x3 ++ if (*p == '\0') ++ return 0; + -+#define AR7242_PLL_REG_ETH0_INT_CLOCK 0x2c ++ if (replace) { ++ strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline)); ++ } else { ++ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); ++ strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); ++ } + -+#define AR91XX_PLL_REG_CPU_CONFIG 0x00 -+#define AR91XX_PLL_REG_ETH_CONFIG 0x04 -+#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14 -+#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18 ++ return 1; ++} ++#else ++static inline int ar71xx_use__image_cmdline(void) { return 0; } ++#endif + -+#define AR91XX_PLL_DIV_SHIFT 0 -+#define AR91XX_PLL_DIV_MASK 0x3ff -+#define AR91XX_DDR_DIV_SHIFT 22 -+#define AR91XX_DDR_DIV_MASK 0x3 -+#define AR91XX_AHB_DIV_SHIFT 19 -+#define AR91XX_AHB_DIV_MASK 0x1 ++static __init void ar71xx_prom_init_cmdline(int argc, char **argv) ++{ ++ int i; + -+#define AR91XX_ETH0_PLL_SHIFT 20 -+#define AR91XX_ETH1_PLL_SHIFT 22 ++ if (ar71xx_use__image_cmdline()) ++ return; + -+#define AR933X_PLL_CPU_CONFIG_REG 0x00 -+#define AR933X_PLL_CLOCK_CTRL_REG 0x08 ++ if (!is_valid_ram_addr(argv)) ++ return; + -+#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT 10 -+#define AR933X_PLL_CPU_CONFIG_NINT_MASK 0x3f -+#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT 16 -+#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f -+#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT 23 -+#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7 ++ for (i = 0; i < argc; i++) ++ if (is_valid_ram_addr(argv[i])) { ++ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); ++ strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline)); ++ } ++} + -+#define AR933X_PLL_CLOCK_CTRL_BYPASS BIT(2) -+#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT 5 -+#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK 0x3 -+#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT 10 -+#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK 0x3 -+#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15 -+#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7 ++void __init prom_init(void) ++{ ++ const char *env; ++ char **envp; + -+#define AR934X_PLL_REG_CPU_CONFIG 0x00 -+#define AR934X_PLL_REG_DDR_CTRL_CLOCK 0x8 ++ printk(KERN_DEBUG "prom: fw_arg0=%08x, fw_arg1=%08x, " ++ "fw_arg2=%08x, fw_arg3=%08x\n", ++ (unsigned int)fw_arg0, (unsigned int)fw_arg1, ++ (unsigned int)fw_arg2, (unsigned int)fw_arg3); + -+#define AR934X_CPU_PLL_CFG_OUTDIV_MSB 21 -+#define AR934X_CPU_PLL_CFG_OUTDIV_LSB 19 -+#define AR934X_CPU_PLL_CFG_OUTDIV_MASK 0x00380000 + -+#define AR934X_CPU_PLL_CFG_OUTDIV_GET(x) \ -+ (((x) & AR934X_CPU_PLL_CFG_OUTDIV_MASK) >> \ -+ AR934X_CPU_PLL_CFG_OUTDIV_LSB) ++ if (ar71xx_prom_init_myloader()) ++ return; + -+#define AR934X_DDR_PLL_CFG_OUTDIV_MSB 25 -+#define AR934X_DDR_PLL_CFG_OUTDIV_LSB 23 -+#define AR934X_DDR_PLL_CFG_OUTDIV_MASK 0x03800000 ++ ar71xx_prom_init_cmdline(fw_arg0, (char **)fw_arg1); + -+#define AR934X_DDR_PLL_CFG_OUTDIV_GET(x) \ -+ (((x) & AR934X_DDR_PLL_CFG_OUTDIV_MASK) >> \ -+ AR934X_DDR_PLL_CFG_OUTDIV_LSB) ++ envp = (char **)fw_arg2; ++ if (!strstr(arcs_cmdline, "ethaddr=")) { ++ env = ar71xx_prom_find_env(envp, "ethaddr"); ++ if (env) ++ ar71xx_prom_append_cmdline("ethaddr", env); ++ } + -+#define AR934X_DDR_PLL_CFG_OUTDIV_SET(x) \ -+ (((x) << AR934X_DDR_PLL_CFG_OUTDIV_LSB) & \ -+ AR934X_DDR_PLL_CFG_OUTDIV_MASK) ++ if (!strstr(arcs_cmdline, "board=")) { ++ env = ar71xx_prom_find_env(envp, "board"); ++ if (env) { ++ /* Workaround for buggy bootloaders */ ++ if (strcmp(env, "RouterStation") == 0 || ++ strcmp(env, "Ubiquiti AR71xx-based board") == 0) ++ env = "UBNT-RS"; + -+#define AR934X_CPU_PLL_CFG_REFDIV_MSB 16 -+#define AR934X_CPU_PLL_CFG_REFDIV_LSB 12 -+#define AR934X_CPU_PLL_CFG_REFDIV_MASK 0x0001f000 ++ if (strcmp(env, "RouterStation PRO") == 0) ++ env = "UBNT-RSPRO"; + -+#define AR934X_CPU_PLL_CFG_REFDIV_GET(x) \ -+ (((x) & AR934X_CPU_PLL_CFG_REFDIV_MASK) >> \ -+ AR934X_CPU_PLL_CFG_REFDIV_LSB) ++ ar71xx_prom_append_cmdline("board", env); ++ } ++ } ++} + -+#define AR934X_CPU_PLL_CFG_REFDIV_SET(x) \ -+ (((x) << AR934X_CPU_PLL_CFG_REFDIV_LSB) & \ -+ AR934X_CPU_PLL_CFG_REFDIV_MASK) ++void __init prom_free_prom_memory(void) ++{ ++ /* We do not have to prom memory to free */ ++} +diff -Nur linux-2.6.39.orig/arch/mips/ar71xx/setup.c linux-2.6.39/arch/mips/ar71xx/setup.c +--- linux-2.6.39.orig/arch/mips/ar71xx/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/ar71xx/setup.c 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,446 @@ ++/* ++ * Atheros AR71xx SoC specific setup ++ * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.31 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+#define AR934X_CPU_PLL_CFG_REFDIV_RESET 2 ++#include ++#include ++#include + -+#define AR934X_CPU_PLL_CFG_NINT_MSB 11 -+#define AR934X_CPU_PLL_CFG_NINT_LSB 6 -+#define AR934X_CPU_PLL_CFG_NINT_MASK 0x00000fc0 ++#include ++#include /* for mips_hpt_frequency */ ++#include /* for _machine_{restart,halt} */ ++#include + -+#define AR934X_CPU_PLL_CFG_NINT_GET(x) \ -+ (((x) & AR934X_CPU_PLL_CFG_NINT_MASK) >> \ -+ AR934X_CPU_PLL_CFG_NINT_LSB) ++#include + -+#define AR934X_CPU_PLL_CFG_NINT_SET(x) \ -+ (((x) << AR934X_CPU_PLL_CFG_NINT_LSB) & \ -+ AR934X_CPU_PLL_CFG_NINT_MASK) ++#include "machtype.h" ++#include "devices.h" + -+#define AR934X_CPU_PLL_CFG_NINT_RESET 20 ++#define AR71XX_SYS_TYPE_LEN 64 + -+#define AR934X_CPU_PLL_CFG_NFRAC_MSB 5 -+#define AR934X_CPU_PLL_CFG_NFRAC_LSB 0 -+#define AR934X_CPU_PLL_CFG_NFRAC_MASK 0x0000003f ++u32 ar71xx_cpu_freq; ++EXPORT_SYMBOL_GPL(ar71xx_cpu_freq); + -+#define AR934X_CPU_PLL_CFG_NFRAC_GET(x) \ -+ (((x) & AR934X_CPU_PLL_CFG_NFRAC_MASK) >> \ -+ AR934X_CPU_PLL_CFG_NFRAC_LSB) ++u32 ar71xx_ahb_freq; ++EXPORT_SYMBOL_GPL(ar71xx_ahb_freq); + -+#define AR934X_CPU_PLL_CFG_NFRAC_SET(x) \ -+ (((x) << AR934X_CPU_PLL_CFG_NFRAC_LSB) & \ -+ AR934X_CPU_PLL_CFG_NFRAC_MASK) ++u32 ar71xx_ddr_freq; ++EXPORT_SYMBOL_GPL(ar71xx_ddr_freq); + -+#define AR934X_DDR_PLL_CFG_REFDIV_MSB 20 -+#define AR934X_DDR_PLL_CFG_REFDIV_LSB 16 -+#define AR934X_DDR_PLL_CFG_REFDIV_MASK 0x001f0000 ++u32 ar71xx_ref_freq; ++EXPORT_SYMBOL_GPL(ar71xx_ref_freq); + -+#define AR934X_DDR_PLL_CFG_REFDIV_GET(x) \ -+ (((x) & AR934X_DDR_PLL_CFG_REFDIV_MASK) >> \ -+ AR934X_DDR_PLL_CFG_REFDIV_LSB) ++enum ar71xx_soc_type ar71xx_soc; ++EXPORT_SYMBOL_GPL(ar71xx_soc); + -+#define AR934X_DDR_PLL_CFG_REFDIV_SET(x) \ -+ (((x) << AR934X_DDR_PLL_CFG_REFDIV_LSB) & \ -+ AR934X_DDR_PLL_CFG_REFDIV_MASK) ++u32 ar71xx_soc_rev; ++EXPORT_SYMBOL_GPL(ar71xx_soc_rev); + -+#define AR934X_DDR_PLL_CFG_REFDIV_RESET 2 ++static char ar71xx_sys_type[AR71XX_SYS_TYPE_LEN]; + -+#define AR934X_DDR_PLL_CFG_NINT_MSB 15 -+#define AR934X_DDR_PLL_CFG_NINT_LSB 10 -+#define AR934X_DDR_PLL_CFG_NINT_MASK 0x0000fc00 ++static void ar71xx_restart(char *command) ++{ ++ ar71xx_device_stop(RESET_MODULE_FULL_CHIP); ++ for (;;) ++ if (cpu_wait) ++ cpu_wait(); ++} + -+#define AR934X_DDR_PLL_CFG_NINT_GET(x) \ -+ (((x) & AR934X_DDR_PLL_CFG_NINT_MASK) >> \ -+ AR934X_DDR_PLL_CFG_NINT_LSB) ++static void ar71xx_halt(void) ++{ ++ while (1) ++ cpu_wait(); ++} + -+#define AR934X_DDR_PLL_CFG_NINT_SET(x) \ -+ (((x) << AR934X_DDR_PLL_CFG_NINT_LSB) & \ -+ AR934X_DDR_PLL_CFG_NINT_MASK) ++static void __init ar71xx_detect_mem_size(void) ++{ ++ unsigned long size; + -+#define AR934X_DDR_PLL_CFG_NINT_RESET 20 ++ for (size = AR71XX_MEM_SIZE_MIN; size < AR71XX_MEM_SIZE_MAX; ++ size <<= 1) { ++ if (!memcmp(ar71xx_detect_mem_size, ++ ar71xx_detect_mem_size + size, 1024)) ++ break; ++ } + -+#define AR934X_DDR_PLL_CFG_NFRAC_MSB 9 -+#define AR934X_DDR_PLL_CFG_NFRAC_LSB 0 -+#define AR934X_DDR_PLL_CFG_NFRAC_MASK 0x000003ff ++ add_memory_region(0, size, BOOT_MEM_RAM); ++} + -+#define AR934X_DDR_PLL_CFG_NFRAC_GET(x) \ -+ (((x) & AR934X_DDR_PLL_CFG_NFRAC_MASK) >> \ -+ AR934X_DDR_PLL_CFG_NFRAC_LSB) ++static void __init ar71xx_detect_sys_type(void) ++{ ++ char *chip = "????"; ++ u32 id; ++ u32 major; ++ u32 minor; ++ u32 rev = 0; + -+#define AR934X_DDR_PLL_CFG_NFRAC_SET(x) \ -+ (((x) << AR934X_DDR_PLL_CFG_NFRAC_LSB) & \ -+ AR934X_DDR_PLL_CFG_NFRAC_MASK) ++ id = ar71xx_reset_rr(AR71XX_RESET_REG_REV_ID); ++ major = id & REV_ID_MAJOR_MASK; + -+#define AR934X_DDR_PLL_CFG_NFRAC_RESET 512 ++ switch (major) { ++ case REV_ID_MAJOR_AR71XX: ++ minor = id & AR71XX_REV_ID_MINOR_MASK; ++ rev = id >> AR71XX_REV_ID_REVISION_SHIFT; ++ rev &= AR71XX_REV_ID_REVISION_MASK; ++ switch (minor) { ++ case AR71XX_REV_ID_MINOR_AR7130: ++ ar71xx_soc = AR71XX_SOC_AR7130; ++ chip = "7130"; ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MSB 19 -+#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB 15 -+#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x000f8000 ++ case AR71XX_REV_ID_MINOR_AR7141: ++ ar71xx_soc = AR71XX_SOC_AR7141; ++ chip = "7141"; ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_GET(x) \ -+ (((x) & AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK) >> \ -+ AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB) ++ case AR71XX_REV_ID_MINOR_AR7161: ++ ar71xx_soc = AR71XX_SOC_AR7161; ++ chip = "7161"; ++ break; ++ } ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SET(x) \ -+ (((x) << AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB) & \ -+ AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK) ++ case REV_ID_MAJOR_AR7240: ++ ar71xx_soc = AR71XX_SOC_AR7240; ++ chip = "7240"; ++ rev = id & AR724X_REV_ID_REVISION_MASK; ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_RESET 0 ++ case REV_ID_MAJOR_AR7241: ++ ar71xx_soc = AR71XX_SOC_AR7241; ++ chip = "7241"; ++ rev = id & AR724X_REV_ID_REVISION_MASK; ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MSB 14 -+#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB 10 -+#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x00007c00 ++ case REV_ID_MAJOR_AR7242: ++ ar71xx_soc = AR71XX_SOC_AR7242; ++ chip = "7242"; ++ rev = id & AR724X_REV_ID_REVISION_MASK; ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_GET(x) \ -+ (((x) & AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK) >> \ -+ AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB) ++ case REV_ID_MAJOR_AR913X: ++ minor = id & AR91XX_REV_ID_MINOR_MASK; ++ rev = id >> AR91XX_REV_ID_REVISION_SHIFT; ++ rev &= AR91XX_REV_ID_REVISION_MASK; ++ switch (minor) { ++ case AR91XX_REV_ID_MINOR_AR9130: ++ ar71xx_soc = AR71XX_SOC_AR9130; ++ chip = "9130"; ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SET(x) \ -+ (((x) << AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB) & \ -+ AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK) ++ case AR91XX_REV_ID_MINOR_AR9132: ++ ar71xx_soc = AR71XX_SOC_AR9132; ++ chip = "9132"; ++ break; ++ } ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_RESET 0 ++ case REV_ID_MAJOR_AR9330: ++ ar71xx_soc = AR71XX_SOC_AR9330; ++ chip = "9330"; ++ rev = id & AR933X_REV_ID_REVISION_MASK; ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MSB 9 -+#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB 5 -+#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x000003e0 ++ case REV_ID_MAJOR_AR9331: ++ ar71xx_soc = AR71XX_SOC_AR9331; ++ chip = "9331"; ++ rev = id & AR933X_REV_ID_REVISION_MASK; ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_GET(x) \ -+ (((x) & AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK) >> \ -+ AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB) ++ case REV_ID_MAJOR_AR9342: ++ ar71xx_soc = AR71XX_SOC_AR9342; ++ chip = "9342"; ++ rev = id & AR934X_REV_ID_REVISION_MASK; ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SET(x) \ -+ (((x) << AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB) & \ -+ AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK) ++ case REV_ID_MAJOR_AR9344: ++ ar71xx_soc = AR71XX_SOC_AR9344; ++ chip = "9344"; ++ rev = id & AR934X_REV_ID_REVISION_MASK; ++ break; + -+#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_RESET 0 ++ default: ++ panic("ar71xx: unknown chip id:0x%08x\n", id); ++ } + -+#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MSB 24 -+#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB 24 -+#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK 0x01000000 ++ ar71xx_soc_rev = rev; + -+#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_GET(x) \ -+ (((x) & AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK) >> \ -+ AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB) ++ sprintf(ar71xx_sys_type, "Atheros AR%s rev %u", chip, rev); ++ pr_info("SoC: %s\n", ar71xx_sys_type); ++} + -+#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_SET(x) \ -+ (((x) << AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB) & \ -+ AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK) ++static void __init ar934x_detect_sys_frequency(void) ++{ ++ u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; + -+#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_RESET 1 ++ if (ar71xx_reset_rr(AR934X_RESET_REG_BOOTSTRAP) & AR934X_REF_CLK_40) ++ ar71xx_ref_freq = 40 * 1000 * 1000; ++ else ++ ar71xx_ref_freq = 25 * 1000 * 1000; + -+extern void __iomem *ar71xx_pll_base; ++ clk_ctrl = ar71xx_pll_rr(AR934X_PLL_REG_DDR_CTRL_CLOCK); + -+static inline void ar71xx_pll_wr(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_pll_base + reg); -+} ++ pll = ar71xx_pll_rr(AR934X_PLL_REG_CPU_CONFIG); ++ out_div = AR934X_CPU_PLL_CFG_OUTDIV_GET(pll); ++ ref_div = AR934X_CPU_PLL_CFG_REFDIV_GET(pll); ++ nint = AR934X_CPU_PLL_CFG_NINT_GET(pll); ++ frac = AR934X_CPU_PLL_CFG_NFRAC_GET(pll); ++ postdiv = AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_GET(clk_ctrl); ++ ar71xx_cpu_freq = ((nint * ar71xx_ref_freq / ref_div) >> out_div) / ++ (postdiv + 1); + -+static inline u32 ar71xx_pll_rr(unsigned reg) -+{ -+ return __raw_readl(ar71xx_pll_base + reg); -+} ++ out_div = AR934X_DDR_PLL_CFG_OUTDIV_GET(pll); ++ ref_div = AR934X_DDR_PLL_CFG_REFDIV_GET(pll); ++ nint = AR934X_DDR_PLL_CFG_NINT_GET(pll); ++ frac = AR934X_DDR_PLL_CFG_NFRAC_GET(pll); ++ postdiv = AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_GET(clk_ctrl); ++ ar71xx_ddr_freq = ((nint * ar71xx_ref_freq / ref_div) >> out_div) / ++ (postdiv + 1); + -+/* -+ * USB_CONFIG block -+ */ -+#define USB_CTRL_REG_FLADJ 0x00 -+#define USB_CTRL_REG_CONFIG 0x04 ++ postdiv = AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_GET(clk_ctrl); + -+extern void __iomem *ar71xx_usb_ctrl_base; ++ if (AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_GET(clk_ctrl)) { ++ ar71xx_ahb_freq = ar71xx_ddr_freq / (postdiv + 1); ++ } else { ++ ar71xx_ahb_freq = ar71xx_cpu_freq / (postdiv + 1); ++ } + -+static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_usb_ctrl_base + reg); +} + -+static inline u32 ar71xx_usb_ctrl_rr(unsigned reg) ++static void __init ar91xx_detect_sys_frequency(void) +{ -+ return __raw_readl(ar71xx_usb_ctrl_base + reg); -+} -+ -+/* -+ * GPIO block -+ */ -+#define GPIO_REG_OE 0x00 -+#define GPIO_REG_IN 0x04 -+#define GPIO_REG_OUT 0x08 -+#define GPIO_REG_SET 0x0c -+#define GPIO_REG_CLEAR 0x10 -+#define GPIO_REG_INT_MODE 0x14 -+#define GPIO_REG_INT_TYPE 0x18 -+#define GPIO_REG_INT_POLARITY 0x1c -+#define GPIO_REG_INT_PENDING 0x20 -+#define GPIO_REG_INT_ENABLE 0x24 -+#define GPIO_REG_FUNC 0x28 ++ u32 pll; ++ u32 freq; ++ u32 div; + -+#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17) -+#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16) -+#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13) -+#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12) -+#define AR71XX_GPIO_FUNC_UART_EN BIT(8) -+#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4) -+#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0) ++ ar71xx_ref_freq = 5 * 1000 * 1000; + -+#define AR71XX_GPIO_COUNT 16 ++ pll = ar71xx_pll_rr(AR91XX_PLL_REG_CPU_CONFIG); + -+#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19) -+#define AR724X_GPIO_FUNC_SPI_EN BIT(18) -+#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14) -+#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13) -+#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12) -+#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11) -+#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10) -+#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9) -+#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) -+#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) -+#define AR724X_GPIO_FUNC_UART_EN BIT(1) -+#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0) ++ div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK); ++ freq = div * ar71xx_ref_freq; + -+#define AR724X_GPIO_COUNT 18 ++ ar71xx_cpu_freq = freq; + -+#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22) -+#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21) -+#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20) -+#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19) -+#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18) -+#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17) -+#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16) -+#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9) -+#define AR91XX_GPIO_FUNC_UART_EN BIT(8) -+#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4) ++ div = ((pll >> AR91XX_DDR_DIV_SHIFT) & AR91XX_DDR_DIV_MASK) + 1; ++ ar71xx_ddr_freq = freq / div; + -+#define AR91XX_GPIO_COUNT 22 ++ div = (((pll >> AR91XX_AHB_DIV_SHIFT) & AR91XX_AHB_DIV_MASK) + 1) * 2; ++ ar71xx_ahb_freq = ar71xx_cpu_freq / div; ++} + -+#define AR933X_GPIO_COUNT 30 ++static void __init ar71xx_detect_sys_frequency(void) ++{ ++ u32 pll; ++ u32 freq; ++ u32 div; + -+#define AR934X_GPIO_FUNC_SPI_CS_1_EN BIT(14) -+#define AR934X_GPIO_FUNC_SPI_CS_0_EN BIT(13) ++ ar71xx_ref_freq = 40 * 1000 * 1000; + -+#define AR934X_GPIO_COUNT 32 -+#define AR934X_GPIO_FUNC_DDR_DQOE_EN BIT(17) ++ pll = ar71xx_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); + -+extern void __iomem *ar71xx_gpio_base; ++ div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; ++ freq = div * ar71xx_ref_freq; + -+static inline void ar71xx_gpio_wr(unsigned reg, u32 value) -+{ -+ __raw_writel(value, ar71xx_gpio_base + reg); ++ div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; ++ ar71xx_cpu_freq = freq / div; ++ ++ div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; ++ ar71xx_ddr_freq = freq / div; ++ ++ div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; ++ ar71xx_ahb_freq = ar71xx_cpu_freq / div; +} + -+static inline u32 ar71xx_gpio_rr(unsigned reg) ++static void __init ar724x_detect_sys_frequency(void) +{ -+ return __raw_readl(ar71xx_gpio_base + reg); ++ u32 pll; ++ u32 freq; ++ u32 div; ++ ++ ar71xx_ref_freq = 5 * 1000 * 1000; ++ ++ pll = ar71xx_pll_rr(AR724X_PLL_REG_CPU_CONFIG); ++ ++ div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); ++ freq = div * ar71xx_ref_freq; ++ ++ div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); ++ freq *= div; ++ ++ ar71xx_cpu_freq = freq; ++ ++ div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; ++ ar71xx_ddr_freq = freq / div; ++ ++ div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; ++ ar71xx_ahb_freq = ar71xx_cpu_freq / div; +} + -+void ar71xx_gpio_init(void) __init; -+void ar71xx_gpio_function_enable(u32 mask); -+void ar71xx_gpio_function_disable(u32 mask); -+void ar71xx_gpio_function_setup(u32 set, u32 clear); ++static void __init ar933x_detect_sys_frequency(void) ++{ ++ u32 clock_ctrl; ++ u32 cpu_config; ++ u32 freq; ++ u32 t; + -+/* -+ * DDR_CTRL block -+ */ -+#define AR71XX_DDR_REG_PCI_WIN0 0x7c -+#define AR71XX_DDR_REG_PCI_WIN1 0x80 -+#define AR71XX_DDR_REG_PCI_WIN2 0x84 -+#define AR71XX_DDR_REG_PCI_WIN3 0x88 -+#define AR71XX_DDR_REG_PCI_WIN4 0x8c -+#define AR71XX_DDR_REG_PCI_WIN5 0x90 -+#define AR71XX_DDR_REG_PCI_WIN6 0x94 -+#define AR71XX_DDR_REG_PCI_WIN7 0x98 -+#define AR71XX_DDR_REG_FLUSH_GE0 0x9c -+#define AR71XX_DDR_REG_FLUSH_GE1 0xa0 -+#define AR71XX_DDR_REG_FLUSH_USB 0xa4 -+#define AR71XX_DDR_REG_FLUSH_PCI 0xa8 ++ t = ar71xx_reset_rr(AR933X_RESET_REG_BOOTSTRAP); ++ if (t & AR933X_BOOTSTRAP_REF_CLK_40) ++ ar71xx_ref_freq = (40 * 1000 * 1000); ++ else ++ ar71xx_ref_freq = (25 * 1000 * 1000); + -+#define AR724X_DDR_REG_FLUSH_GE0 0x7c -+#define AR724X_DDR_REG_FLUSH_GE1 0x80 -+#define AR724X_DDR_REG_FLUSH_USB 0x84 -+#define AR724X_DDR_REG_FLUSH_PCIE 0x88 ++ clock_ctrl = ar71xx_pll_rr(AR933X_PLL_CLOCK_CTRL_REG); ++ if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { ++ ar71xx_cpu_freq = ar71xx_ref_freq; ++ ar71xx_ahb_freq = ar71xx_ref_freq; ++ ar71xx_ddr_freq = ar71xx_ref_freq; ++ } else { ++ cpu_config = ar71xx_pll_rr(AR933X_PLL_CPU_CONFIG_REG); + -+#define AR91XX_DDR_REG_FLUSH_GE0 0x7c -+#define AR91XX_DDR_REG_FLUSH_GE1 0x80 -+#define AR91XX_DDR_REG_FLUSH_USB 0x84 -+#define AR91XX_DDR_REG_FLUSH_WMAC 0x88 ++ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & ++ AR933X_PLL_CPU_CONFIG_REFDIV_MASK; ++ freq = ar71xx_ref_freq / t; + -+#define AR933X_DDR_REG_FLUSH_GE0 0x7c -+#define AR933X_DDR_REG_FLUSH_GE1 0x80 -+#define AR933X_DDR_REG_FLUSH_USB 0x84 -+#define AR933X_DDR_REG_FLUSH_WMAC 0x88 ++ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & ++ AR933X_PLL_CPU_CONFIG_NINT_MASK; ++ freq *= t; + -+#define AR934X_DDR_REG_FLUSH_GE0 0x9c -+#define AR934X_DDR_REG_FLUSH_GE1 0xa0 -+#define AR934X_DDR_REG_FLUSH_USB 0xa4 -+#define AR934X_DDR_REG_FLUSH_PCIE 0xa8 ++ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & ++ AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; ++ if (t == 0) ++ t = 1; + ++ freq >>= t; + -+#define PCI_WIN0_OFFS 0x10000000 -+#define PCI_WIN1_OFFS 0x11000000 -+#define PCI_WIN2_OFFS 0x12000000 -+#define PCI_WIN3_OFFS 0x13000000 -+#define PCI_WIN4_OFFS 0x14000000 -+#define PCI_WIN5_OFFS 0x15000000 -+#define PCI_WIN6_OFFS 0x16000000 -+#define PCI_WIN7_OFFS 0x07000000 ++ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & ++ AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; ++ ar71xx_cpu_freq = freq / t; + -+extern void __iomem *ar71xx_ddr_base; ++ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & ++ AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; ++ ar71xx_ddr_freq = freq / t; + -+static inline void ar71xx_ddr_wr(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_ddr_base + reg); ++ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & ++ AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; ++ ar71xx_ahb_freq = freq / t; ++ } +} + -+static inline u32 ar71xx_ddr_rr(unsigned reg) ++static void __init detect_sys_frequency(void) +{ -+ return __raw_readl(ar71xx_ddr_base + reg); -+} ++ switch (ar71xx_soc) { ++ case AR71XX_SOC_AR7130: ++ case AR71XX_SOC_AR7141: ++ case AR71XX_SOC_AR7161: ++ ar71xx_detect_sys_frequency(); ++ break; + -+void ar71xx_ddr_flush(u32 reg); ++ case AR71XX_SOC_AR7240: ++ case AR71XX_SOC_AR7241: ++ case AR71XX_SOC_AR7242: ++ ar724x_detect_sys_frequency(); ++ break; + -+/* -+ * PCI block -+ */ -+#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000) -+#define AR71XX_PCI_CFG_SIZE 0x100 ++ case AR71XX_SOC_AR9130: ++ case AR71XX_SOC_AR9132: ++ ar91xx_detect_sys_frequency(); ++ break; + -+#define PCI_REG_CRP_AD_CBE 0x00 -+#define PCI_REG_CRP_WRDATA 0x04 -+#define PCI_REG_CRP_RDDATA 0x08 -+#define PCI_REG_CFG_AD 0x0c -+#define PCI_REG_CFG_CBE 0x10 -+#define PCI_REG_CFG_WRDATA 0x14 -+#define PCI_REG_CFG_RDDATA 0x18 -+#define PCI_REG_PCI_ERR 0x1c -+#define PCI_REG_PCI_ERR_ADDR 0x20 -+#define PCI_REG_AHB_ERR 0x24 -+#define PCI_REG_AHB_ERR_ADDR 0x28 ++ case AR71XX_SOC_AR9330: ++ case AR71XX_SOC_AR9331: ++ ar933x_detect_sys_frequency(); ++ break; + -+#define PCI_CRP_CMD_WRITE 0x00010000 -+#define PCI_CRP_CMD_READ 0x00000000 -+#define PCI_CFG_CMD_READ 0x0000000a -+#define PCI_CFG_CMD_WRITE 0x0000000b ++ case AR71XX_SOC_AR9341: ++ case AR71XX_SOC_AR9342: ++ case AR71XX_SOC_AR9344: ++ ar934x_detect_sys_frequency(); ++ break; ++ default: ++ BUG(); ++ } ++} + -+#define PCI_IDSEL_ADL_START 17 ++const char *get_system_type(void) ++{ ++ return ar71xx_sys_type; ++} + -+#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000) -+#define AR724X_PCI_CFG_SIZE 0x1000 ++unsigned int __cpuinit get_c0_compare_irq(void) ++{ ++ return CP0_LEGACY_COMPARE_IRQ; ++} + -+#define AR724X_PCI_REG_APP 0x00 -+#define AR724X_PCI_REG_RESET 0x18 -+#define AR724X_PCI_REG_INT_STATUS 0x4c -+#define AR724X_PCI_REG_INT_MASK 0x50 ++void __init plat_mem_setup(void) ++{ ++ set_io_port_base(KSEG1); + -+#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0) -+#define AR724X_PCI_RESET_LINK_UP BIT(0) ++ ar71xx_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, ++ AR71XX_DDR_CTRL_SIZE); + -+#define AR724X_PCI_INT_DEV0 BIT(14) ++ ar71xx_pll_base = ioremap_nocache(AR71XX_PLL_BASE, ++ AR71XX_PLL_SIZE); + -+/* -+ * RESET block -+ */ -+#define AR71XX_RESET_REG_TIMER 0x00 -+#define AR71XX_RESET_REG_TIMER_RELOAD 0x04 -+#define AR71XX_RESET_REG_WDOG_CTRL 0x08 -+#define AR71XX_RESET_REG_WDOG 0x0c -+#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10 -+#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14 -+#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18 -+#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c -+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20 -+#define AR71XX_RESET_REG_RESET_MODULE 0x24 -+#define AR71XX_RESET_REG_PERFC_CTRL 0x2c -+#define AR71XX_RESET_REG_PERFC0 0x30 -+#define AR71XX_RESET_REG_PERFC1 0x34 -+#define AR71XX_RESET_REG_REV_ID 0x90 ++ ar71xx_reset_base = ioremap_nocache(AR71XX_RESET_BASE, ++ AR71XX_RESET_SIZE); + -+#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18 -+#define AR91XX_RESET_REG_RESET_MODULE 0x1c -+#define AR91XX_RESET_REG_PERF_CTRL 0x20 -+#define AR91XX_RESET_REG_PERFC0 0x24 -+#define AR91XX_RESET_REG_PERFC1 0x28 ++ ar71xx_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); + -+#define AR724X_RESET_REG_RESET_MODULE 0x1c ++ ar71xx_usb_ctrl_base = ioremap_nocache(AR71XX_USB_CTRL_BASE, ++ AR71XX_USB_CTRL_SIZE); + -+#define AR933X_RESET_REG_RESET_MODULE 0x1c -+#define AR933X_RESET_REG_BOOTSTRAP 0xac -+#define AR933X_BOOTSTRAP_EEPBUSY BIT(4) -+#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) ++ ar71xx_detect_mem_size(); ++ ar71xx_detect_sys_type(); ++ detect_sys_frequency(); + -+#define AR934X_RESET_REG_RESET_MODULE 0x1c -+#define AR934X_RESET_REG_BOOTSTRAP 0xb0 -+/* 0 - 25MHz 1 - 40 MHz */ -+#define AR934X_REF_CLK_40 (1 << 4) -+ -+#define WDOG_CTRL_LAST_RESET BIT(31) -+#define WDOG_CTRL_ACTION_MASK 3 -+#define WDOG_CTRL_ACTION_NONE 0 /* no action */ -+#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */ -+#define WDOG_CTRL_ACTION_NMI 2 /* NMI */ -+#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */ -+ -+#define MISC_INT_ENET_LINK BIT(12) -+#define MISC_INT_DDR_PERF BIT(11) -+#define MISC_INT_TIMER4 BIT(10) -+#define MISC_INT_TIMER3 BIT(9) -+#define MISC_INT_TIMER2 BIT(8) -+#define MISC_INT_DMA BIT(7) -+#define MISC_INT_OHCI BIT(6) -+#define MISC_INT_PERFC BIT(5) -+#define MISC_INT_WDOG BIT(4) -+#define MISC_INT_UART BIT(3) -+#define MISC_INT_GPIO BIT(2) -+#define MISC_INT_ERROR BIT(1) -+#define MISC_INT_TIMER BIT(0) -+ -+#define PCI_INT_CORE BIT(4) -+#define PCI_INT_DEV2 BIT(2) -+#define PCI_INT_DEV1 BIT(1) -+#define PCI_INT_DEV0 BIT(0) -+ -+#define RESET_MODULE_EXTERNAL BIT(28) -+#define RESET_MODULE_FULL_CHIP BIT(24) -+#define RESET_MODULE_AMBA2WMAC BIT(22) -+#define RESET_MODULE_CPU_NMI BIT(21) -+#define RESET_MODULE_CPU_COLD BIT(20) -+#define RESET_MODULE_DMA BIT(19) -+#define RESET_MODULE_SLIC BIT(18) -+#define RESET_MODULE_STEREO BIT(17) -+#define RESET_MODULE_DDR BIT(16) -+#define RESET_MODULE_GE1_MAC BIT(13) -+#define RESET_MODULE_GE1_PHY BIT(12) -+#define RESET_MODULE_USBSUS_OVERRIDE BIT(10) -+#define RESET_MODULE_GE0_MAC BIT(9) -+#define RESET_MODULE_GE0_PHY BIT(8) -+#define RESET_MODULE_USB_OHCI_DLL BIT(6) -+#define RESET_MODULE_USB_HOST BIT(5) -+#define RESET_MODULE_USB_PHY BIT(4) -+#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3) -+#define RESET_MODULE_PCI_BUS BIT(1) -+#define RESET_MODULE_PCI_CORE BIT(0) -+ -+#define AR724X_RESET_GE1_MDIO BIT(23) -+#define AR724X_RESET_GE0_MDIO BIT(22) -+#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10) -+#define AR724X_RESET_PCIE_PHY BIT(7) -+#define AR724X_RESET_PCIE BIT(6) -+#define AR724X_RESET_USB_HOST BIT(5) -+#define AR724X_RESET_USB_PHY BIT(4) -+#define AR724X_RESET_USBSUS_OVERRIDE BIT(3) -+ -+#define AR933X_RESET_WMAC BIT(11) -+#define AR933X_RESET_GE1_MDIO BIT(23) -+#define AR933X_RESET_GE0_MDIO BIT(22) -+#define AR933X_RESET_GE1_MAC BIT(13) -+#define AR933X_RESET_GE0_MAC BIT(9) -+ -+#define REV_ID_MAJOR_MASK 0xfff0 -+#define REV_ID_MAJOR_AR71XX 0x00a0 -+#define REV_ID_MAJOR_AR913X 0x00b0 -+#define REV_ID_MAJOR_AR7240 0x00c0 -+#define REV_ID_MAJOR_AR7241 0x0100 -+#define REV_ID_MAJOR_AR7242 0x1100 -+#define REV_ID_MAJOR_AR9330 0x0110 -+#define REV_ID_MAJOR_AR9331 0x1110 -+#define REV_ID_MAJOR_AR9341 0x0120 -+#define REV_ID_MAJOR_AR9342 0x1120 -+#define REV_ID_MAJOR_AR9344 0x2120 -+ -+#define AR71XX_REV_ID_MINOR_MASK 0x3 -+#define AR71XX_REV_ID_MINOR_AR7130 0x0 -+#define AR71XX_REV_ID_MINOR_AR7141 0x1 -+#define AR71XX_REV_ID_MINOR_AR7161 0x2 -+#define AR71XX_REV_ID_REVISION_MASK 0x3 -+#define AR71XX_REV_ID_REVISION_SHIFT 2 ++ pr_info("Clocks: CPU:%u.%03uMHz, DDR:%u.%03uMHz, AHB:%u.%03uMHz, " ++ "Ref:%u.%03uMHz", ++ ar71xx_cpu_freq / 1000000, (ar71xx_cpu_freq / 1000) % 1000, ++ ar71xx_ddr_freq / 1000000, (ar71xx_ddr_freq / 1000) % 1000, ++ ar71xx_ahb_freq / 1000000, (ar71xx_ahb_freq / 1000) % 1000, ++ ar71xx_ref_freq / 1000000, (ar71xx_ref_freq / 1000) % 1000); + -+#define AR91XX_REV_ID_MINOR_MASK 0x3 -+#define AR91XX_REV_ID_MINOR_AR9130 0x0 -+#define AR91XX_REV_ID_MINOR_AR9132 0x1 -+#define AR91XX_REV_ID_REVISION_MASK 0x3 -+#define AR91XX_REV_ID_REVISION_SHIFT 2 ++ _machine_restart = ar71xx_restart; ++ _machine_halt = ar71xx_halt; ++ pm_power_off = ar71xx_halt; ++} + -+#define AR724X_REV_ID_REVISION_MASK 0x3 ++void __init plat_time_init(void) ++{ ++ mips_hpt_frequency = ar71xx_cpu_freq / 2; ++} + -+#define AR933X_REV_ID_REVISION_MASK 0xf ++__setup("board=", mips_machtype_setup); + -+#define AR934X_REV_ID_REVISION_MASK 0xf ++static int __init ar71xx_machine_setup(void) ++{ ++ ar71xx_gpio_init(); + -+extern void __iomem *ar71xx_reset_base; ++ ar71xx_add_device_uart(); ++ ar71xx_add_device_wdt(); + -+static inline void ar71xx_reset_wr(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_reset_base + reg); ++ mips_machine_setup(); ++ return 0; +} + -+static inline u32 ar71xx_reset_rr(unsigned reg) ++arch_initcall(ar71xx_machine_setup); ++ ++static void __init ar71xx_generic_init(void) +{ -+ return __raw_readl(ar71xx_reset_base + reg); ++ /* Nothing to do */ +} + -+void ar71xx_device_stop(u32 mask); -+void ar71xx_device_start(u32 mask); -+int ar71xx_device_stopped(u32 mask); ++MIPS_MACHINE(AR71XX_MACH_GENERIC, "Generic", "Generic AR71xx board", ++ ar71xx_generic_init); +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/checksum.h linux-2.6.39/arch/mips/include/asm/checksum.h +--- linux-2.6.39.orig/arch/mips/include/asm/checksum.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/include/asm/checksum.h 2011-08-24 18:17:23.000000000 +0200 +@@ -12,6 +12,7 @@ + #define _ASM_CHECKSUM_H + + #include ++#include + + #include + +@@ -104,26 +105,30 @@ + const unsigned int *stop = word + ihl; + unsigned int csum; + int carry; ++ unsigned int w; + +- csum = word[0]; +- csum += word[1]; +- carry = (csum < word[1]); ++ csum = __get_unaligned_cpu32(word++); + ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; + +- csum += word[2]; +- carry = (csum < word[2]); ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; + +- csum += word[3]; +- carry = (csum < word[3]); ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; + +- word += 4; + do { +- csum += *word; +- carry = (csum < *word); ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; +- word++; + } while (word != stop); + + return csum_fold(csum); +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/fw/myloader/myloader.h linux-2.6.39/arch/mips/include/asm/fw/myloader/myloader.h +--- linux-2.6.39.orig/arch/mips/include/asm/fw/myloader/myloader.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/fw/myloader/myloader.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,34 @@ +/* -+ * SPI block ++ * Compex's MyLoader specific definitions ++ * ++ * Copyright (C) 2006-2008 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * + */ -+#define SPI_REG_FS 0x00 /* Function Select */ -+#define SPI_REG_CTRL 0x04 /* SPI Control */ -+#define SPI_REG_IOC 0x08 /* SPI I/O Control */ -+#define SPI_REG_RDS 0x0c /* Read Data Shift */ -+ -+#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */ -+ -+#define SPI_CTRL_RD BIT(6) /* Remap Disable */ -+#define SPI_CTRL_DIV_MASK 0x3f -+ -+#define SPI_IOC_DO BIT(0) /* Data Out pin */ -+#define SPI_IOC_CLK BIT(8) /* CLK pin */ -+#define SPI_IOC_CS(n) BIT(16 + (n)) -+#define SPI_IOC_CS0 SPI_IOC_CS(0) -+#define SPI_IOC_CS1 SPI_IOC_CS(1) -+#define SPI_IOC_CS2 SPI_IOC_CS(2) -+#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2) -+ -+void ar71xx_flash_acquire(void); -+void ar71xx_flash_release(void); + -+/* -+ * MII_CTRL block -+ */ -+#define MII_REG_MII0_CTRL 0x00 -+#define MII_REG_MII1_CTRL 0x04 ++#ifndef _ASM_MIPS_FW_MYLOADER_H ++#define _ASM_MIPS_FW_MYLOADER_H + -+#define MII0_CTRL_IF_GMII 0 -+#define MII0_CTRL_IF_MII 1 -+#define MII0_CTRL_IF_RGMII 2 -+#define MII0_CTRL_IF_RMII 3 ++#include + -+#define MII1_CTRL_IF_RGMII 0 -+#define MII1_CTRL_IF_RMII 1 ++struct myloader_info { ++ uint32_t vid; ++ uint32_t did; ++ uint32_t svid; ++ uint32_t sdid; ++ uint8_t macs[MYLO_ETHADDR_COUNT][6]; ++}; + -+#endif /* __ASSEMBLER__ */ ++#ifdef CONFIG_MYLOADER ++extern struct myloader_info *myloader_get_info(void) __init; ++#else ++static inline struct myloader_info *myloader_get_info(void) ++{ ++ return NULL; ++} ++#endif /* CONFIG_MYLOADER */ + -+#endif /* __ASM_MACH_AR71XX_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 2011-04-27 12:19:21.867661560 +0200 -@@ -0,0 +1,26 @@ ++#endif /* _ASM_MIPS_FW_MYLOADER_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar71xx.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,769 @@ +/* -+ * AR91xx parallel flash driver platform data definitions ++ * Atheros AR71xx SoC specific definitions + * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * ++ * Parts of this file are based on Atheros 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.31 BSP ++ * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + -+#ifndef __AR91XX_FLASH_H -+#define __AR91XX_FLASH_H ++#ifndef __ASM_MACH_AR71XX_H ++#define __ASM_MACH_AR71XX_H + -+struct mtd_partition; ++#include ++#include ++#include ++#include + -+struct ar91xx_flash_platform_data { -+ unsigned int width; -+ u8 is_shared:1; -+#ifdef CONFIG_MTD_PARTITIONS -+ unsigned int nr_parts; -+ struct mtd_partition *parts; -+#endif -+}; ++#ifndef __ASSEMBLER__ + -+#endif /* __AR91XX_FLASH_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h 2011-08-06 09:32:36.758018150 +0200 -@@ -0,0 +1,67 @@ -+/* -+ * Atheros AR933X UART defines -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++#define AR71XX_PCI_MEM_BASE 0x10000000 ++#define AR71XX_PCI_MEM_SIZE 0x08000000 ++#define AR71XX_APB_BASE 0x18000000 ++#define AR71XX_GE0_BASE 0x19000000 ++#define AR71XX_GE0_SIZE 0x01000000 ++#define AR71XX_GE1_BASE 0x1a000000 ++#define AR71XX_GE1_SIZE 0x01000000 ++#define AR71XX_EHCI_BASE 0x1b000000 ++#define AR71XX_EHCI_SIZE 0x01000000 ++#define AR71XX_OHCI_BASE 0x1c000000 ++#define AR71XX_OHCI_SIZE 0x01000000 ++#define AR7240_OHCI_BASE 0x1b000000 ++#define AR7240_OHCI_SIZE 0x01000000 ++#define AR71XX_SPI_BASE 0x1f000000 ++#define AR71XX_SPI_SIZE 0x01000000 + -+#ifndef __AR933X_UART_H -+#define __AR933X_UART_H ++#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000) ++#define AR71XX_DDR_CTRL_SIZE 0x10000 ++#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000) ++#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000) ++#define AR71XX_UART_SIZE 0x10000 ++#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) ++#define AR71XX_USB_CTRL_SIZE 0x10000 ++#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000) ++#define AR71XX_GPIO_SIZE 0x10000 ++#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000) ++#define AR71XX_PLL_SIZE 0x10000 ++#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) ++#define AR71XX_RESET_SIZE 0x10000 ++#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000) ++#define AR71XX_MII_SIZE 0x10000 ++#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000) ++#define AR71XX_SLIC_SIZE 0x10000 ++#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000) ++#define AR71XX_DMA_SIZE 0x10000 ++#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000) ++#define AR71XX_STEREO_SIZE 0x10000 + -+#define AR933X_UART_REGS_SIZE 20 -+#define AR933X_UART_FIFO_SIZE 16 ++#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000) ++#define AR724X_PCI_CRP_SIZE 0x100 + -+#define AR933X_UART_DATA_REG 0x00 -+#define AR933X_UART_CS_REG 0x04 -+#define AR933X_UART_CLOCK_REG 0x08 -+#define AR933X_UART_INT_REG 0x0c -+#define AR933X_UART_INT_EN_REG 0x10 ++#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000) ++#define AR724X_PCI_CTRL_SIZE 0x100 + -+#define AR933X_UART_DATA_TX_RX_MASK 0xff -+#define AR933X_UART_DATA_RX_CSR BIT(8) -+#define AR933X_UART_DATA_TX_CSR BIT(9) ++#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000) ++#define AR91XX_WMAC_SIZE 0x30000 + -+#define AR933X_UART_CS_PARITY_S 0 -+#define AR933X_UART_CS_PARITY_M 0x3 -+#define AR933X_UART_CS_PARITY_NONE 0 -+#define AR933X_UART_CS_PARITY_ODD 1 -+#define AR933X_UART_CS_PARITY_EVEN 2 -+#define AR933X_UART_CS_IF_MODE_S 2 -+#define AR933X_UART_CS_IF_MODE_M 0x3 -+#define AR933X_UART_CS_IF_MODE_NONE 0 -+#define AR933X_UART_CS_IF_MODE_DTE 1 -+#define AR933X_UART_CS_IF_MODE_DCE 2 -+#define AR933X_UART_CS_FLOW_CTRL_S 4 -+#define AR933X_UART_CS_FLOW_CTRL_M 0x3 -+#define AR933X_UART_CS_DMA_EN BIT(6) -+#define AR933X_UART_CS_TX_READY_ORIDE BIT(7) -+#define AR933X_UART_CS_RX_READY_ORIDE BIT(8) -+#define AR933X_UART_CS_TX_READY BIT(9) -+#define AR933X_UART_CS_RX_BREAK BIT(10) -+#define AR933X_UART_CS_TX_BREAK BIT(11) -+#define AR933X_UART_CS_HOST_INT BIT(12) -+#define AR933X_UART_CS_HOST_INT_EN BIT(13) -+#define AR933X_UART_CS_TX_BUSY BIT(14) -+#define AR933X_UART_CS_RX_BUSY BIT(15) ++#define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000) ++#define AR933X_UART_SIZE 0x14 ++#define AR933X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) ++#define AR933X_WMAC_SIZE 0x20000 + -+#define AR933X_UART_CLOCK_STEP_M 0xffff -+#define AR933X_UART_CLOCK_SCALE_M 0xfff -+#define AR933X_UART_CLOCK_SCALE_S 16 -+#define AR933X_UART_CLOCK_STEP_M 0xffff ++#define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) ++#define AR934X_WMAC_SIZE 0x20000 + -+#define AR933X_UART_INT_RX_VALID BIT(0) -+#define AR933X_UART_INT_TX_READY BIT(1) -+#define AR933X_UART_INT_RX_FRAMING_ERR BIT(2) -+#define AR933X_UART_INT_RX_OFLOW_ERR BIT(3) -+#define AR933X_UART_INT_TX_OFLOW_ERR BIT(4) -+#define AR933X_UART_INT_RX_PARITY_ERR BIT(5) -+#define AR933X_UART_INT_RX_BREAK_ON BIT(6) -+#define AR933X_UART_INT_RX_BREAK_OFF BIT(7) -+#define AR933X_UART_INT_RX_FULL BIT(8) -+#define AR933X_UART_INT_TX_EMPTY BIT(9) -+#define AR933X_UART_INT_ALLINTS 0x3ff ++#define AR71XX_MEM_SIZE_MIN 0x0200000 ++#define AR71XX_MEM_SIZE_MAX 0x10000000 + -+#endif /* __AR933X_UART_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h 2011-08-06 09:32:36.758018150 +0200 -@@ -0,0 +1,18 @@ -+/* -+ * Platform data definition for Atheros AR933X UART -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++#define AR71XX_CPU_IRQ_BASE 0 ++#define AR71XX_MISC_IRQ_BASE 8 ++#define AR71XX_MISC_IRQ_COUNT 32 ++#define AR71XX_GPIO_IRQ_BASE 40 ++#define AR71XX_GPIO_IRQ_COUNT 32 ++#define AR71XX_PCI_IRQ_BASE 72 ++#define AR71XX_PCI_IRQ_COUNT 8 + -+#ifndef _AR933X_UART_PLATFORM_H -+#define _AR933X_UART_PLATFORM_H ++#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2) ++#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3) ++#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4) ++#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5) ++#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6) ++#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7) + -+struct ar933x_uart_platform_data { -+ unsigned uartclk; ++#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0) ++#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1) ++#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2) ++#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3) ++#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4) ++#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5) ++#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6) ++#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7) ++#define AR71XX_MISC_IRQ_TIMER2 (AR71XX_MISC_IRQ_BASE + 8) ++#define AR71XX_MISC_IRQ_TIMER3 (AR71XX_MISC_IRQ_BASE + 9) ++#define AR71XX_MISC_IRQ_TIMER4 (AR71XX_MISC_IRQ_BASE + 10) ++#define AR71XX_MISC_IRQ_DDR_PERF (AR71XX_MISC_IRQ_BASE + 11) ++#define AR71XX_MISC_IRQ_ENET_LINK (AR71XX_MISC_IRQ_BASE + 12) ++ ++#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x)) ++ ++#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0) ++#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1) ++#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2) ++#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4) ++ ++extern u32 ar71xx_ahb_freq; ++extern u32 ar71xx_cpu_freq; ++extern u32 ar71xx_ddr_freq; ++extern u32 ar71xx_ref_freq; ++ ++enum ar71xx_soc_type { ++ AR71XX_SOC_UNKNOWN, ++ AR71XX_SOC_AR7130, ++ AR71XX_SOC_AR7141, ++ AR71XX_SOC_AR7161, ++ AR71XX_SOC_AR7240, ++ AR71XX_SOC_AR7241, ++ AR71XX_SOC_AR7242, ++ AR71XX_SOC_AR9130, ++ AR71XX_SOC_AR9132, ++ AR71XX_SOC_AR9330, ++ AR71XX_SOC_AR9331, ++ AR71XX_SOC_AR9341, ++ AR71XX_SOC_AR9342, ++ AR71XX_SOC_AR9344, +}; ++extern u32 ar71xx_soc_rev; ++ ++extern enum ar71xx_soc_type ar71xx_soc; + -+#endif /* _AR933X_UART_PLATFORM_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 2011-04-27 12:19:21.877661867 +0200 -@@ -0,0 +1,56 @@ +/* -+ * Atheros AR71xx specific CPU feature overrides -+ * -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This file was derived from: include/asm-mips/cpu-features.h -+ * Copyright (C) 2003, 2004 Ralf Baechle -+ * Copyright (C) 2004 Maciej W. Rozycki -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * ++ * PLL block + */ -+#ifndef __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H -+#define __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H ++#define AR71XX_PLL_REG_CPU_CONFIG 0x00 ++#define AR71XX_PLL_REG_SEC_CONFIG 0x04 ++#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 ++#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 + -+#define cpu_has_tlb 1 -+#define cpu_has_4kex 1 -+#define cpu_has_3k_cache 0 -+#define cpu_has_4k_cache 1 -+#define cpu_has_tx39_cache 0 -+#define cpu_has_sb1_cache 0 -+#define cpu_has_fpu 0 -+#define cpu_has_32fpr 0 -+#define cpu_has_counter 1 -+#define cpu_has_watch 1 -+#define cpu_has_divec 1 ++#define AR71XX_PLL_DIV_SHIFT 3 ++#define AR71XX_PLL_DIV_MASK 0x1f ++#define AR71XX_CPU_DIV_SHIFT 16 ++#define AR71XX_CPU_DIV_MASK 0x3 ++#define AR71XX_DDR_DIV_SHIFT 18 ++#define AR71XX_DDR_DIV_MASK 0x3 ++#define AR71XX_AHB_DIV_SHIFT 20 ++#define AR71XX_AHB_DIV_MASK 0x7 + -+#define cpu_has_prefetch 1 -+#define cpu_has_ejtag 1 -+#define cpu_has_llsc 1 ++#define AR71XX_ETH0_PLL_SHIFT 17 ++#define AR71XX_ETH1_PLL_SHIFT 19 + -+#define cpu_has_mips16 1 -+#define cpu_has_mdmx 0 -+#define cpu_has_mips3d 0 -+#define cpu_has_smartmips 0 ++#define AR724X_PLL_REG_CPU_CONFIG 0x00 ++#define AR724X_PLL_REG_PCIE_CONFIG 0x18 + -+#define cpu_has_mips32r1 1 -+#define cpu_has_mips32r2 1 -+#define cpu_has_mips64r1 0 -+#define cpu_has_mips64r2 0 ++#define AR724X_PLL_DIV_SHIFT 0 ++#define AR724X_PLL_DIV_MASK 0x3ff ++#define AR724X_PLL_REF_DIV_SHIFT 10 ++#define AR724X_PLL_REF_DIV_MASK 0xf ++#define AR724X_AHB_DIV_SHIFT 19 ++#define AR724X_AHB_DIV_MASK 0x1 ++#define AR724X_DDR_DIV_SHIFT 22 ++#define AR724X_DDR_DIV_MASK 0x3 + -+#define cpu_has_dsp 0 -+#define cpu_has_mipsmt 0 ++#define AR7242_PLL_REG_ETH0_INT_CLOCK 0x2c + -+#define cpu_has_64bits 0 -+#define cpu_has_64bit_zero_reg 0 -+#define cpu_has_64bit_gp_regs 0 -+#define cpu_has_64bit_addresses 0 ++#define AR91XX_PLL_REG_CPU_CONFIG 0x00 ++#define AR91XX_PLL_REG_ETH_CONFIG 0x04 ++#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14 ++#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18 + -+#define cpu_dcache_line_size() 32 -+#define cpu_icache_line_size() 32 ++#define AR91XX_PLL_DIV_SHIFT 0 ++#define AR91XX_PLL_DIV_MASK 0x3ff ++#define AR91XX_DDR_DIV_SHIFT 22 ++#define AR91XX_DDR_DIV_MASK 0x3 ++#define AR91XX_AHB_DIV_SHIFT 19 ++#define AR91XX_AHB_DIV_MASK 0x1 + -+#endif /* __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h 2011-04-27 12:19:21.877661867 +0200 -@@ -0,0 +1,53 @@ -+/* -+ * Atheros AR71xx GPIO API definitions -+ * -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ ++#define AR91XX_ETH0_PLL_SHIFT 20 ++#define AR91XX_ETH1_PLL_SHIFT 22 + -+#ifndef __ASM_MACH_AR71XX_GPIO_H -+#define __ASM_MACH_AR71XX_GPIO_H ++#define AR933X_PLL_CPU_CONFIG_REG 0x00 ++#define AR933X_PLL_CLOCK_CTRL_REG 0x08 + -+#define ARCH_NR_GPIOS 64 -+#include ++#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT 10 ++#define AR933X_PLL_CPU_CONFIG_NINT_MASK 0x3f ++#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT 16 ++#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f ++#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT 23 ++#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7 + -+#include ++#define AR933X_PLL_CLOCK_CTRL_BYPASS BIT(2) ++#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT 5 ++#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK 0x3 ++#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT 10 ++#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK 0x3 ++#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15 ++#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7 + -+extern unsigned long ar71xx_gpio_count; -+extern void __ar71xx_gpio_set_value(unsigned gpio, int value); -+extern int __ar71xx_gpio_get_value(unsigned gpio); ++#define AR934X_PLL_REG_CPU_CONFIG 0x00 ++#define AR934X_PLL_REG_DDR_CTRL_CLOCK 0x8 + -+static inline int gpio_to_irq(unsigned gpio) -+{ -+ return AR71XX_GPIO_IRQ(gpio); -+} ++#define AR934X_CPU_PLL_CFG_OUTDIV_MSB 21 ++#define AR934X_CPU_PLL_CFG_OUTDIV_LSB 19 ++#define AR934X_CPU_PLL_CFG_OUTDIV_MASK 0x00380000 + -+static inline int irq_to_gpio(unsigned irq) -+{ -+ return irq - AR71XX_GPIO_IRQ_BASE; -+} ++#define AR934X_CPU_PLL_CFG_OUTDIV_GET(x) \ ++ (((x) & AR934X_CPU_PLL_CFG_OUTDIV_MASK) >> \ ++ AR934X_CPU_PLL_CFG_OUTDIV_LSB) + -+static inline int gpio_get_value(unsigned gpio) -+{ -+ if (gpio < ar71xx_gpio_count) -+ return __ar71xx_gpio_get_value(gpio); ++#define AR934X_DDR_PLL_CFG_OUTDIV_MSB 25 ++#define AR934X_DDR_PLL_CFG_OUTDIV_LSB 23 ++#define AR934X_DDR_PLL_CFG_OUTDIV_MASK 0x03800000 + -+ return __gpio_get_value(gpio); -+} ++#define AR934X_DDR_PLL_CFG_OUTDIV_GET(x) \ ++ (((x) & AR934X_DDR_PLL_CFG_OUTDIV_MASK) >> \ ++ AR934X_DDR_PLL_CFG_OUTDIV_LSB) + -+static inline void gpio_set_value(unsigned gpio, int value) -+{ -+ if (gpio < ar71xx_gpio_count) -+ __ar71xx_gpio_set_value(gpio, value); -+ else -+ __gpio_set_value(gpio, value); -+} ++#define AR934X_DDR_PLL_CFG_OUTDIV_SET(x) \ ++ (((x) << AR934X_DDR_PLL_CFG_OUTDIV_LSB) & \ ++ AR934X_DDR_PLL_CFG_OUTDIV_MASK) + -+#define gpio_cansleep __gpio_cansleep ++#define AR934X_CPU_PLL_CFG_REFDIV_MSB 16 ++#define AR934X_CPU_PLL_CFG_REFDIV_LSB 12 ++#define AR934X_CPU_PLL_CFG_REFDIV_MASK 0x0001f000 + -+#endif /* __ASM_MACH_AR71XX_GPIO_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h 2011-04-27 12:19:21.877661867 +0200 -@@ -0,0 +1,17 @@ -+/* -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#ifndef __ASM_MACH_AR71XX_IRQ_H -+#define __ASM_MACH_AR71XX_IRQ_H ++#define AR934X_CPU_PLL_CFG_REFDIV_GET(x) \ ++ (((x) & AR934X_CPU_PLL_CFG_REFDIV_MASK) >> \ ++ AR934X_CPU_PLL_CFG_REFDIV_LSB) + -+#define MIPS_CPU_IRQ_BASE 0 -+#define NR_IRQS 80 ++#define AR934X_CPU_PLL_CFG_REFDIV_SET(x) \ ++ (((x) << AR934X_CPU_PLL_CFG_REFDIV_LSB) & \ ++ AR934X_CPU_PLL_CFG_REFDIV_MASK) + -+#include_next ++#define AR934X_CPU_PLL_CFG_REFDIV_RESET 2 + -+#endif /* __ASM_MACH_AR71XX_IRQ_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 2011-04-27 12:19:21.877661867 +0200 -@@ -0,0 +1,32 @@ -+/* -+ * Atheros AR71xx specific kernel entry setup -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+#ifndef __ASM_MACH_AR71XX_KERNEL_ENTRY_H -+#define __ASM_MACH_AR71XX_KERNEL_ENTRY_H ++#define AR934X_CPU_PLL_CFG_NINT_MSB 11 ++#define AR934X_CPU_PLL_CFG_NINT_LSB 6 ++#define AR934X_CPU_PLL_CFG_NINT_MASK 0x00000fc0 + -+ /* -+ * Some bootloaders set the 'Kseg0 coherency algorithm' to -+ * 'Cacheable, noncoherent, write-through, no write allocate' -+ * and this cause performance issues. Let's go and change it to -+ * 'Cacheable, noncoherent, write-back, write allocate' -+ */ -+ .macro kernel_entry_setup -+ mfc0 t0, CP0_CONFIG -+ li t1, ~CONF_CM_CMASK -+ and t0, t1 -+ ori t0, CONF_CM_CACHABLE_NONCOHERENT -+ mtc0 t0, CP0_CONFIG -+ nop -+ .endm ++#define AR934X_CPU_PLL_CFG_NINT_GET(x) \ ++ (((x) & AR934X_CPU_PLL_CFG_NINT_MASK) >> \ ++ AR934X_CPU_PLL_CFG_NINT_LSB) + -+ .macro smp_slave_setup -+ .endm ++#define AR934X_CPU_PLL_CFG_NINT_SET(x) \ ++ (((x) << AR934X_CPU_PLL_CFG_NINT_LSB) & \ ++ AR934X_CPU_PLL_CFG_NINT_MASK) + -+#endif /* __ASM_MACH_AR71XX_KERNEL_ENTRY_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 2011-04-27 12:19:21.877661867 +0200 -@@ -0,0 +1,66 @@ -+/* -+ * MikroTik RouterBOARD 750 definitions -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#ifndef _MACH_RB750_H -+#define _MACH_RB750_H ++#define AR934X_CPU_PLL_CFG_NINT_RESET 20 + -+#include ++#define AR934X_CPU_PLL_CFG_NFRAC_MSB 5 ++#define AR934X_CPU_PLL_CFG_NFRAC_LSB 0 ++#define AR934X_CPU_PLL_CFG_NFRAC_MASK 0x0000003f + -+#define RB750_GPIO_LVC573_LE 0 /* Latch enable on LVC573 */ -+#define RB750_GPIO_NAND_IO0 1 /* NAND I/O 0 */ -+#define RB750_GPIO_NAND_IO1 2 /* NAND I/O 1 */ -+#define RB750_GPIO_NAND_IO2 3 /* NAND I/O 2 */ -+#define RB750_GPIO_NAND_IO3 4 /* NAND I/O 3 */ -+#define RB750_GPIO_NAND_IO4 5 /* NAND I/O 4 */ -+#define RB750_GPIO_NAND_IO5 6 /* NAND I/O 5 */ -+#define RB750_GPIO_NAND_IO6 7 /* NAND I/O 6 */ -+#define RB750_GPIO_NAND_IO7 8 /* NAND I/O 7 */ -+#define RB750_GPIO_NAND_NCE 11 /* NAND Chip Enable (active low) */ -+#define RB750_GPIO_NAND_RDY 12 /* NAND Ready */ -+#define RB750_GPIO_NAND_CLE 14 /* NAND Command Latch Enable */ -+#define RB750_GPIO_NAND_ALE 15 /* NAND Address Latch Enable */ -+#define RB750_GPIO_NAND_NRE 16 /* NAND Read Enable (active low) */ -+#define RB750_GPIO_NAND_NWE 17 /* NAND Write Enable (active low) */ ++#define AR934X_CPU_PLL_CFG_NFRAC_GET(x) \ ++ (((x) & AR934X_CPU_PLL_CFG_NFRAC_MASK) >> \ ++ AR934X_CPU_PLL_CFG_NFRAC_LSB) + -+#define RB750_GPIO_BTN_RESET 1 -+#define RB750_GPIO_SPI_CS0 2 -+#define RB750_GPIO_LED_ACT 12 -+#define RB750_GPIO_LED_PORT1 13 -+#define RB750_GPIO_LED_PORT2 14 -+#define RB750_GPIO_LED_PORT3 15 -+#define RB750_GPIO_LED_PORT4 16 -+#define RB750_GPIO_LED_PORT5 17 ++#define AR934X_CPU_PLL_CFG_NFRAC_SET(x) \ ++ (((x) << AR934X_CPU_PLL_CFG_NFRAC_LSB) & \ ++ AR934X_CPU_PLL_CFG_NFRAC_MASK) + -+#define RB750_LED_ACT BIT(RB750_GPIO_LED_ACT) -+#define RB750_LED_PORT1 BIT(RB750_GPIO_LED_PORT1) -+#define RB750_LED_PORT2 BIT(RB750_GPIO_LED_PORT2) -+#define RB750_LED_PORT3 BIT(RB750_GPIO_LED_PORT3) -+#define RB750_LED_PORT4 BIT(RB750_GPIO_LED_PORT4) -+#define RB750_LED_PORT5 BIT(RB750_GPIO_LED_PORT5) ++#define AR934X_DDR_PLL_CFG_REFDIV_MSB 20 ++#define AR934X_DDR_PLL_CFG_REFDIV_LSB 16 ++#define AR934X_DDR_PLL_CFG_REFDIV_MASK 0x001f0000 + -+#define RB750_LVC573_LE BIT(RB750_GPIO_LVC573_LE) ++#define AR934X_DDR_PLL_CFG_REFDIV_GET(x) \ ++ (((x) & AR934X_DDR_PLL_CFG_REFDIV_MASK) >> \ ++ AR934X_DDR_PLL_CFG_REFDIV_LSB) + -+#define RB750_LED_BITS (RB750_LED_PORT1 | RB750_LED_PORT2 | RB750_LED_PORT3 | \ -+ RB750_LED_PORT4 | RB750_LED_PORT5 | RB750_LED_ACT) ++#define AR934X_DDR_PLL_CFG_REFDIV_SET(x) \ ++ (((x) << AR934X_DDR_PLL_CFG_REFDIV_LSB) & \ ++ AR934X_DDR_PLL_CFG_REFDIV_MASK) + -+struct rb750_led_data { -+ char *name; -+ char *default_trigger; -+ u32 mask; -+ int active_low; -+}; ++#define AR934X_DDR_PLL_CFG_REFDIV_RESET 2 + -+struct rb750_led_platform_data { -+ int num_leds; -+ struct rb750_led_data *leds; -+}; -+ -+int rb750_latch_change(u32 mask_clr, u32 mask_set); -+ -+#endif /* _MACH_RB750_H */ -\ No newline at end of file -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h 2011-04-27 12:19:21.877661867 +0200 -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h -+ * Copyright (C) 2003, 2004 Ralf Baechle -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef __ASM_MACH_AR71XX_MANGLE_PORT_H -+#define __ASM_MACH_AR71XX_MANGLE_PORT_H ++#define AR934X_DDR_PLL_CFG_NINT_MSB 15 ++#define AR934X_DDR_PLL_CFG_NINT_LSB 10 ++#define AR934X_DDR_PLL_CFG_NINT_MASK 0x0000fc00 + -+#define __swizzle_addr_b(port) ((port) ^ 3) -+#define __swizzle_addr_w(port) ((port) ^ 2) -+#define __swizzle_addr_l(port) (port) -+#define __swizzle_addr_q(port) (port) ++#define AR934X_DDR_PLL_CFG_NINT_GET(x) \ ++ (((x) & AR934X_DDR_PLL_CFG_NINT_MASK) >> \ ++ AR934X_DDR_PLL_CFG_NINT_LSB) + -+#if defined(CONFIG_SWAP_IO_SPACE) ++#define AR934X_DDR_PLL_CFG_NINT_SET(x) \ ++ (((x) << AR934X_DDR_PLL_CFG_NINT_LSB) & \ ++ AR934X_DDR_PLL_CFG_NINT_MASK) + -+# define ioswabb(a, x) (x) -+# define __mem_ioswabb(a, x) (x) -+# define ioswabw(a, x) le16_to_cpu(x) -+# define __mem_ioswabw(a, x) (x) -+# define ioswabl(a, x) le32_to_cpu(x) -+# define __mem_ioswabl(a, x) (x) -+# define ioswabq(a, x) le64_to_cpu(x) -+# define __mem_ioswabq(a, x) (x) ++#define AR934X_DDR_PLL_CFG_NINT_RESET 20 + -+#else ++#define AR934X_DDR_PLL_CFG_NFRAC_MSB 9 ++#define AR934X_DDR_PLL_CFG_NFRAC_LSB 0 ++#define AR934X_DDR_PLL_CFG_NFRAC_MASK 0x000003ff + -+# define ioswabb(a, x) (x) -+# define __mem_ioswabb(a, x) (x) -+# define ioswabw(a, x) (x) -+# define __mem_ioswabw(a, x) cpu_to_le16(x) -+# define ioswabl(a, x) (x) -+# define __mem_ioswabl(a, x) cpu_to_le32(x) -+# define ioswabq(a, x) (x) -+# define __mem_ioswabq(a, x) cpu_to_le64(x) ++#define AR934X_DDR_PLL_CFG_NFRAC_GET(x) \ ++ (((x) & AR934X_DDR_PLL_CFG_NFRAC_MASK) >> \ ++ AR934X_DDR_PLL_CFG_NFRAC_LSB) + -+#endif ++#define AR934X_DDR_PLL_CFG_NFRAC_SET(x) \ ++ (((x) << AR934X_DDR_PLL_CFG_NFRAC_LSB) & \ ++ AR934X_DDR_PLL_CFG_NFRAC_MASK) + -+#endif /* __ASM_MACH_AR71XX_MANGLE_PORT_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h 2011-04-27 12:19:21.877661867 +0200 -@@ -0,0 +1,46 @@ -+/* -+ * Atheros AR71xx SoC specific PCI definitions -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++#define AR934X_DDR_PLL_CFG_NFRAC_RESET 512 + -+#ifndef __ASM_MACH_AR71XX_PCI_H -+#define __ASM_MACH_AR71XX_PCI_H ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MSB 19 ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB 15 ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x000f8000 + -+struct pci_dev; ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_GET(x) \ ++ (((x) & AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK) >> \ ++ AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB) + -+struct ar71xx_pci_irq { -+ int irq; -+ u8 slot; -+ u8 pin; -+}; ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SET(x) \ ++ (((x) << AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_LSB) & \ ++ AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK) + -+#ifdef CONFIG_PCI -+extern int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev); -+extern unsigned ar71xx_pci_nr_irqs __initdata; -+extern struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata; ++#define AR934X_CPU_DDR_CLK_CTRL_AHB_POST_DIV_RESET 0 + -+int ar71xx_pcibios_map_irq(const struct pci_dev *dev, -+ uint8_t slot, uint8_t pin) __init; -+int ar71xx_pcibios_init(void) __init; ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MSB 14 ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB 10 ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x00007c00 + -+int ar71xx_pci_be_handler(int is_fixup); ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_GET(x) \ ++ (((x) & AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK) >> \ ++ AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB) + -+int ar724x_pcibios_map_irq(const struct pci_dev *dev, -+ uint8_t slot, uint8_t pin) __init; -+int ar724x_pcibios_init(void) __init; ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SET(x) \ ++ (((x) << AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_LSB) & \ ++ AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK) + -+int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) __init; -+#else -+static inline int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) -+{ -+ return 0; -+} -+#endif ++#define AR934X_CPU_DDR_CLK_CTRL_DDR_POST_DIV_RESET 0 + -+#endif /* __ASM_MACH_AR71XX_PCI_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h 2011-08-22 07:40:11.890481646 +0200 -@@ -0,0 +1,63 @@ -+/* -+ * Atheros AR71xx SoC specific platform data definitions -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MSB 9 ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB 5 ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x000003e0 + -+#ifndef __ASM_MACH_AR71XX_PLATFORM_H -+#define __ASM_MACH_AR71XX_PLATFORM_H ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_GET(x) \ ++ (((x) & AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK) >> \ ++ AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB) + -+#include -+#include -+#include -+#include ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SET(x) \ ++ (((x) << AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_LSB) & \ ++ AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK) + -+struct ag71xx_platform_data { -+ phy_interface_t phy_if_mode; -+ u32 phy_mask; -+ int speed; -+ int duplex; -+ u32 reset_bit; -+ u32 mii_if; -+ u8 mac_addr[ETH_ALEN]; -+ struct device *mii_bus_dev; ++#define AR934X_CPU_DDR_CLK_CTRL_CPU_POST_DIV_RESET 0 + -+ u8 has_gbit:1; -+ u8 is_ar91xx:1; -+ u8 is_ar7240:1; -+ u8 is_ar724x:1; -+ u8 has_ar8216:1; -+ u8 has_ar7240_switch:1; ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MSB 24 ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB 24 ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK 0x01000000 + -+ void (*ddr_flush)(void); -+ void (*set_pll)(int speed); ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_GET(x) \ ++ (((x) & AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK) >> \ ++ AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB) + -+ u32 fifo_cfg1; -+ u32 fifo_cfg2; -+ u32 fifo_cfg3; -+}; ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_SET(x) \ ++ (((x) << AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_LSB) & \ ++ AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_MASK) + -+struct ag71xx_mdio_platform_data { -+ u32 phy_mask; -+ int is_ar7240; -+}; ++#define AR934X_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL_RESET 1 + -+struct ar71xx_ehci_platform_data { -+ u8 is_ar91xx; -+}; ++extern void __iomem *ar71xx_pll_base; + -+struct ar71xx_spi_platform_data { -+ unsigned bus_num; -+ unsigned num_chipselect; -+ u32 (*get_ioc_base)(u8 chip_select, int cs_high, int is_on); -+}; ++static inline void ar71xx_pll_wr(unsigned reg, u32 val) ++{ ++ __raw_writel(val, ar71xx_pll_base + reg); ++} + -+#define AR71XX_SPI_CS_INACTIVE 0 -+#define AR71XX_SPI_CS_ACTIVE 1 ++static inline u32 ar71xx_pll_rr(unsigned reg) ++{ ++ return __raw_readl(ar71xx_pll_base + reg); ++} + -+#endif /* __ASM_MACH_AR71XX_PLATFORM_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h 2011-04-27 12:19:21.867661560 +0200 -@@ -0,0 +1,48 @@ +/* -+ * SPI driver definitions for the CPLD chip on the Mikrotik RB4xx boards -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This file was based on the patches for Linux 2.6.27.39 published by -+ * MikroTik for their RouterBoard 4xx series devices. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. ++ * USB_CONFIG block + */ ++#define USB_CTRL_REG_FLADJ 0x00 ++#define USB_CTRL_REG_CONFIG 0x04 + -+#define CPLD_GPIO_nLED1 0 -+#define CPLD_GPIO_nLED2 1 -+#define CPLD_GPIO_nLED3 2 -+#define CPLD_GPIO_nLED4 3 -+#define CPLD_GPIO_FAN 4 -+#define CPLD_GPIO_ALE 5 -+#define CPLD_GPIO_CLE 6 -+#define CPLD_GPIO_nCE 7 -+#define CPLD_GPIO_nLED5 8 ++extern void __iomem *ar71xx_usb_ctrl_base; + -+#define CPLD_NUM_GPIOS 9 ++static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val) ++{ ++ __raw_writel(val, ar71xx_usb_ctrl_base + reg); ++} + -+#define CPLD_CFG_nLED1 BIT(CPLD_GPIO_nLED1) -+#define CPLD_CFG_nLED2 BIT(CPLD_GPIO_nLED2) -+#define CPLD_CFG_nLED3 BIT(CPLD_GPIO_nLED3) -+#define CPLD_CFG_nLED4 BIT(CPLD_GPIO_nLED4) -+#define CPLD_CFG_FAN BIT(CPLD_GPIO_FAN) -+#define CPLD_CFG_ALE BIT(CPLD_GPIO_ALE) -+#define CPLD_CFG_CLE BIT(CPLD_GPIO_CLE) -+#define CPLD_CFG_nCE BIT(CPLD_GPIO_nCE) -+#define CPLD_CFG_nLED5 BIT(CPLD_GPIO_nLED5) ++static inline u32 ar71xx_usb_ctrl_rr(unsigned reg) ++{ ++ return __raw_readl(ar71xx_usb_ctrl_base + reg); ++} + -+struct rb4xx_cpld_platform_data { -+ unsigned gpio_base; -+}; -+ -+extern int rb4xx_cpld_change_cfg(unsigned mask, unsigned value); -+extern int rb4xx_cpld_read(unsigned char *rx_buf, -+ const unsigned char *verify_buf, -+ unsigned cnt); -+extern int rb4xx_cpld_read_from(unsigned addr, -+ unsigned char *rx_buf, -+ const unsigned char *verify_buf, -+ unsigned cnt); -+extern int rb4xx_cpld_write(const unsigned char *buf, unsigned count); -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h ---- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h 2011-04-27 12:19:21.867661560 +0200 -@@ -0,0 +1,25 @@ +/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle ++ * GPIO block + */ -+#ifndef __ASM_MACH_AR71XX_WAR_H -+#define __ASM_MACH_AR71XX_WAR_H ++#define GPIO_REG_OE 0x00 ++#define GPIO_REG_IN 0x04 ++#define GPIO_REG_OUT 0x08 ++#define GPIO_REG_SET 0x0c ++#define GPIO_REG_CLEAR 0x10 ++#define GPIO_REG_INT_MODE 0x14 ++#define GPIO_REG_INT_TYPE 0x18 ++#define GPIO_REG_INT_POLARITY 0x1c ++#define GPIO_REG_INT_PENDING 0x20 ++#define GPIO_REG_INT_ENABLE 0x24 ++#define GPIO_REG_FUNC 0x28 + -+#define R4600_V1_INDEX_ICACHEOP_WAR 0 -+#define R4600_V1_HIT_CACHEOP_WAR 0 -+#define R4600_V2_HIT_CACHEOP_WAR 0 -+#define R5432_CP0_INTERRUPT_WAR 0 -+#define BCM1250_M3_WAR 0 -+#define SIBYTE_1956_WAR 0 -+#define MIPS4K_ICACHE_REFILL_WAR 0 -+#define MIPS_CACHE_SYNC_WAR 0 -+#define TX49XX_ICACHE_INDEX_INV_WAR 0 -+#define RM9000_CDEX_SMP_WAR 0 -+#define ICACHE_REFILLS_WORKAROUND_WAR 0 -+#define R10000_LLSC_WAR 0 -+#define MIPS34K_MISSED_ITLB_WAR 0 ++#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17) ++#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16) ++#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13) ++#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12) ++#define AR71XX_GPIO_FUNC_UART_EN BIT(8) ++#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4) ++#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0) + -+#endif /* __ASM_MACH_AR71XX_WAR_H */ -diff -Nur linux-2.6.39.orig/arch/mips/include/asm/time.h linux-2.6.39/arch/mips/include/asm/time.h ---- linux-2.6.39.orig/arch/mips/include/asm/time.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/include/asm/time.h 2011-08-24 05:53:05.239228886 +0200 -@@ -52,6 +52,7 @@ - */ - #ifdef CONFIG_CEVT_R4K_LIB - extern unsigned int __weak get_c0_compare_int(void); -+extern unsigned int __weak get_c0_compare_irq(void); - extern int r4k_clockevent_init(void); - #endif - -diff -Nur linux-2.6.39.orig/arch/mips/Kconfig linux-2.6.39/arch/mips/Kconfig ---- linux-2.6.39.orig/arch/mips/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/Kconfig 2011-08-24 02:42:39.969240338 +0200 -@@ -84,6 +84,23 @@ - help - Support for the Atheros AR71XX/AR724X/AR913X SoCs. - -+config ATHEROS_AR71XX -+ bool "Atheros AR71xx based boards" -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select HW_HAS_PCI -+ select IRQ_CPU -+ select ARCH_REQUIRE_GPIOLIB -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_HAS_CPU_MIPS32_R2 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_HAS_EARLY_PRINTK -+ select MIPS_MACHINE -+ help -+ Support for Atheros AR71xx based boards. ++#define AR71XX_GPIO_COUNT 16 + - config BCM47XX - bool "Broadcom BCM47XX based boards" - select CEVT_R4K -@@ -739,6 +756,7 @@ - endchoice - - source "arch/mips/alchemy/Kconfig" -+source "arch/mips/ar71xx/Kconfig" - source "arch/mips/ath79/Kconfig" - source "arch/mips/bcm63xx/Kconfig" - source "arch/mips/jazz/Kconfig" -@@ -907,6 +925,9 @@ - config MIPS_DISABLE_OBSOLETE_IDE - bool - -+config MYLOADER -+ bool ++#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19) ++#define AR724X_GPIO_FUNC_SPI_EN BIT(18) ++#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14) ++#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13) ++#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12) ++#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11) ++#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10) ++#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9) ++#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) ++#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) ++#define AR724X_GPIO_FUNC_UART_EN BIT(1) ++#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0) + - config SYNC_R4K - bool - -diff -Nur linux-2.6.39.orig/arch/mips/Kconfig.orig linux-2.6.39/arch/mips/Kconfig.orig ---- linux-2.6.39.orig/arch/mips/Kconfig.orig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/Kconfig.orig 2011-08-22 16:21:32.077979816 +0200 -@@ -0,0 +1,2472 @@ -+config MIPS -+ bool -+ default y -+ select HAVE_GENERIC_DMA_COHERENT -+ select HAVE_IDE -+ select HAVE_OPROFILE -+ select HAVE_IRQ_WORK -+ select HAVE_PERF_EVENTS -+ select PERF_USE_VMALLOC -+ select HAVE_ARCH_KGDB -+ select HAVE_FUNCTION_TRACER -+ select HAVE_FUNCTION_TRACE_MCOUNT_TEST -+ select HAVE_DYNAMIC_FTRACE -+ select HAVE_FTRACE_MCOUNT_RECORD -+ select HAVE_C_RECORDMCOUNT -+ select HAVE_FUNCTION_GRAPH_TRACER -+ select HAVE_KPROBES -+ select HAVE_KRETPROBES -+ select RTC_LIB if !MACH_LOONGSON -+ select GENERIC_ATOMIC64 if !64BIT -+ select HAVE_DMA_ATTRS -+ select HAVE_DMA_API_DEBUG -+ select HAVE_GENERIC_HARDIRQS -+ select GENERIC_IRQ_PROBE -+ select GENERIC_IRQ_SHOW -+ select HAVE_ARCH_JUMP_LABEL -+ -+menu "Machine selection" -+ -+config ZONE_DMA -+ bool ++#define AR724X_GPIO_COUNT 18 + -+choice -+ prompt "System type" -+ default SGI_IP22 ++#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22) ++#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21) ++#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20) ++#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19) ++#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18) ++#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17) ++#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16) ++#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9) ++#define AR91XX_GPIO_FUNC_UART_EN BIT(8) ++#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4) + -+config MIPS_ALCHEMY -+ bool "Alchemy processor based machines" -+ select 64BIT_PHYS_ADDR -+ select CEVT_R4K_LIB -+ select CSRC_R4K_LIB -+ select IRQ_CPU -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_APM_EMULATION -+ select GENERIC_GPIO -+ select ARCH_WANT_OPTIONAL_GPIOLIB -+ select SYS_SUPPORTS_ZBOOT -+ -+config AR7 -+ bool "Texas Instruments AR7" -+ select BOOT_ELF32 -+ select DMA_NONCOHERENT -+ select CEVT_R4K -+ select CSRC_R4K -+ select IRQ_CPU -+ select NO_EXCEPT_FILL -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select SYS_SUPPORTS_ZBOOT_UART16550 -+ select ARCH_REQUIRE_GPIOLIB -+ select GCD -+ select VLYNQ -+ help -+ Support for the Texas Instruments AR7 System-on-a-Chip -+ family: TNETD7100, 7200 and 7300. ++#define AR91XX_GPIO_COUNT 22 + -+config ATH79 -+ bool "Atheros AR71XX/AR724X/AR913X based boards" -+ select ARCH_REQUIRE_GPIOLIB -+ select BOOT_RAW -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select IRQ_CPU -+ select MIPS_MACHINE -+ select SYS_HAS_CPU_MIPS32_R2 -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ help -+ Support for the Atheros AR71XX/AR724X/AR913X SoCs. ++#define AR933X_GPIO_COUNT 30 + -+config ATHEROS_AR71XX -+ bool "Atheros AR71xx based boards" -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select HW_HAS_PCI -+ select IRQ_CPU -+ select ARCH_REQUIRE_GPIOLIB -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_HAS_CPU_MIPS32_R2 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_HAS_EARLY_PRINTK -+ select MIPS_MACHINE -+ help -+ Support for Atheros AR71xx based boards. ++#define AR934X_GPIO_FUNC_SPI_CS_1_EN BIT(14) ++#define AR934X_GPIO_FUNC_SPI_CS_0_EN BIT(13) + -+config BCM47XX -+ bool "Broadcom BCM47XX based boards" -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select HW_HAS_PCI -+ select IRQ_CPU -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select SSB -+ select SSB_DRIVER_MIPS -+ select SSB_DRIVER_EXTIF -+ select SSB_EMBEDDED -+ select SSB_B43_PCI_BRIDGE if PCI -+ select SSB_PCICORE_HOSTMODE if PCI -+ select GENERIC_GPIO -+ select SYS_HAS_EARLY_PRINTK -+ select CFE -+ help -+ Support for BCM47XX based boards ++#define AR934X_GPIO_COUNT 32 ++#define AR934X_GPIO_FUNC_DDR_DQOE_EN BIT(17) + -+config BCM63XX -+ bool "Broadcom BCM63XX based boards" -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select IRQ_CPU -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_HAS_EARLY_PRINTK -+ select SWAP_IO_SPACE -+ select ARCH_REQUIRE_GPIOLIB -+ help -+ Support for BCM63XX based boards ++extern void __iomem *ar71xx_gpio_base; + -+config MIPS_COBALT -+ bool "Cobalt Server" -+ select CEVT_R4K -+ select CSRC_R4K -+ select CEVT_GT641XX -+ select DMA_NONCOHERENT -+ select HW_HAS_PCI -+ select I8253 -+ select I8259 -+ select IRQ_CPU -+ select IRQ_GT641XX -+ select PCI_GT64XXX_PCI0 -+ select PCI -+ select SYS_HAS_CPU_NEVADA -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_LITTLE_ENDIAN ++static inline void ar71xx_gpio_wr(unsigned reg, u32 value) ++{ ++ __raw_writel(value, ar71xx_gpio_base + reg); ++} + -+config MACH_DECSTATION -+ bool "DECstations" -+ select BOOT_ELF32 -+ select CEVT_DS1287 -+ select CEVT_R4K -+ select CSRC_IOASIC -+ select CSRC_R4K -+ select CPU_DADDI_WORKAROUNDS if 64BIT -+ select CPU_R4000_WORKAROUNDS if 64BIT -+ select CPU_R4400_WORKAROUNDS if 64BIT -+ select DMA_NONCOHERENT -+ select NO_IOPORT -+ select IRQ_CPU -+ select SYS_HAS_CPU_R3000 -+ select SYS_HAS_CPU_R4X00 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select SYS_SUPPORTS_128HZ -+ select SYS_SUPPORTS_256HZ -+ select SYS_SUPPORTS_1024HZ -+ help -+ This enables support for DEC's MIPS based workstations. For details -+ see the Linux/MIPS FAQ on and the -+ DECstation porting pages on . ++static inline u32 ar71xx_gpio_rr(unsigned reg) ++{ ++ return __raw_readl(ar71xx_gpio_base + reg); ++} + -+ If you have one of the following DECstation Models you definitely -+ want to choose R4xx0 for the CPU Type: ++void ar71xx_gpio_init(void) __init; ++void ar71xx_gpio_function_enable(u32 mask); ++void ar71xx_gpio_function_disable(u32 mask); ++void ar71xx_gpio_function_setup(u32 set, u32 clear); + -+ DECstation 5000/50 -+ DECstation 5000/150 -+ DECstation 5000/260 -+ DECsystem 5900/260 ++/* ++ * DDR_CTRL block ++ */ ++#define AR71XX_DDR_REG_PCI_WIN0 0x7c ++#define AR71XX_DDR_REG_PCI_WIN1 0x80 ++#define AR71XX_DDR_REG_PCI_WIN2 0x84 ++#define AR71XX_DDR_REG_PCI_WIN3 0x88 ++#define AR71XX_DDR_REG_PCI_WIN4 0x8c ++#define AR71XX_DDR_REG_PCI_WIN5 0x90 ++#define AR71XX_DDR_REG_PCI_WIN6 0x94 ++#define AR71XX_DDR_REG_PCI_WIN7 0x98 ++#define AR71XX_DDR_REG_FLUSH_GE0 0x9c ++#define AR71XX_DDR_REG_FLUSH_GE1 0xa0 ++#define AR71XX_DDR_REG_FLUSH_USB 0xa4 ++#define AR71XX_DDR_REG_FLUSH_PCI 0xa8 + -+ otherwise choose R3000. ++#define AR724X_DDR_REG_FLUSH_GE0 0x7c ++#define AR724X_DDR_REG_FLUSH_GE1 0x80 ++#define AR724X_DDR_REG_FLUSH_USB 0x84 ++#define AR724X_DDR_REG_FLUSH_PCIE 0x88 + -+config MACH_JAZZ -+ bool "Jazz family of machines" -+ select ARC -+ select ARC32 -+ select ARCH_MAY_HAVE_PC_FDC -+ select CEVT_R4K -+ select CSRC_R4K -+ select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN -+ select GENERIC_ISA_DMA -+ select IRQ_CPU -+ select I8253 -+ select I8259 -+ select ISA -+ select SYS_HAS_CPU_R4X00 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL -+ select SYS_SUPPORTS_100HZ -+ help -+ This a family of machines based on the MIPS R4030 chipset which was -+ used by several vendors to build RISC/os and Windows NT workstations. -+ Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and -+ Olivetti M700-10 workstations. ++#define AR91XX_DDR_REG_FLUSH_GE0 0x7c ++#define AR91XX_DDR_REG_FLUSH_GE1 0x80 ++#define AR91XX_DDR_REG_FLUSH_USB 0x84 ++#define AR91XX_DDR_REG_FLUSH_WMAC 0x88 + -+config MACH_JZ4740 -+ bool "Ingenic JZ4740 based machines" -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select DMA_NONCOHERENT -+ select IRQ_CPU -+ select GENERIC_GPIO -+ select ARCH_REQUIRE_GPIOLIB -+ select SYS_HAS_EARLY_PRINTK -+ select HAVE_PWM -+ select HAVE_CLK ++#define AR933X_DDR_REG_FLUSH_GE0 0x7c ++#define AR933X_DDR_REG_FLUSH_GE1 0x80 ++#define AR933X_DDR_REG_FLUSH_USB 0x84 ++#define AR933X_DDR_REG_FLUSH_WMAC 0x88 + -+config LASAT -+ bool "LASAT Networks platforms" -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select SYS_HAS_EARLY_PRINTK -+ select HW_HAS_PCI -+ select IRQ_CPU -+ select PCI_GT64XXX_PCI0 -+ select MIPS_NILE4 -+ select R5000_CPU_SCACHE -+ select SYS_HAS_CPU_R5000 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_64BIT_KERNEL if BROKEN -+ select SYS_SUPPORTS_LITTLE_ENDIAN ++#define AR934X_DDR_REG_FLUSH_GE0 0x9c ++#define AR934X_DDR_REG_FLUSH_GE1 0xa0 ++#define AR934X_DDR_REG_FLUSH_USB 0xa4 ++#define AR934X_DDR_REG_FLUSH_PCIE 0xa8 + -+config MACH_LOONGSON -+ bool "Loongson family of machines" -+ select SYS_SUPPORTS_ZBOOT -+ help -+ This enables the support of Loongson family of machines. -+ -+ Loongson is a family of general-purpose MIPS-compatible CPUs. -+ developed at Institute of Computing Technology (ICT), -+ Chinese Academy of Sciences (CAS) in the People's Republic -+ of China. The chief architect is Professor Weiwu Hu. -+ -+config MIPS_MALTA -+ bool "MIPS Malta board" -+ select ARCH_MAY_HAVE_PC_FDC -+ select BOOT_ELF32 -+ select BOOT_RAW -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select GENERIC_ISA_DMA -+ select IRQ_CPU -+ select IRQ_GIC -+ select HW_HAS_PCI -+ select I8253 -+ select I8259 -+ select MIPS_BOARDS_GEN -+ select MIPS_BONITO64 -+ select MIPS_CPU_SCACHE -+ select PCI_GT64XXX_PCI0 -+ select MIPS_MSC -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_HAS_CPU_MIPS32_R2 -+ select SYS_HAS_CPU_MIPS64_R1 -+ select SYS_HAS_CPU_NEVADA -+ select SYS_HAS_CPU_RM7000 -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select SYS_SUPPORTS_MIPS_CMP -+ select SYS_SUPPORTS_MULTITHREADING -+ select SYS_SUPPORTS_SMARTMIPS -+ select SYS_SUPPORTS_ZBOOT -+ help -+ This enables support for the MIPS Technologies Malta evaluation -+ board. + -+config MIPS_SIM -+ bool 'MIPS simulator (MIPSsim)' -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select SYS_HAS_EARLY_PRINTK -+ select IRQ_CPU -+ select BOOT_RAW -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_HAS_CPU_MIPS32_R2 -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_MULTITHREADING -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ help -+ This option enables support for MIPS Technologies MIPSsim software -+ emulator. ++#define PCI_WIN0_OFFS 0x10000000 ++#define PCI_WIN1_OFFS 0x11000000 ++#define PCI_WIN2_OFFS 0x12000000 ++#define PCI_WIN3_OFFS 0x13000000 ++#define PCI_WIN4_OFFS 0x14000000 ++#define PCI_WIN5_OFFS 0x15000000 ++#define PCI_WIN6_OFFS 0x16000000 ++#define PCI_WIN7_OFFS 0x07000000 + -+config NEC_MARKEINS -+ bool "NEC EMMA2RH Mark-eins board" -+ select SOC_EMMA2RH -+ select HW_HAS_PCI -+ help -+ This enables support for the NEC Electronics Mark-eins boards. ++extern void __iomem *ar71xx_ddr_base; + -+config MACH_VR41XX -+ bool "NEC VR4100 series based machines" -+ select CEVT_R4K -+ select CSRC_R4K -+ select SYS_HAS_CPU_VR41XX -+ select ARCH_REQUIRE_GPIOLIB ++static inline void ar71xx_ddr_wr(unsigned reg, u32 val) ++{ ++ __raw_writel(val, ar71xx_ddr_base + reg); ++} + -+config NXP_STB220 -+ bool "NXP STB220 board" -+ select SOC_PNX833X -+ help -+ Support for NXP Semiconductors STB220 Development Board. ++static inline u32 ar71xx_ddr_rr(unsigned reg) ++{ ++ return __raw_readl(ar71xx_ddr_base + reg); ++} + -+config NXP_STB225 -+ bool "NXP 225 board" -+ select SOC_PNX833X -+ select SOC_PNX8335 -+ help -+ Support for NXP Semiconductors STB225 Development Board. ++void ar71xx_ddr_flush(u32 reg); + -+config PNX8550_JBS -+ bool "NXP PNX8550 based JBS board" -+ select PNX8550 -+ select SYS_SUPPORTS_LITTLE_ENDIAN ++/* ++ * PCI block ++ */ ++#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000) ++#define AR71XX_PCI_CFG_SIZE 0x100 + -+config PNX8550_STB810 -+ bool "NXP PNX8550 based STB810 board" -+ select PNX8550 -+ select SYS_SUPPORTS_LITTLE_ENDIAN ++#define PCI_REG_CRP_AD_CBE 0x00 ++#define PCI_REG_CRP_WRDATA 0x04 ++#define PCI_REG_CRP_RDDATA 0x08 ++#define PCI_REG_CFG_AD 0x0c ++#define PCI_REG_CFG_CBE 0x10 ++#define PCI_REG_CFG_WRDATA 0x14 ++#define PCI_REG_CFG_RDDATA 0x18 ++#define PCI_REG_PCI_ERR 0x1c ++#define PCI_REG_PCI_ERR_ADDR 0x20 ++#define PCI_REG_AHB_ERR 0x24 ++#define PCI_REG_AHB_ERR_ADDR 0x28 + -+config PMC_MSP -+ bool "PMC-Sierra MSP chipsets" -+ depends on EXPERIMENTAL -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select SWAP_IO_SPACE -+ select NO_EXCEPT_FILL -+ select BOOT_RAW -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_HAS_CPU_MIPS32_R2 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select IRQ_CPU -+ select SERIAL_8250 -+ select SERIAL_8250_CONSOLE -+ help -+ This adds support for the PMC-Sierra family of Multi-Service -+ Processor System-On-A-Chips. These parts include a number -+ of integrated peripherals, interfaces and DSPs in addition to -+ a variety of MIPS cores. ++#define PCI_CRP_CMD_WRITE 0x00010000 ++#define PCI_CRP_CMD_READ 0x00000000 ++#define PCI_CFG_CMD_READ 0x0000000a ++#define PCI_CFG_CMD_WRITE 0x0000000b + -+config PMC_YOSEMITE -+ bool "PMC-Sierra Yosemite eval board" -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_COHERENT -+ select HW_HAS_PCI -+ select IRQ_CPU -+ select IRQ_CPU_RM7K -+ select IRQ_CPU_RM9K -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_RM9000 -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_HIGHMEM -+ select SYS_SUPPORTS_SMP -+ help -+ Yosemite is an evaluation board for the RM9000x2 processor -+ manufactured by PMC-Sierra. ++#define PCI_IDSEL_ADL_START 17 + -+config POWERTV -+ bool "Cisco PowerTV" -+ select BOOT_ELF32 -+ select CEVT_R4K -+ select CPU_MIPSR2_IRQ_VI -+ select CPU_MIPSR2_IRQ_EI -+ select CSRC_POWERTV -+ select DMA_NONCOHERENT -+ select HW_HAS_PCI -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_HAS_CPU_MIPS32_R2 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_HIGHMEM -+ select USB_OHCI_LITTLE_ENDIAN -+ help -+ This enables support for the Cisco PowerTV Platform. ++#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000) ++#define AR724X_PCI_CFG_SIZE 0x1000 + -+config SGI_IP22 -+ bool "SGI IP22 (Indy/Indigo2)" -+ select ARC -+ select ARC32 -+ select BOOT_ELF32 -+ select CEVT_R4K -+ select CSRC_R4K -+ select DEFAULT_SGI_PARTITION -+ select DMA_NONCOHERENT -+ select HW_HAS_EISA -+ select I8253 -+ select I8259 -+ select IP22_CPU_SCACHE -+ select IRQ_CPU -+ select GENERIC_ISA_DMA_SUPPORT_BROKEN -+ select SGI_HAS_I8042 -+ select SGI_HAS_INDYDOG -+ select SGI_HAS_HAL2 -+ select SGI_HAS_SEEQ -+ select SGI_HAS_WD93 -+ select SGI_HAS_ZILOG -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_R4X00 -+ select SYS_HAS_CPU_R5000 -+ # -+ # Disable EARLY_PRINTK for now since it leads to overwritten prom -+ # memory during early boot on some machines. -+ # -+ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com -+ # for a more details discussion -+ # -+ # select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ help -+ This are the SGI Indy, Challenge S and Indigo2, as well as certain -+ OEM variants like the Tandem CMN B006S. To compile a Linux kernel -+ that runs on these, say Y here. -+ -+config SGI_IP27 -+ bool "SGI IP27 (Origin200/2000)" -+ select ARC -+ select ARC64 -+ select BOOT_ELF64 -+ select DEFAULT_SGI_PARTITION -+ select DMA_COHERENT -+ select SYS_HAS_EARLY_PRINTK -+ select HW_HAS_PCI -+ select NR_CPUS_DEFAULT_64 -+ select SYS_HAS_CPU_R10000 -+ select SYS_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_NUMA -+ select SYS_SUPPORTS_SMP -+ help -+ This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics -+ workstations. To compile a Linux kernel that runs on these, say Y -+ here. -+ -+config SGI_IP28 -+ bool "SGI IP28 (Indigo2 R10k) (EXPERIMENTAL)" -+ depends on EXPERIMENTAL -+ select ARC -+ select ARC64 -+ select BOOT_ELF64 -+ select CEVT_R4K -+ select CSRC_R4K -+ select DEFAULT_SGI_PARTITION -+ select DMA_NONCOHERENT -+ select GENERIC_ISA_DMA_SUPPORT_BROKEN -+ select IRQ_CPU -+ select HW_HAS_EISA -+ select I8253 -+ select I8259 -+ select SGI_HAS_I8042 -+ select SGI_HAS_INDYDOG -+ select SGI_HAS_HAL2 -+ select SGI_HAS_SEEQ -+ select SGI_HAS_WD93 -+ select SGI_HAS_ZILOG -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_R10000 -+ # -+ # Disable EARLY_PRINTK for now since it leads to overwritten prom -+ # memory during early boot on some machines. -+ # -+ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com -+ # for a more details discussion -+ # -+ # select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ help -+ This is the SGI Indigo2 with R10000 processor. To compile a Linux -+ kernel that runs on these, say Y here. -+ -+config SGI_IP32 -+ bool "SGI IP32 (O2)" -+ select ARC -+ select ARC32 -+ select BOOT_ELF32 -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select HW_HAS_PCI -+ select IRQ_CPU -+ select R5000_CPU_SCACHE -+ select RM7000_CPU_SCACHE -+ select SYS_HAS_CPU_R5000 -+ select SYS_HAS_CPU_R10000 if BROKEN -+ select SYS_HAS_CPU_RM7000 -+ select SYS_HAS_CPU_NEVADA -+ select SYS_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ help -+ If you want this kernel to run on SGI O2 workstation, say Y here. -+ -+config SIBYTE_CRHINE -+ bool "Sibyte BCM91120C-CRhine" -+ depends on EXPERIMENTAL -+ select BOOT_ELF32 -+ select DMA_COHERENT -+ select SIBYTE_BCM1120 -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_SB1 -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ -+config SIBYTE_CARMEL -+ bool "Sibyte BCM91120x-Carmel" -+ depends on EXPERIMENTAL -+ select BOOT_ELF32 -+ select DMA_COHERENT -+ select SIBYTE_BCM1120 -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_SB1 -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ -+config SIBYTE_CRHONE -+ bool "Sibyte BCM91125C-CRhone" -+ depends on EXPERIMENTAL -+ select BOOT_ELF32 -+ select DMA_COHERENT -+ select SIBYTE_BCM1125 -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_SB1 -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_HIGHMEM -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ -+config SIBYTE_RHONE -+ bool "Sibyte BCM91125E-Rhone" -+ depends on EXPERIMENTAL -+ select BOOT_ELF32 -+ select DMA_COHERENT -+ select SIBYTE_BCM1125H -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_SB1 -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ -+config SIBYTE_SWARM -+ bool "Sibyte BCM91250A-SWARM" -+ select BOOT_ELF32 -+ select DMA_COHERENT -+ select HAVE_PATA_PLATFORM -+ select NR_CPUS_DEFAULT_2 -+ select SIBYTE_SB1250 -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_SB1 -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_HIGHMEM -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select ZONE_DMA32 if 64BIT -+ -+config SIBYTE_LITTLESUR -+ bool "Sibyte BCM91250C2-LittleSur" -+ depends on EXPERIMENTAL -+ select BOOT_ELF32 -+ select DMA_COHERENT -+ select HAVE_PATA_PLATFORM -+ select NR_CPUS_DEFAULT_2 -+ select SIBYTE_SB1250 -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_SB1 -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_HIGHMEM -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ -+config SIBYTE_SENTOSA -+ bool "Sibyte BCM91250E-Sentosa" -+ depends on EXPERIMENTAL -+ select BOOT_ELF32 -+ select DMA_COHERENT -+ select NR_CPUS_DEFAULT_2 -+ select SIBYTE_SB1250 -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_SB1 -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ -+config SIBYTE_BIGSUR -+ bool "Sibyte BCM91480B-BigSur" -+ select BOOT_ELF32 -+ select DMA_COHERENT -+ select NR_CPUS_DEFAULT_4 -+ select SIBYTE_BCM1x80 -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_SB1 -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_HIGHMEM -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select ZONE_DMA32 if 64BIT -+ -+config SNI_RM -+ bool "SNI RM200/300/400" -+ select ARC if CPU_LITTLE_ENDIAN -+ select ARC32 if CPU_LITTLE_ENDIAN -+ select SNIPROM if CPU_BIG_ENDIAN -+ select ARCH_MAY_HAVE_PC_FDC -+ select BOOT_ELF32 -+ select CEVT_R4K -+ select CSRC_R4K -+ select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN -+ select DMA_NONCOHERENT -+ select GENERIC_ISA_DMA -+ select HW_HAS_EISA -+ select HW_HAS_PCI -+ select IRQ_CPU -+ select I8253 -+ select I8259 -+ select ISA -+ select SWAP_IO_SPACE if CPU_BIG_ENDIAN -+ select SYS_HAS_CPU_R4X00 -+ select SYS_HAS_CPU_R5000 -+ select SYS_HAS_CPU_R10000 -+ select R5000_CPU_SCACHE -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_HIGHMEM -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ help -+ The SNI RM200/300/400 are MIPS-based machines manufactured by -+ Siemens Nixdorf Informationssysteme (SNI), parent company of Pyramid -+ Technology and now in turn merged with Fujitsu. Say Y here to -+ support this machine type. ++#define AR724X_PCI_REG_APP 0x00 ++#define AR724X_PCI_REG_RESET 0x18 ++#define AR724X_PCI_REG_INT_STATUS 0x4c ++#define AR724X_PCI_REG_INT_MASK 0x50 + -+config MACH_TX39XX -+ bool "Toshiba TX39 series based machines" ++#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0) ++#define AR724X_PCI_RESET_LINK_UP BIT(0) + -+config MACH_TX49XX -+ bool "Toshiba TX49 series based machines" ++#define AR724X_PCI_INT_DEV0 BIT(14) + -+config MIKROTIK_RB532 -+ bool "Mikrotik RB532 boards" -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select HW_HAS_PCI -+ select IRQ_CPU -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select SWAP_IO_SPACE -+ select BOOT_RAW -+ select ARCH_REQUIRE_GPIOLIB -+ help -+ Support the Mikrotik(tm) RouterBoard 532 series, -+ based on the IDT RC32434 SoC. ++/* ++ * RESET block ++ */ ++#define AR71XX_RESET_REG_TIMER 0x00 ++#define AR71XX_RESET_REG_TIMER_RELOAD 0x04 ++#define AR71XX_RESET_REG_WDOG_CTRL 0x08 ++#define AR71XX_RESET_REG_WDOG 0x0c ++#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10 ++#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14 ++#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18 ++#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c ++#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20 ++#define AR71XX_RESET_REG_RESET_MODULE 0x24 ++#define AR71XX_RESET_REG_PERFC_CTRL 0x2c ++#define AR71XX_RESET_REG_PERFC0 0x30 ++#define AR71XX_RESET_REG_PERFC1 0x34 ++#define AR71XX_RESET_REG_REV_ID 0x90 + -+config WR_PPMC -+ bool "Wind River PPMC board" -+ select CEVT_R4K -+ select CSRC_R4K -+ select IRQ_CPU -+ select BOOT_ELF32 -+ select DMA_NONCOHERENT -+ select HW_HAS_PCI -+ select PCI_GT64XXX_PCI0 -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_HAS_CPU_MIPS32_R2 -+ select SYS_HAS_CPU_MIPS64_R1 -+ select SYS_HAS_CPU_NEVADA -+ select SYS_HAS_CPU_RM7000 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ help -+ This enables support for the Wind River MIPS32 4KC PPMC evaluation -+ board, which is based on GT64120 bridge chip. ++#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18 ++#define AR91XX_RESET_REG_RESET_MODULE 0x1c ++#define AR91XX_RESET_REG_PERF_CTRL 0x20 ++#define AR91XX_RESET_REG_PERFC0 0x24 ++#define AR91XX_RESET_REG_PERFC1 0x28 + -+config CAVIUM_OCTEON_SIMULATOR -+ bool "Cavium Networks Octeon Simulator" -+ select CEVT_R4K -+ select 64BIT_PHYS_ADDR -+ select DMA_COHERENT -+ select SYS_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_HIGHMEM -+ select SYS_SUPPORTS_HOTPLUG_CPU -+ select SYS_HAS_CPU_CAVIUM_OCTEON -+ help -+ The Octeon simulator is software performance model of the Cavium -+ Octeon Processor. It supports simulating Octeon processors on x86 -+ hardware. ++#define AR724X_RESET_REG_RESET_MODULE 0x1c + -+config CAVIUM_OCTEON_REFERENCE_BOARD -+ bool "Cavium Networks Octeon reference board" -+ select CEVT_R4K -+ select 64BIT_PHYS_ADDR -+ select DMA_COHERENT -+ select SYS_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_HIGHMEM -+ select SYS_SUPPORTS_HOTPLUG_CPU -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_HAS_CPU_CAVIUM_OCTEON -+ select SWAP_IO_SPACE -+ select HW_HAS_PCI -+ select ARCH_SUPPORTS_MSI -+ select ZONE_DMA32 -+ select USB_ARCH_HAS_OHCI -+ select USB_ARCH_HAS_EHCI -+ help -+ This option supports all of the Octeon reference boards from Cavium -+ Networks. It builds a kernel that dynamically determines the Octeon -+ CPU type and supports all known board reference implementations. -+ Some of the supported boards are: -+ EBT3000 -+ EBH3000 -+ EBH3100 -+ Thunder -+ Kodama -+ Hikari -+ Say Y here for most Octeon reference boards. -+ -+endchoice -+ -+source "arch/mips/alchemy/Kconfig" -+source "arch/mips/ar71xx/Kconfig" -+source "arch/mips/ath79/Kconfig" -+source "arch/mips/bcm63xx/Kconfig" -+source "arch/mips/jazz/Kconfig" -+source "arch/mips/jz4740/Kconfig" -+source "arch/mips/lasat/Kconfig" -+source "arch/mips/pmc-sierra/Kconfig" -+source "arch/mips/powertv/Kconfig" -+source "arch/mips/sgi-ip27/Kconfig" -+source "arch/mips/sibyte/Kconfig" -+source "arch/mips/txx9/Kconfig" -+source "arch/mips/vr41xx/Kconfig" -+source "arch/mips/cavium-octeon/Kconfig" -+source "arch/mips/loongson/Kconfig" ++#define AR933X_RESET_REG_RESET_MODULE 0x1c ++#define AR933X_RESET_REG_BOOTSTRAP 0xac ++#define AR933X_BOOTSTRAP_EEPBUSY BIT(4) ++#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) + -+endmenu ++#define AR934X_RESET_REG_RESET_MODULE 0x1c ++#define AR934X_RESET_REG_BOOTSTRAP 0xb0 ++/* 0 - 25MHz 1 - 40 MHz */ ++#define AR934X_REF_CLK_40 (1 << 4) + -+config RWSEM_GENERIC_SPINLOCK -+ bool -+ default y ++#define WDOG_CTRL_LAST_RESET BIT(31) ++#define WDOG_CTRL_ACTION_MASK 3 ++#define WDOG_CTRL_ACTION_NONE 0 /* no action */ ++#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */ ++#define WDOG_CTRL_ACTION_NMI 2 /* NMI */ ++#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */ + -+config RWSEM_XCHGADD_ALGORITHM -+ bool ++#define MISC_INT_ENET_LINK BIT(12) ++#define MISC_INT_DDR_PERF BIT(11) ++#define MISC_INT_TIMER4 BIT(10) ++#define MISC_INT_TIMER3 BIT(9) ++#define MISC_INT_TIMER2 BIT(8) ++#define MISC_INT_DMA BIT(7) ++#define MISC_INT_OHCI BIT(6) ++#define MISC_INT_PERFC BIT(5) ++#define MISC_INT_WDOG BIT(4) ++#define MISC_INT_UART BIT(3) ++#define MISC_INT_GPIO BIT(2) ++#define MISC_INT_ERROR BIT(1) ++#define MISC_INT_TIMER BIT(0) + -+config ARCH_HAS_ILOG2_U32 -+ bool -+ default n ++#define PCI_INT_CORE BIT(4) ++#define PCI_INT_DEV2 BIT(2) ++#define PCI_INT_DEV1 BIT(1) ++#define PCI_INT_DEV0 BIT(0) + -+config ARCH_HAS_ILOG2_U64 -+ bool -+ default n -+ -+config ARCH_SUPPORTS_OPROFILE -+ bool -+ default y if !MIPS_MT_SMTC -+ -+config GENERIC_FIND_NEXT_BIT -+ bool -+ default y ++#define RESET_MODULE_EXTERNAL BIT(28) ++#define RESET_MODULE_FULL_CHIP BIT(24) ++#define RESET_MODULE_AMBA2WMAC BIT(22) ++#define RESET_MODULE_CPU_NMI BIT(21) ++#define RESET_MODULE_CPU_COLD BIT(20) ++#define RESET_MODULE_DMA BIT(19) ++#define RESET_MODULE_SLIC BIT(18) ++#define RESET_MODULE_STEREO BIT(17) ++#define RESET_MODULE_DDR BIT(16) ++#define RESET_MODULE_GE1_MAC BIT(13) ++#define RESET_MODULE_GE1_PHY BIT(12) ++#define RESET_MODULE_USBSUS_OVERRIDE BIT(10) ++#define RESET_MODULE_GE0_MAC BIT(9) ++#define RESET_MODULE_GE0_PHY BIT(8) ++#define RESET_MODULE_USB_OHCI_DLL BIT(6) ++#define RESET_MODULE_USB_HOST BIT(5) ++#define RESET_MODULE_USB_PHY BIT(4) ++#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3) ++#define RESET_MODULE_PCI_BUS BIT(1) ++#define RESET_MODULE_PCI_CORE BIT(0) + -+config GENERIC_FIND_BIT_LE -+ bool -+ default y ++#define AR724X_RESET_GE1_MDIO BIT(23) ++#define AR724X_RESET_GE0_MDIO BIT(22) ++#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10) ++#define AR724X_RESET_PCIE_PHY BIT(7) ++#define AR724X_RESET_PCIE BIT(6) ++#define AR724X_RESET_USB_HOST BIT(5) ++#define AR724X_RESET_USB_PHY BIT(4) ++#define AR724X_RESET_USBSUS_OVERRIDE BIT(3) + -+config GENERIC_HWEIGHT -+ bool -+ default y ++#define AR933X_RESET_WMAC BIT(11) ++#define AR933X_RESET_GE1_MDIO BIT(23) ++#define AR933X_RESET_GE0_MDIO BIT(22) ++#define AR933X_RESET_GE1_MAC BIT(13) ++#define AR933X_RESET_GE0_MAC BIT(9) + -+config GENERIC_CALIBRATE_DELAY -+ bool -+ default y ++#define REV_ID_MAJOR_MASK 0xfff0 ++#define REV_ID_MAJOR_AR71XX 0x00a0 ++#define REV_ID_MAJOR_AR913X 0x00b0 ++#define REV_ID_MAJOR_AR7240 0x00c0 ++#define REV_ID_MAJOR_AR7241 0x0100 ++#define REV_ID_MAJOR_AR7242 0x1100 ++#define REV_ID_MAJOR_AR9330 0x0110 ++#define REV_ID_MAJOR_AR9331 0x1110 ++#define REV_ID_MAJOR_AR9341 0x0120 ++#define REV_ID_MAJOR_AR9342 0x1120 ++#define REV_ID_MAJOR_AR9344 0x2120 + -+config GENERIC_CLOCKEVENTS -+ bool -+ default y ++#define AR71XX_REV_ID_MINOR_MASK 0x3 ++#define AR71XX_REV_ID_MINOR_AR7130 0x0 ++#define AR71XX_REV_ID_MINOR_AR7141 0x1 ++#define AR71XX_REV_ID_MINOR_AR7161 0x2 ++#define AR71XX_REV_ID_REVISION_MASK 0x3 ++#define AR71XX_REV_ID_REVISION_SHIFT 2 + -+config GENERIC_CMOS_UPDATE -+ bool -+ default y ++#define AR91XX_REV_ID_MINOR_MASK 0x3 ++#define AR91XX_REV_ID_MINOR_AR9130 0x0 ++#define AR91XX_REV_ID_MINOR_AR9132 0x1 ++#define AR91XX_REV_ID_REVISION_MASK 0x3 ++#define AR91XX_REV_ID_REVISION_SHIFT 2 + -+config SCHED_OMIT_FRAME_POINTER -+ bool -+ default y ++#define AR724X_REV_ID_REVISION_MASK 0x3 + -+# -+# Select some configuration options automatically based on user selections. -+# -+config ARC -+ bool ++#define AR933X_REV_ID_REVISION_MASK 0xf + -+config ARCH_MAY_HAVE_PC_FDC -+ bool ++#define AR934X_REV_ID_REVISION_MASK 0xf + -+config BOOT_RAW -+ bool ++extern void __iomem *ar71xx_reset_base; + -+config CEVT_BCM1480 -+ bool ++static inline void ar71xx_reset_wr(unsigned reg, u32 val) ++{ ++ __raw_writel(val, ar71xx_reset_base + reg); ++} + -+config CEVT_DS1287 -+ bool ++static inline u32 ar71xx_reset_rr(unsigned reg) ++{ ++ return __raw_readl(ar71xx_reset_base + reg); ++} + -+config CEVT_GT641XX -+ bool ++void ar71xx_device_stop(u32 mask); ++void ar71xx_device_start(u32 mask); ++int ar71xx_device_stopped(u32 mask); + -+config CEVT_R4K_LIB -+ bool ++/* ++ * SPI block ++ */ ++#define SPI_REG_FS 0x00 /* Function Select */ ++#define SPI_REG_CTRL 0x04 /* SPI Control */ ++#define SPI_REG_IOC 0x08 /* SPI I/O Control */ ++#define SPI_REG_RDS 0x0c /* Read Data Shift */ + -+config CEVT_R4K -+ select CEVT_R4K_LIB -+ bool ++#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */ + -+config CEVT_SB1250 -+ bool ++#define SPI_CTRL_RD BIT(6) /* Remap Disable */ ++#define SPI_CTRL_DIV_MASK 0x3f + -+config CEVT_TXX9 -+ bool ++#define SPI_IOC_DO BIT(0) /* Data Out pin */ ++#define SPI_IOC_CLK BIT(8) /* CLK pin */ ++#define SPI_IOC_CS(n) BIT(16 + (n)) ++#define SPI_IOC_CS0 SPI_IOC_CS(0) ++#define SPI_IOC_CS1 SPI_IOC_CS(1) ++#define SPI_IOC_CS2 SPI_IOC_CS(2) ++#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2) + -+config CSRC_BCM1480 -+ bool ++void ar71xx_flash_acquire(void); ++void ar71xx_flash_release(void); + -+config CSRC_IOASIC -+ bool ++/* ++ * MII_CTRL block ++ */ ++#define MII_REG_MII0_CTRL 0x00 ++#define MII_REG_MII1_CTRL 0x04 + -+config CSRC_POWERTV -+ bool ++#define MII0_CTRL_IF_GMII 0 ++#define MII0_CTRL_IF_MII 1 ++#define MII0_CTRL_IF_RGMII 2 ++#define MII0_CTRL_IF_RMII 3 + -+config CSRC_R4K_LIB -+ bool ++#define MII1_CTRL_IF_RGMII 0 ++#define MII1_CTRL_IF_RMII 1 + -+config CSRC_R4K -+ select CSRC_R4K_LIB -+ bool ++#endif /* __ASSEMBLER__ */ + -+config CSRC_SB1250 -+ bool ++#endif /* __ASM_MACH_AR71XX_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar91xx_flash.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,26 @@ ++/* ++ * AR91xx parallel flash driver platform data definitions ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+config GPIO_TXX9 -+ select GENERIC_GPIO -+ select ARCH_REQUIRE_GPIOLIB -+ bool ++#ifndef __AR91XX_FLASH_H ++#define __AR91XX_FLASH_H + -+config CFE -+ bool ++struct mtd_partition; + -+config ARCH_DMA_ADDR_T_64BIT -+ def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT ++struct ar91xx_flash_platform_data { ++ unsigned int width; ++ u8 is_shared:1; ++#ifdef CONFIG_MTD_PARTITIONS ++ unsigned int nr_parts; ++ struct mtd_partition *parts; ++#endif ++}; + -+config DMA_COHERENT -+ bool ++#endif /* __AR91XX_FLASH_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,67 @@ ++/* ++ * Atheros AR933X UART defines ++ * ++ * Copyright (C) 2011 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+config DMA_NONCOHERENT -+ bool -+ select NEED_DMA_MAP_STATE ++#ifndef __AR933X_UART_H ++#define __AR933X_UART_H + -+config NEED_DMA_MAP_STATE -+ bool ++#define AR933X_UART_REGS_SIZE 20 ++#define AR933X_UART_FIFO_SIZE 16 + -+config SYS_HAS_EARLY_PRINTK -+ bool ++#define AR933X_UART_DATA_REG 0x00 ++#define AR933X_UART_CS_REG 0x04 ++#define AR933X_UART_CLOCK_REG 0x08 ++#define AR933X_UART_INT_REG 0x0c ++#define AR933X_UART_INT_EN_REG 0x10 + -+config HOTPLUG_CPU -+ bool "Support for hot-pluggable CPUs" -+ depends on SMP && HOTPLUG && SYS_SUPPORTS_HOTPLUG_CPU -+ help -+ Say Y here to allow turning CPUs off and on. CPUs can be -+ controlled through /sys/devices/system/cpu. -+ (Note: power management support will enable this option -+ automatically on SMP systems. ) -+ Say N if you want to disable CPU hotplug. ++#define AR933X_UART_DATA_TX_RX_MASK 0xff ++#define AR933X_UART_DATA_RX_CSR BIT(8) ++#define AR933X_UART_DATA_TX_CSR BIT(9) + -+config SYS_SUPPORTS_HOTPLUG_CPU -+ bool ++#define AR933X_UART_CS_PARITY_S 0 ++#define AR933X_UART_CS_PARITY_M 0x3 ++#define AR933X_UART_CS_PARITY_NONE 0 ++#define AR933X_UART_CS_PARITY_ODD 1 ++#define AR933X_UART_CS_PARITY_EVEN 2 ++#define AR933X_UART_CS_IF_MODE_S 2 ++#define AR933X_UART_CS_IF_MODE_M 0x3 ++#define AR933X_UART_CS_IF_MODE_NONE 0 ++#define AR933X_UART_CS_IF_MODE_DTE 1 ++#define AR933X_UART_CS_IF_MODE_DCE 2 ++#define AR933X_UART_CS_FLOW_CTRL_S 4 ++#define AR933X_UART_CS_FLOW_CTRL_M 0x3 ++#define AR933X_UART_CS_DMA_EN BIT(6) ++#define AR933X_UART_CS_TX_READY_ORIDE BIT(7) ++#define AR933X_UART_CS_RX_READY_ORIDE BIT(8) ++#define AR933X_UART_CS_TX_READY BIT(9) ++#define AR933X_UART_CS_RX_BREAK BIT(10) ++#define AR933X_UART_CS_TX_BREAK BIT(11) ++#define AR933X_UART_CS_HOST_INT BIT(12) ++#define AR933X_UART_CS_HOST_INT_EN BIT(13) ++#define AR933X_UART_CS_TX_BUSY BIT(14) ++#define AR933X_UART_CS_RX_BUSY BIT(15) + -+config I8259 -+ bool ++#define AR933X_UART_CLOCK_STEP_M 0xffff ++#define AR933X_UART_CLOCK_SCALE_M 0xfff ++#define AR933X_UART_CLOCK_SCALE_S 16 ++#define AR933X_UART_CLOCK_STEP_M 0xffff + -+config MIPS_BONITO64 -+ bool ++#define AR933X_UART_INT_RX_VALID BIT(0) ++#define AR933X_UART_INT_TX_READY BIT(1) ++#define AR933X_UART_INT_RX_FRAMING_ERR BIT(2) ++#define AR933X_UART_INT_RX_OFLOW_ERR BIT(3) ++#define AR933X_UART_INT_TX_OFLOW_ERR BIT(4) ++#define AR933X_UART_INT_RX_PARITY_ERR BIT(5) ++#define AR933X_UART_INT_RX_BREAK_ON BIT(6) ++#define AR933X_UART_INT_RX_BREAK_OFF BIT(7) ++#define AR933X_UART_INT_RX_FULL BIT(8) ++#define AR933X_UART_INT_TX_EMPTY BIT(9) ++#define AR933X_UART_INT_ALLINTS 0x3ff + -+config MIPS_MSC -+ bool ++#endif /* __AR933X_UART_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/ar933x_uart_platform.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,18 @@ ++/* ++ * Platform data definition for Atheros AR933X UART ++ * ++ * Copyright (C) 2011 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+config MIPS_NILE4 -+ bool ++#ifndef _AR933X_UART_PLATFORM_H ++#define _AR933X_UART_PLATFORM_H + -+config MIPS_DISABLE_OBSOLETE_IDE -+ bool ++struct ar933x_uart_platform_data { ++ unsigned uartclk; ++}; + -+config SYNC_R4K -+ bool -+ -+config MIPS_MACHINE -+ def_bool n -+ -+config NO_IOPORT -+ def_bool n ++#endif /* _AR933X_UART_PLATFORM_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,56 @@ ++/* ++ * Atheros AR71xx specific CPU feature overrides ++ * ++ * Copyright (C) 2008 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This file was derived from: include/asm-mips/cpu-features.h ++ * Copyright (C) 2003, 2004 Ralf Baechle ++ * Copyright (C) 2004 Maciej W. Rozycki ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++#ifndef __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H ++#define __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H + -+config GENERIC_ISA_DMA -+ bool -+ select ZONE_DMA if GENERIC_ISA_DMA_SUPPORT_BROKEN=n -+ select ISA_DMA_API ++#define cpu_has_tlb 1 ++#define cpu_has_4kex 1 ++#define cpu_has_3k_cache 0 ++#define cpu_has_4k_cache 1 ++#define cpu_has_tx39_cache 0 ++#define cpu_has_sb1_cache 0 ++#define cpu_has_fpu 0 ++#define cpu_has_32fpr 0 ++#define cpu_has_counter 1 ++#define cpu_has_watch 1 ++#define cpu_has_divec 1 + -+config GENERIC_ISA_DMA_SUPPORT_BROKEN -+ bool -+ select GENERIC_ISA_DMA ++#define cpu_has_prefetch 1 ++#define cpu_has_ejtag 1 ++#define cpu_has_llsc 1 + -+config ISA_DMA_API -+ bool ++#define cpu_has_mips16 1 ++#define cpu_has_mdmx 0 ++#define cpu_has_mips3d 0 ++#define cpu_has_smartmips 0 + -+config GENERIC_GPIO -+ bool ++#define cpu_has_mips32r1 1 ++#define cpu_has_mips32r2 1 ++#define cpu_has_mips64r1 0 ++#define cpu_has_mips64r2 0 + -+# -+# Endianess selection. Sufficiently obscure so many users don't know what to -+# answer,so we try hard to limit the available choices. Also the use of a -+# choice statement should be more obvious to the user. -+# -+choice -+ prompt "Endianess selection" -+ help -+ Some MIPS machines can be configured for either little or big endian -+ byte order. These modes require different kernels and a different -+ Linux distribution. In general there is one preferred byteorder for a -+ particular system but some systems are just as commonly used in the -+ one or the other endianness. -+ -+config CPU_BIG_ENDIAN -+ bool "Big endian" -+ depends on SYS_SUPPORTS_BIG_ENDIAN -+ -+config CPU_LITTLE_ENDIAN -+ bool "Little endian" -+ depends on SYS_SUPPORTS_LITTLE_ENDIAN -+ help ++#define cpu_has_dsp 0 ++#define cpu_has_mipsmt 0 + -+endchoice ++#define cpu_has_64bits 0 ++#define cpu_has_64bit_zero_reg 0 ++#define cpu_has_64bit_gp_regs 0 ++#define cpu_has_64bit_addresses 0 + -+config EXPORT_UASM -+ bool ++#define cpu_dcache_line_size() 32 ++#define cpu_icache_line_size() 32 + -+config SYS_SUPPORTS_APM_EMULATION -+ bool ++#endif /* __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/gpio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/gpio.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,53 @@ ++/* ++ * Atheros AR71xx GPIO API definitions ++ * ++ * Copyright (C) 2008 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ + -+config SYS_SUPPORTS_BIG_ENDIAN -+ bool ++#ifndef __ASM_MACH_AR71XX_GPIO_H ++#define __ASM_MACH_AR71XX_GPIO_H + -+config SYS_SUPPORTS_LITTLE_ENDIAN -+ bool ++#define ARCH_NR_GPIOS 64 ++#include + -+config SYS_SUPPORTS_HUGETLBFS -+ bool -+ depends on CPU_SUPPORTS_HUGEPAGES && 64BIT -+ default y ++#include + -+config IRQ_CPU -+ bool ++extern unsigned long ar71xx_gpio_count; ++extern void __ar71xx_gpio_set_value(unsigned gpio, int value); ++extern int __ar71xx_gpio_get_value(unsigned gpio); + -+config IRQ_CPU_RM7K -+ bool ++static inline int gpio_to_irq(unsigned gpio) ++{ ++ return AR71XX_GPIO_IRQ(gpio); ++} + -+config IRQ_CPU_RM9K -+ bool ++static inline int irq_to_gpio(unsigned irq) ++{ ++ return irq - AR71XX_GPIO_IRQ_BASE; ++} + -+config IRQ_MSP_SLP -+ bool ++static inline int gpio_get_value(unsigned gpio) ++{ ++ if (gpio < ar71xx_gpio_count) ++ return __ar71xx_gpio_get_value(gpio); + -+config IRQ_MSP_CIC -+ bool ++ return __gpio_get_value(gpio); ++} + -+config IRQ_TXX9 -+ bool ++static inline void gpio_set_value(unsigned gpio, int value) ++{ ++ if (gpio < ar71xx_gpio_count) ++ __ar71xx_gpio_set_value(gpio, value); ++ else ++ __gpio_set_value(gpio, value); ++} + -+config IRQ_GT641XX -+ bool ++#define gpio_cansleep __gpio_cansleep + -+config IRQ_GIC -+ bool ++#endif /* __ASM_MACH_AR71XX_GPIO_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/irq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/irq.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,17 @@ ++/* ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++#ifndef __ASM_MACH_AR71XX_IRQ_H ++#define __ASM_MACH_AR71XX_IRQ_H + -+config MIPS_BOARDS_GEN -+ bool ++#define MIPS_CPU_IRQ_BASE 0 ++#define NR_IRQS 80 + -+config PCI_GT64XXX_PCI0 -+ bool ++#include_next + -+config NO_EXCEPT_FILL -+ bool ++#endif /* __ASM_MACH_AR71XX_IRQ_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,32 @@ ++/* ++ * Atheros AR71xx specific kernel entry setup ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++#ifndef __ASM_MACH_AR71XX_KERNEL_ENTRY_H ++#define __ASM_MACH_AR71XX_KERNEL_ENTRY_H + -+config MIPS_RM9122 -+ bool -+ select SERIAL_RM9000 ++ /* ++ * Some bootloaders set the 'Kseg0 coherency algorithm' to ++ * 'Cacheable, noncoherent, write-through, no write allocate' ++ * and this cause performance issues. Let's go and change it to ++ * 'Cacheable, noncoherent, write-back, write allocate' ++ */ ++ .macro kernel_entry_setup ++ mfc0 t0, CP0_CONFIG ++ li t1, ~CONF_CM_CMASK ++ and t0, t1 ++ ori t0, CONF_CM_CACHABLE_NONCOHERENT ++ mtc0 t0, CP0_CONFIG ++ nop ++ .endm + -+config SOC_EMMA2RH -+ bool -+ select CEVT_R4K -+ select CSRC_R4K -+ select DMA_NONCOHERENT -+ select IRQ_CPU -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_R5500 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_BIG_ENDIAN ++ .macro smp_slave_setup ++ .endm + -+config SOC_PNX833X -+ bool -+ select CEVT_R4K -+ select CSRC_R4K -+ select IRQ_CPU -+ select DMA_NONCOHERENT -+ select SYS_HAS_CPU_MIPS32_R2 -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select GENERIC_GPIO -+ select CPU_MIPSR2_IRQ_VI ++#endif /* __ASM_MACH_AR71XX_KERNEL_ENTRY_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mach-rb750.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,66 @@ ++/* ++ * MikroTik RouterBOARD 750 definitions ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++#ifndef _MACH_RB750_H ++#define _MACH_RB750_H + -+config SOC_PNX8335 -+ bool -+ select SOC_PNX833X ++#include + -+config PNX8550 -+ bool -+ select SOC_PNX8550 ++#define RB750_GPIO_LVC573_LE 0 /* Latch enable on LVC573 */ ++#define RB750_GPIO_NAND_IO0 1 /* NAND I/O 0 */ ++#define RB750_GPIO_NAND_IO1 2 /* NAND I/O 1 */ ++#define RB750_GPIO_NAND_IO2 3 /* NAND I/O 2 */ ++#define RB750_GPIO_NAND_IO3 4 /* NAND I/O 3 */ ++#define RB750_GPIO_NAND_IO4 5 /* NAND I/O 4 */ ++#define RB750_GPIO_NAND_IO5 6 /* NAND I/O 5 */ ++#define RB750_GPIO_NAND_IO6 7 /* NAND I/O 6 */ ++#define RB750_GPIO_NAND_IO7 8 /* NAND I/O 7 */ ++#define RB750_GPIO_NAND_NCE 11 /* NAND Chip Enable (active low) */ ++#define RB750_GPIO_NAND_RDY 12 /* NAND Ready */ ++#define RB750_GPIO_NAND_CLE 14 /* NAND Command Latch Enable */ ++#define RB750_GPIO_NAND_ALE 15 /* NAND Address Latch Enable */ ++#define RB750_GPIO_NAND_NRE 16 /* NAND Read Enable (active low) */ ++#define RB750_GPIO_NAND_NWE 17 /* NAND Write Enable (active low) */ + -+config SOC_PNX8550 -+ bool -+ select DMA_NONCOHERENT -+ select HW_HAS_PCI -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select GENERIC_GPIO ++#define RB750_GPIO_BTN_RESET 1 ++#define RB750_GPIO_SPI_CS0 2 ++#define RB750_GPIO_LED_ACT 12 ++#define RB750_GPIO_LED_PORT1 13 ++#define RB750_GPIO_LED_PORT2 14 ++#define RB750_GPIO_LED_PORT3 15 ++#define RB750_GPIO_LED_PORT4 16 ++#define RB750_GPIO_LED_PORT5 17 + -+config SWAP_IO_SPACE -+ bool ++#define RB750_LED_ACT BIT(RB750_GPIO_LED_ACT) ++#define RB750_LED_PORT1 BIT(RB750_GPIO_LED_PORT1) ++#define RB750_LED_PORT2 BIT(RB750_GPIO_LED_PORT2) ++#define RB750_LED_PORT3 BIT(RB750_GPIO_LED_PORT3) ++#define RB750_LED_PORT4 BIT(RB750_GPIO_LED_PORT4) ++#define RB750_LED_PORT5 BIT(RB750_GPIO_LED_PORT5) + -+config SERIAL_RM9000 -+ bool ++#define RB750_LVC573_LE BIT(RB750_GPIO_LVC573_LE) + -+config SGI_HAS_INDYDOG -+ bool ++#define RB750_LED_BITS (RB750_LED_PORT1 | RB750_LED_PORT2 | RB750_LED_PORT3 | \ ++ RB750_LED_PORT4 | RB750_LED_PORT5 | RB750_LED_ACT) + -+config SGI_HAS_HAL2 -+ bool ++struct rb750_led_data { ++ char *name; ++ char *default_trigger; ++ u32 mask; ++ int active_low; ++}; + -+config SGI_HAS_SEEQ -+ bool ++struct rb750_led_platform_data { ++ int num_leds; ++ struct rb750_led_data *leds; ++}; + -+config SGI_HAS_WD93 -+ bool ++int rb750_latch_change(u32 mask_clr, u32 mask_set); + -+config SGI_HAS_ZILOG -+ bool ++#endif /* _MACH_RB750_H */ +\ No newline at end of file +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/mangle-port.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (C) 2008 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h ++ * Copyright (C) 2003, 2004 Ralf Baechle ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+config SGI_HAS_I8042 -+ bool ++#ifndef __ASM_MACH_AR71XX_MANGLE_PORT_H ++#define __ASM_MACH_AR71XX_MANGLE_PORT_H + -+config DEFAULT_SGI_PARTITION -+ bool ++#define __swizzle_addr_b(port) ((port) ^ 3) ++#define __swizzle_addr_w(port) ((port) ^ 2) ++#define __swizzle_addr_l(port) (port) ++#define __swizzle_addr_q(port) (port) + -+config ARC32 -+ bool ++#if defined(CONFIG_SWAP_IO_SPACE) + -+config SNIPROM -+ bool ++# define ioswabb(a, x) (x) ++# define __mem_ioswabb(a, x) (x) ++# define ioswabw(a, x) le16_to_cpu(x) ++# define __mem_ioswabw(a, x) (x) ++# define ioswabl(a, x) le32_to_cpu(x) ++# define __mem_ioswabl(a, x) (x) ++# define ioswabq(a, x) le64_to_cpu(x) ++# define __mem_ioswabq(a, x) (x) + -+config BOOT_ELF32 -+ bool ++#else + -+config MIPS_L1_CACHE_SHIFT -+ int -+ default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL -+ default "6" if MIPS_CPU_SCACHE -+ default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON -+ default "5" ++# define ioswabb(a, x) (x) ++# define __mem_ioswabb(a, x) (x) ++# define ioswabw(a, x) (x) ++# define __mem_ioswabw(a, x) cpu_to_le16(x) ++# define ioswabl(a, x) (x) ++# define __mem_ioswabl(a, x) cpu_to_le32(x) ++# define ioswabq(a, x) (x) ++# define __mem_ioswabq(a, x) cpu_to_le64(x) + -+config HAVE_STD_PC_SERIAL_PORT -+ bool ++#endif + -+config ARC_CONSOLE -+ bool "ARC console support" -+ depends on SGI_IP22 || SGI_IP28 || (SNI_RM && CPU_LITTLE_ENDIAN) ++#endif /* __ASM_MACH_AR71XX_MANGLE_PORT_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/pci.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,46 @@ ++/* ++ * Atheros AR71xx SoC specific PCI definitions ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+config ARC_MEMORY -+ bool -+ depends on MACH_JAZZ || SNI_RM || SGI_IP32 -+ default y ++#ifndef __ASM_MACH_AR71XX_PCI_H ++#define __ASM_MACH_AR71XX_PCI_H + -+config ARC_PROMLIB -+ bool -+ depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP28 || SGI_IP32 -+ default y ++struct pci_dev; + -+config ARC64 -+ bool ++struct ar71xx_pci_irq { ++ int irq; ++ u8 slot; ++ u8 pin; ++}; + -+config BOOT_ELF64 -+ bool ++#ifdef CONFIG_PCI ++extern int (*ar71xx_pci_plat_dev_init)(struct pci_dev *dev); ++extern unsigned ar71xx_pci_nr_irqs __initdata; ++extern struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata; + -+menu "CPU selection" ++int ar71xx_pcibios_map_irq(const struct pci_dev *dev, ++ uint8_t slot, uint8_t pin) __init; ++int ar71xx_pcibios_init(void) __init; + -+choice -+ prompt "CPU type" -+ default CPU_R4X00 ++int ar71xx_pci_be_handler(int is_fixup); + -+config CPU_LOONGSON2E -+ bool "Loongson 2E" -+ depends on SYS_HAS_CPU_LOONGSON2E -+ select CPU_LOONGSON2 -+ help -+ The Loongson 2E processor implements the MIPS III instruction set -+ with many extensions. ++int ar724x_pcibios_map_irq(const struct pci_dev *dev, ++ uint8_t slot, uint8_t pin) __init; ++int ar724x_pcibios_init(void) __init; + -+ It has an internal FPGA northbridge, which is compatible to -+ bonito64. ++int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) __init; ++#else ++static inline int ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) ++{ ++ return 0; ++} ++#endif + -+config CPU_LOONGSON2F -+ bool "Loongson 2F" -+ depends on SYS_HAS_CPU_LOONGSON2F -+ select CPU_LOONGSON2 -+ select GENERIC_GPIO -+ select ARCH_REQUIRE_GPIOLIB -+ help -+ The Loongson 2F processor implements the MIPS III instruction set -+ with many extensions. -+ -+ Loongson2F have built-in DDR2 and PCIX controller. The PCIX controller -+ have a similar programming interface with FPGA northbridge used in -+ Loongson2E. -+ -+config CPU_MIPS32_R1 -+ bool "MIPS32 Release 1" -+ depends on SYS_HAS_CPU_MIPS32_R1 -+ select CPU_HAS_PREFETCH -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM -+ help -+ Choose this option to build a kernel for release 1 or later of the -+ MIPS32 architecture. Most modern embedded systems with a 32-bit -+ MIPS processor are based on a MIPS32 processor. If you know the -+ specific type of processor in your system, choose those that one -+ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system. -+ Release 2 of the MIPS32 architecture is available since several -+ years so chances are you even have a MIPS32 Release 2 processor -+ in which case you should choose CPU_MIPS32_R2 instead for better -+ performance. -+ -+config CPU_MIPS32_R2 -+ bool "MIPS32 Release 2" -+ depends on SYS_HAS_CPU_MIPS32_R2 -+ select CPU_HAS_PREFETCH -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM -+ help -+ Choose this option to build a kernel for release 2 or later of the -+ MIPS32 architecture. Most modern embedded systems with a 32-bit -+ MIPS processor are based on a MIPS32 processor. If you know the -+ specific type of processor in your system, choose those that one -+ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system. -+ -+config CPU_MIPS64_R1 -+ bool "MIPS64 Release 1" -+ depends on SYS_HAS_CPU_MIPS64_R1 -+ select CPU_HAS_PREFETCH -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM -+ select CPU_SUPPORTS_HUGEPAGES -+ help -+ Choose this option to build a kernel for release 1 or later of the -+ MIPS64 architecture. Many modern embedded systems with a 64-bit -+ MIPS processor are based on a MIPS64 processor. If you know the -+ specific type of processor in your system, choose those that one -+ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system. -+ Release 2 of the MIPS64 architecture is available since several -+ years so chances are you even have a MIPS64 Release 2 processor -+ in which case you should choose CPU_MIPS64_R2 instead for better -+ performance. -+ -+config CPU_MIPS64_R2 -+ bool "MIPS64 Release 2" -+ depends on SYS_HAS_CPU_MIPS64_R2 -+ select CPU_HAS_PREFETCH -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM -+ select CPU_SUPPORTS_HUGEPAGES -+ help -+ Choose this option to build a kernel for release 2 or later of the -+ MIPS64 architecture. Many modern embedded systems with a 64-bit -+ MIPS processor are based on a MIPS64 processor. If you know the -+ specific type of processor in your system, choose those that one -+ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system. -+ -+config CPU_R3000 -+ bool "R3000" -+ depends on SYS_HAS_CPU_R3000 -+ select CPU_HAS_WB -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM -+ help -+ Please make sure to pick the right CPU type. Linux/MIPS is not -+ designed to be generic, i.e. Kernels compiled for R3000 CPUs will -+ *not* work on R4000 machines and vice versa. However, since most -+ of the supported machines have an R4000 (or similar) CPU, R4x00 -+ might be a safe bet. If the resulting kernel does not work, -+ try to recompile with R3000. -+ -+config CPU_TX39XX -+ bool "R39XX" -+ depends on SYS_HAS_CPU_TX39XX -+ select CPU_SUPPORTS_32BIT_KERNEL -+ -+config CPU_VR41XX -+ bool "R41xx" -+ depends on SYS_HAS_CPU_VR41XX -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ help -+ The options selects support for the NEC VR4100 series of processors. -+ Only choose this option if you have one of these processors as a -+ kernel built with this option will not run on any other type of -+ processor or vice versa. -+ -+config CPU_R4300 -+ bool "R4300" -+ depends on SYS_HAS_CPU_R4300 -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ help -+ MIPS Technologies R4300-series processors. ++#endif /* __ASM_MACH_AR71XX_PCI_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/platform.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/platform.h 2011-08-24 18:17:23.000000000 +0200 +@@ -0,0 +1,63 @@ ++/* ++ * Atheros AR71xx SoC specific platform data definitions ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+config CPU_R4X00 -+ bool "R4x00" -+ depends on SYS_HAS_CPU_R4X00 -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ help -+ MIPS Technologies R4000-series processors other than 4300, including -+ the R4000, R4400, R4600, and 4700. -+ -+config CPU_TX49XX -+ bool "R49XX" -+ depends on SYS_HAS_CPU_TX49XX -+ select CPU_HAS_PREFETCH -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ -+config CPU_R5000 -+ bool "R5000" -+ depends on SYS_HAS_CPU_R5000 -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ help -+ MIPS Technologies R5000-series processors other than the Nevada. -+ -+config CPU_R5432 -+ bool "R5432" -+ depends on SYS_HAS_CPU_R5432 -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ -+config CPU_R5500 -+ bool "R5500" -+ depends on SYS_HAS_CPU_R5500 -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ select CPU_SUPPORTS_HUGEPAGES -+ help -+ NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV -+ instruction set. -+ -+config CPU_R6000 -+ bool "R6000" -+ depends on EXPERIMENTAL -+ depends on SYS_HAS_CPU_R6000 -+ select CPU_SUPPORTS_32BIT_KERNEL -+ help -+ MIPS Technologies R6000 and R6000A series processors. Note these -+ processors are extremely rare and the support for them is incomplete. -+ -+config CPU_NEVADA -+ bool "RM52xx" -+ depends on SYS_HAS_CPU_NEVADA -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ help -+ QED / PMC-Sierra RM52xx-series ("Nevada") processors. -+ -+config CPU_R8000 -+ bool "R8000" -+ depends on EXPERIMENTAL -+ depends on SYS_HAS_CPU_R8000 -+ select CPU_HAS_PREFETCH -+ select CPU_SUPPORTS_64BIT_KERNEL -+ help -+ MIPS Technologies R8000 processors. Note these processors are -+ uncommon and the support for them is incomplete. -+ -+config CPU_R10000 -+ bool "R10000" -+ depends on SYS_HAS_CPU_R10000 -+ select CPU_HAS_PREFETCH -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM -+ help -+ MIPS Technologies R10000-series processors. -+ -+config CPU_RM7000 -+ bool "RM7000" -+ depends on SYS_HAS_CPU_RM7000 -+ select CPU_HAS_PREFETCH -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM -+ -+config CPU_RM9000 -+ bool "RM9000" -+ depends on SYS_HAS_CPU_RM9000 -+ select CPU_HAS_PREFETCH -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM -+ select WEAK_ORDERING -+ -+config CPU_SB1 -+ bool "SB1" -+ depends on SYS_HAS_CPU_SB1 -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM -+ select WEAK_ORDERING -+ -+config CPU_CAVIUM_OCTEON -+ bool "Cavium Octeon processor" -+ depends on SYS_HAS_CPU_CAVIUM_OCTEON -+ select CPU_HAS_PREFETCH -+ select CPU_SUPPORTS_64BIT_KERNEL -+ select SYS_SUPPORTS_SMP -+ select NR_CPUS_DEFAULT_16 -+ select WEAK_ORDERING -+ select CPU_SUPPORTS_HIGHMEM -+ select CPU_SUPPORTS_HUGEPAGES -+ help -+ The Cavium Octeon processor is a highly integrated chip containing -+ many ethernet hardware widgets for networking tasks. The processor -+ can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets. -+ Full details can be found at http://www.caviumnetworks.com. -+ -+config CPU_BMIPS3300 -+ bool "BMIPS3300" -+ depends on SYS_HAS_CPU_BMIPS3300 -+ select DMA_NONCOHERENT -+ select IRQ_CPU -+ select SWAP_IO_SPACE -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select WEAK_ORDERING -+ help -+ Broadcom BMIPS3300 processors. ++#ifndef __ASM_MACH_AR71XX_PLATFORM_H ++#define __ASM_MACH_AR71XX_PLATFORM_H + -+config CPU_BMIPS4350 -+ bool "BMIPS4350" -+ depends on SYS_HAS_CPU_BMIPS4350 -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select DMA_NONCOHERENT -+ select IRQ_CPU -+ select SWAP_IO_SPACE -+ select SYS_SUPPORTS_SMP -+ select SYS_SUPPORTS_HOTPLUG_CPU -+ select WEAK_ORDERING -+ help -+ Broadcom BMIPS4350 ("VIPER") processors. ++#include ++#include ++#include ++#include + -+config CPU_BMIPS4380 -+ bool "BMIPS4380" -+ depends on SYS_HAS_CPU_BMIPS4380 -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select DMA_NONCOHERENT -+ select IRQ_CPU -+ select SWAP_IO_SPACE -+ select SYS_SUPPORTS_SMP -+ select SYS_SUPPORTS_HOTPLUG_CPU -+ select WEAK_ORDERING -+ help -+ Broadcom BMIPS4380 processors. ++struct ag71xx_platform_data { ++ phy_interface_t phy_if_mode; ++ u32 phy_mask; ++ int speed; ++ int duplex; ++ u32 reset_bit; ++ u32 mii_if; ++ u8 mac_addr[ETH_ALEN]; ++ struct device *mii_bus_dev; + -+config CPU_BMIPS5000 -+ bool "BMIPS5000" -+ depends on SYS_HAS_CPU_BMIPS5000 -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM -+ select DMA_NONCOHERENT -+ select IRQ_CPU -+ select SWAP_IO_SPACE -+ select SYS_SUPPORTS_SMP -+ select SYS_SUPPORTS_HOTPLUG_CPU -+ select WEAK_ORDERING -+ help -+ Broadcom BMIPS5000 processors. ++ u8 has_gbit:1; ++ u8 is_ar91xx:1; ++ u8 is_ar7240:1; ++ u8 is_ar724x:1; ++ u8 has_ar8216:1; ++ u8 has_ar7240_switch:1; + -+endchoice ++ void (*ddr_flush)(void); ++ void (*set_pll)(int speed); + -+if CPU_LOONGSON2F -+config CPU_NOP_WORKAROUNDS -+ bool ++ u32 fifo_cfg1; ++ u32 fifo_cfg2; ++ u32 fifo_cfg3; ++}; + -+config CPU_JUMP_WORKAROUNDS -+ bool ++struct ag71xx_mdio_platform_data { ++ u32 phy_mask; ++ int is_ar7240; ++}; + -+config CPU_LOONGSON2F_WORKAROUNDS -+ bool "Loongson 2F Workarounds" -+ default y -+ select CPU_NOP_WORKAROUNDS -+ select CPU_JUMP_WORKAROUNDS -+ help -+ Loongson 2F01 / 2F02 processors have the NOP & JUMP issues which -+ require workarounds. Without workarounds the system may hang -+ unexpectedly. For more information please refer to the gas -+ -mfix-loongson2f-nop and -mfix-loongson2f-jump options. ++struct ar71xx_ehci_platform_data { ++ u8 is_ar91xx; ++}; + -+ Loongson 2F03 and later have fixed these issues and no workarounds -+ are needed. The workarounds have no significant side effect on them -+ but may decrease the performance of the system so this option should -+ be disabled unless the kernel is intended to be run on 2F01 or 2F02 -+ systems. ++struct ar71xx_spi_platform_data { ++ unsigned bus_num; ++ unsigned num_chipselect; ++ u32 (*get_ioc_base)(u8 chip_select, int cs_high, int is_on); ++}; + -+ If unsure, please say Y. -+endif # CPU_LOONGSON2F ++#define AR71XX_SPI_CS_INACTIVE 0 ++#define AR71XX_SPI_CS_ACTIVE 1 + -+config SYS_SUPPORTS_ZBOOT -+ bool -+ select HAVE_KERNEL_GZIP -+ select HAVE_KERNEL_BZIP2 -+ select HAVE_KERNEL_LZMA -+ select HAVE_KERNEL_LZO ++#endif /* __ASM_MACH_AR71XX_PLATFORM_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,48 @@ ++/* ++ * SPI driver definitions for the CPLD chip on the Mikrotik RB4xx boards ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This file was based on the patches for Linux 2.6.27.39 published by ++ * MikroTik for their RouterBoard 4xx series devices. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+config SYS_SUPPORTS_ZBOOT_UART16550 -+ bool -+ select SYS_SUPPORTS_ZBOOT ++#define CPLD_GPIO_nLED1 0 ++#define CPLD_GPIO_nLED2 1 ++#define CPLD_GPIO_nLED3 2 ++#define CPLD_GPIO_nLED4 3 ++#define CPLD_GPIO_FAN 4 ++#define CPLD_GPIO_ALE 5 ++#define CPLD_GPIO_CLE 6 ++#define CPLD_GPIO_nCE 7 ++#define CPLD_GPIO_nLED5 8 + -+config CPU_LOONGSON2 -+ bool -+ select CPU_SUPPORTS_32BIT_KERNEL -+ select CPU_SUPPORTS_64BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM ++#define CPLD_NUM_GPIOS 9 + -+config SYS_HAS_CPU_LOONGSON2E -+ bool ++#define CPLD_CFG_nLED1 BIT(CPLD_GPIO_nLED1) ++#define CPLD_CFG_nLED2 BIT(CPLD_GPIO_nLED2) ++#define CPLD_CFG_nLED3 BIT(CPLD_GPIO_nLED3) ++#define CPLD_CFG_nLED4 BIT(CPLD_GPIO_nLED4) ++#define CPLD_CFG_FAN BIT(CPLD_GPIO_FAN) ++#define CPLD_CFG_ALE BIT(CPLD_GPIO_ALE) ++#define CPLD_CFG_CLE BIT(CPLD_GPIO_CLE) ++#define CPLD_CFG_nCE BIT(CPLD_GPIO_nCE) ++#define CPLD_CFG_nLED5 BIT(CPLD_GPIO_nLED5) + -+config SYS_HAS_CPU_LOONGSON2F -+ bool -+ select CPU_SUPPORTS_CPUFREQ -+ select CPU_SUPPORTS_ADDRWINCFG if 64BIT -+ select CPU_SUPPORTS_UNCACHED_ACCELERATED ++struct rb4xx_cpld_platform_data { ++ unsigned gpio_base; ++}; + -+config SYS_HAS_CPU_MIPS32_R1 -+ bool ++extern int rb4xx_cpld_change_cfg(unsigned mask, unsigned value); ++extern int rb4xx_cpld_read(unsigned char *rx_buf, ++ const unsigned char *verify_buf, ++ unsigned cnt); ++extern int rb4xx_cpld_read_from(unsigned addr, ++ unsigned char *rx_buf, ++ const unsigned char *verify_buf, ++ unsigned cnt); ++extern int rb4xx_cpld_write(const unsigned char *buf, unsigned count); +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h +--- linux-2.6.39.orig/arch/mips/include/asm/mach-ar71xx/war.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/include/asm/mach-ar71xx/war.h 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle ++ */ ++#ifndef __ASM_MACH_AR71XX_WAR_H ++#define __ASM_MACH_AR71XX_WAR_H + -+config SYS_HAS_CPU_MIPS32_R2 -+ bool ++#define R4600_V1_INDEX_ICACHEOP_WAR 0 ++#define R4600_V1_HIT_CACHEOP_WAR 0 ++#define R4600_V2_HIT_CACHEOP_WAR 0 ++#define R5432_CP0_INTERRUPT_WAR 0 ++#define BCM1250_M3_WAR 0 ++#define SIBYTE_1956_WAR 0 ++#define MIPS4K_ICACHE_REFILL_WAR 0 ++#define MIPS_CACHE_SYNC_WAR 0 ++#define TX49XX_ICACHE_INDEX_INV_WAR 0 ++#define RM9000_CDEX_SMP_WAR 0 ++#define ICACHE_REFILLS_WORKAROUND_WAR 0 ++#define R10000_LLSC_WAR 0 ++#define MIPS34K_MISSED_ITLB_WAR 0 + -+config SYS_HAS_CPU_MIPS64_R1 -+ bool ++#endif /* __ASM_MACH_AR71XX_WAR_H */ +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/time.h linux-2.6.39/arch/mips/include/asm/time.h +--- linux-2.6.39.orig/arch/mips/include/asm/time.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/include/asm/time.h 2011-08-24 18:17:24.000000000 +0200 +@@ -52,6 +52,7 @@ + */ + #ifdef CONFIG_CEVT_R4K_LIB + extern unsigned int __weak get_c0_compare_int(void); ++extern unsigned int __weak get_c0_compare_irq(void); + extern int r4k_clockevent_init(void); + #endif + +diff -Nur linux-2.6.39.orig/arch/mips/kernel/traps.c linux-2.6.39/arch/mips/kernel/traps.c +--- linux-2.6.39.orig/arch/mips/kernel/traps.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/kernel/traps.c 2011-08-24 18:17:24.000000000 +0200 +@@ -54,6 +54,7 @@ + #include + #include + #include ++#include + + extern void check_wait(void); + extern asmlinkage void r4k_wait(void); +@@ -1576,6 +1577,8 @@ + if (cpu_has_mips_r2) { + cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; + cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; ++ if (get_c0_compare_irq) ++ cp0_compare_irq = get_c0_compare_irq(); + cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7; + if (cp0_perfcount_irq == cp0_compare_irq) + cp0_perfcount_irq = -1; +diff -Nur linux-2.6.39.orig/arch/mips/pci/Makefile linux-2.6.39/arch/mips/pci/Makefile +--- linux-2.6.39.orig/arch/mips/pci/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/pci/Makefile 2011-08-24 18:17:24.000000000 +0200 +@@ -18,6 +18,7 @@ + obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o + obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ + ops-bcm63xx.o ++obj-$(CONFIG_ATHEROS_AR71XX) += pci-ar71xx.o pci-ar724x.o + + # + # These are still pretty much in the old state, watch, go blind. +diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c linux-2.6.39/arch/mips/pci/pci-ar71xx.c +--- linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/pci/pci-ar71xx.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,415 @@ ++/* ++ * Atheros AR71xx PCI host controller driver ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+config SYS_HAS_CPU_MIPS64_R2 -+ bool ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+config SYS_HAS_CPU_R3000 -+ bool ++#include ++#include + -+config SYS_HAS_CPU_TX39XX -+ bool ++#undef DEBUG ++#ifdef DEBUG ++#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args) ++#else ++#define DBG(fmt, args...) ++#endif + -+config SYS_HAS_CPU_VR41XX -+ bool ++#define AR71XX_PCI_DELAY 100 /* msecs */ + -+config SYS_HAS_CPU_R4300 -+ bool ++#if 0 ++#define PCI_IDSEL_BASE PCI_IDSEL_ADL_START ++#else ++#define PCI_IDSEL_BASE 0 ++#endif + -+config SYS_HAS_CPU_R4X00 -+ bool ++static void __iomem *ar71xx_pcicfg_base; ++static DEFINE_SPINLOCK(ar71xx_pci_lock); ++static int ar71xx_pci_fixup_enable; + -+config SYS_HAS_CPU_TX49XX -+ bool ++static inline void ar71xx_pci_delay(void) ++{ ++ mdelay(AR71XX_PCI_DELAY); ++} + -+config SYS_HAS_CPU_R5000 -+ bool ++/* Byte lane enable bits */ ++static u8 ble_table[4][4] = { ++ {0x0, 0xf, 0xf, 0xf}, ++ {0xe, 0xd, 0xb, 0x7}, ++ {0xc, 0xf, 0x3, 0xf}, ++ {0xf, 0xf, 0xf, 0xf}, ++}; + -+config SYS_HAS_CPU_R5432 -+ bool ++static inline u32 ar71xx_pci_get_ble(int where, int size, int local) ++{ ++ u32 t; + -+config SYS_HAS_CPU_R5500 -+ bool ++ t = ble_table[size & 3][where & 3]; ++ BUG_ON(t == 0xf); ++ t <<= (local) ? 20 : 4; ++ return t; ++} + -+config SYS_HAS_CPU_R6000 -+ bool ++static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn, ++ int where) ++{ ++ u32 ret; + -+config SYS_HAS_CPU_NEVADA -+ bool ++ if (!bus->number) { ++ /* type 0 */ ++ ret = (1 << (PCI_IDSEL_BASE + PCI_SLOT(devfn))) ++ | (PCI_FUNC(devfn) << 8) | (where & ~3); ++ } else { ++ /* type 1 */ ++ ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11) ++ | (PCI_FUNC(devfn) << 8) | (where & ~3) | 1; ++ } + -+config SYS_HAS_CPU_R8000 -+ bool ++ return ret; ++} + -+config SYS_HAS_CPU_R10000 -+ bool ++int ar71xx_pci_be_handler(int is_fixup) ++{ ++ void __iomem *base = ar71xx_pcicfg_base; ++ u32 pci_err; ++ u32 ahb_err; + -+config SYS_HAS_CPU_RM7000 -+ bool ++ pci_err = __raw_readl(base + PCI_REG_PCI_ERR) & 3; ++ if (pci_err) { ++ if (!is_fixup) ++ printk(KERN_ALERT "PCI error %d at PCI addr 0x%x\n", ++ pci_err, ++ __raw_readl(base + PCI_REG_PCI_ERR_ADDR)); + -+config SYS_HAS_CPU_RM9000 -+ bool ++ __raw_writel(pci_err, base + PCI_REG_PCI_ERR); ++ } + -+config SYS_HAS_CPU_SB1 -+ bool ++ ahb_err = __raw_readl(base + PCI_REG_AHB_ERR) & 1; ++ if (ahb_err) { ++ if (!is_fixup) ++ printk(KERN_ALERT "AHB error at AHB address 0x%x\n", ++ __raw_readl(base + PCI_REG_AHB_ERR_ADDR)); + -+config SYS_HAS_CPU_CAVIUM_OCTEON -+ bool ++ __raw_writel(ahb_err, base + PCI_REG_AHB_ERR); ++ } + -+config SYS_HAS_CPU_BMIPS3300 -+ bool ++ return (ahb_err | pci_err) ? 1 : 0; ++} + -+config SYS_HAS_CPU_BMIPS4350 -+ bool ++static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus, ++ unsigned int devfn, int where, int size, u32 cmd) ++{ ++ void __iomem *base = ar71xx_pcicfg_base; ++ u32 addr; + -+config SYS_HAS_CPU_BMIPS4380 -+ bool ++ addr = ar71xx_pci_bus_addr(bus, devfn, where); + -+config SYS_HAS_CPU_BMIPS5000 -+ bool ++ DBG("PCI: set cfgaddr: %02x:%02x.%01x/%02x:%01d, addr=%08x\n", ++ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), ++ where, size, addr); + -+# -+# CPU may reorder R->R, R->W, W->R, W->W -+# Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC -+# -+config WEAK_ORDERING -+ bool ++ __raw_writel(addr, base + PCI_REG_CFG_AD); ++ __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0), ++ base + PCI_REG_CFG_CBE); + -+# -+# CPU may reorder reads and writes beyond LL/SC -+# CPU may reorder R->LL, R->LL, W->LL, W->LL, R->SC, R->SC, W->SC, W->SC -+# -+config WEAK_REORDERING_BEYOND_LLSC -+ bool -+endmenu ++ return ar71xx_pci_be_handler(1); ++} + -+# -+# These two indicate any level of the MIPS32 and MIPS64 architecture -+# -+config CPU_MIPS32 -+ bool -+ default y if CPU_MIPS32_R1 || CPU_MIPS32_R2 ++static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 *value) ++{ ++ void __iomem *base = ar71xx_pcicfg_base; ++ static u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0}; ++ unsigned long flags; ++ u32 data; ++ int retry = 0; ++ int ret; + -+config CPU_MIPS64 -+ bool -+ default y if CPU_MIPS64_R1 || CPU_MIPS64_R2 ++ ret = PCIBIOS_SUCCESSFUL; + -+# -+# These two indicate the revision of the architecture, either Release 1 or Release 2 -+# -+config CPU_MIPSR1 -+ bool -+ default y if CPU_MIPS32_R1 || CPU_MIPS64_R1 ++ DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d\n", bus->number, ++ PCI_SLOT(devfn), PCI_FUNC(devfn), where, size); + -+config CPU_MIPSR2 -+ bool -+ default y if CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_CAVIUM_OCTEON ++retry: ++ spin_lock_irqsave(&ar71xx_pci_lock, flags); + -+config SYS_SUPPORTS_32BIT_KERNEL -+ bool -+config SYS_SUPPORTS_64BIT_KERNEL -+ bool -+config CPU_SUPPORTS_32BIT_KERNEL -+ bool -+config CPU_SUPPORTS_64BIT_KERNEL -+ bool -+config CPU_SUPPORTS_CPUFREQ -+ bool -+config CPU_SUPPORTS_ADDRWINCFG -+ bool -+config CPU_SUPPORTS_HUGEPAGES -+ bool -+config CPU_SUPPORTS_UNCACHED_ACCELERATED -+ bool -+config MIPS_PGD_C0_CONTEXT -+ bool -+ default y if 64BIT && CPU_MIPSR2 ++ if (bus->number == 0 && devfn == 0) { ++ u32 t; + -+# -+# Set to y for ptrace access to watch registers. -+# -+config HARDWARE_WATCHPOINTS -+ bool -+ default y if CPU_MIPSR1 || CPU_MIPSR2 ++ t = PCI_CRP_CMD_READ | (where & ~3); + -+menu "Kernel type" ++ __raw_writel(t, base + PCI_REG_CRP_AD_CBE); ++ data = __raw_readl(base + PCI_REG_CRP_RDDATA); + -+choice ++ DBG("PCI: rd local cfg, ad_cbe:%08x, data:%08x\n", t, data); + -+ prompt "Kernel code model" -+ help -+ You should only select this option if you have a workload that -+ actually benefits from 64-bit processing or if your machine has -+ large memory. You will only be presented a single option in this -+ menu if your system does not support both 32-bit and 64-bit kernels. -+ -+config 32BIT -+ bool "32-bit kernel" -+ depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL -+ select TRAD_SIGNALS -+ help -+ Select this option if you want to build a 32-bit kernel. -+config 64BIT -+ bool "64-bit kernel" -+ depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL -+ select HAVE_SYSCALL_WRAPPERS -+ help -+ Select this option if you want to build a 64-bit kernel. ++ } else { ++ int err; + -+endchoice ++ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, ++ PCI_CFG_CMD_READ); + -+choice -+ prompt "Kernel page size" -+ default PAGE_SIZE_4KB ++ if (err == 0) { ++ data = __raw_readl(base + PCI_REG_CFG_RDDATA); ++ } else { ++ ret = PCIBIOS_DEVICE_NOT_FOUND; ++ data = ~0; ++ } ++ } + -+config PAGE_SIZE_4KB -+ bool "4kB" -+ depends on !CPU_LOONGSON2 -+ help -+ This option select the standard 4kB Linux page size. On some -+ R3000-family processors this is the only available page size. Using -+ 4kB page size will minimize memory consumption and is therefore -+ recommended for low memory systems. -+ -+config PAGE_SIZE_8KB -+ bool "8kB" -+ depends on (EXPERIMENTAL && CPU_R8000) || CPU_CAVIUM_OCTEON -+ help -+ Using 8kB page size will result in higher performance kernel at -+ the price of higher memory consumption. This option is available -+ only on R8000 and cnMIPS processors. Note that you will need a -+ suitable Linux distribution to support this. -+ -+config PAGE_SIZE_16KB -+ bool "16kB" -+ depends on !CPU_R3000 && !CPU_TX39XX -+ help -+ Using 16kB page size will result in higher performance kernel at -+ the price of higher memory consumption. This option is available on -+ all non-R3000 family processors. Note that you will need a suitable -+ Linux distribution to support this. -+ -+config PAGE_SIZE_32KB -+ bool "32kB" -+ depends on CPU_CAVIUM_OCTEON -+ help -+ Using 32kB page size will result in higher performance kernel at -+ the price of higher memory consumption. This option is available -+ only on cnMIPS cores. Note that you will need a suitable Linux -+ distribution to support this. -+ -+config PAGE_SIZE_64KB -+ bool "64kB" -+ depends on EXPERIMENTAL && !CPU_R3000 && !CPU_TX39XX -+ help -+ Using 64kB page size will result in higher performance kernel at -+ the price of higher memory consumption. This option is available on -+ all non-R3000 family processor. Not that at the time of this -+ writing this option is still high experimental. -+ -+endchoice -+ -+config FORCE_MAX_ZONEORDER -+ int "Maximum zone order" -+ range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB -+ default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB -+ range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB -+ default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB -+ range 11 64 -+ default "11" -+ help -+ The kernel memory allocator divides physically contiguous memory -+ blocks into "zones", where each zone is a power of two number of -+ pages. This option selects the largest power of two that the kernel -+ keeps in the memory allocator. If you need to allocate very large -+ blocks of physically contiguous memory, then you may need to -+ increase this value. ++ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); + -+ This config option is actually maximum order plus one. For example, -+ a value of 11 means that the largest free memory block is 2^10 pages. ++ DBG("PCI: read config: data=%08x raw=%08x\n", ++ (data >> (8 * (where & 3))) & mask[size & 7], data); + -+ The page size is not necessarily 4KB. Keep this in mind -+ when choosing a value for this option. ++ *value = (data >> (8 * (where & 3))) & mask[size & 7]; + -+config BOARD_SCACHE -+ bool -+ -+config IP22_CPU_SCACHE -+ bool -+ select BOARD_SCACHE -+ -+# -+# Support for a MIPS32 / MIPS64 style S-caches -+# -+config MIPS_CPU_SCACHE -+ bool -+ select BOARD_SCACHE -+ -+config R5000_CPU_SCACHE -+ bool -+ select BOARD_SCACHE ++ /* ++ * PCI controller bug: sometimes reads to the PCI_COMMAND register ++ * return 0xffff, even though the PCI trace shows the correct value. ++ * Work around this by retrying reads to this register ++ */ ++ if (where == PCI_COMMAND && (*value & 0xffff) == 0xffff && retry++ < 2) ++ goto retry; + -+config RM7000_CPU_SCACHE -+ bool -+ select BOARD_SCACHE ++ return ret; ++} + -+config SIBYTE_DMA_PAGEOPS -+ bool "Use DMA to clear/copy pages" -+ depends on CPU_SB1 -+ help -+ Instead of using the CPU to zero and copy pages, use a Data Mover -+ channel. These DMA channels are otherwise unused by the standard -+ SiByte Linux port. Seems to give a small performance benefit. ++static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 value) ++{ ++ void __iomem *base = ar71xx_pcicfg_base; ++ unsigned long flags; ++ int ret; + -+config CPU_HAS_PREFETCH -+ bool ++ DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d value=%08x\n", ++ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), ++ where, size, value); + -+choice -+ prompt "MIPS MT options" ++ value = value << (8 * (where & 3)); ++ ret = PCIBIOS_SUCCESSFUL; + -+config MIPS_MT_DISABLED -+ bool "Disable multithreading support." -+ help -+ Use this option if your workload can't take advantage of -+ MIPS hardware multithreading support. On systems that don't have -+ the option of an MT-enabled processor this option will be the only -+ option in this menu. -+ -+config MIPS_MT_SMP -+ bool "Use 1 TC on each available VPE for SMP" -+ depends on SYS_SUPPORTS_MULTITHREADING -+ select CPU_MIPSR2_IRQ_VI -+ select CPU_MIPSR2_IRQ_EI -+ select MIPS_MT -+ select NR_CPUS_DEFAULT_2 -+ select SMP -+ select SYS_SUPPORTS_SCHED_SMT if SMP -+ select SYS_SUPPORTS_SMP -+ select SMP_UP -+ help -+ This is a kernel model which is known a VSMP but lately has been -+ marketesed into SMVP. -+ Virtual SMP uses the processor's VPEs to implement virtual -+ processors. In currently available configuration of the 34K processor -+ this allows for a dual processor. Both processors will share the same -+ primary caches; each will obtain the half of the TLB for it's own -+ exclusive use. For a layman this model can be described as similar to -+ what Intel calls Hyperthreading. -+ -+ For further information see http://www.linux-mips.org/wiki/34K#VSMP -+ -+config MIPS_MT_SMTC -+ bool "SMTC: Use all TCs on all VPEs for SMP" -+ depends on CPU_MIPS32_R2 -+ #depends on CPU_MIPS64_R2 # once there is hardware ... -+ depends on SYS_SUPPORTS_MULTITHREADING -+ select CPU_MIPSR2_IRQ_VI -+ select CPU_MIPSR2_IRQ_EI -+ select MIPS_MT -+ select NR_CPUS_DEFAULT_8 -+ select SMP -+ select SYS_SUPPORTS_SMP -+ select SMP_UP -+ help -+ This is a kernel model which is known a SMTC or lately has been -+ marketesed into SMVP. -+ is presenting the available TC's of the core as processors to Linux. -+ On currently available 34K processors this means a Linux system will -+ see up to 5 processors. The implementation of the SMTC kernel differs -+ significantly from VSMP and cannot efficiently coexist in the same -+ kernel binary so the choice between VSMP and SMTC is a compile time -+ decision. ++ spin_lock_irqsave(&ar71xx_pci_lock, flags); ++ if (bus->number == 0 && devfn == 0) { ++ u32 t; + -+ For further information see http://www.linux-mips.org/wiki/34K#SMTC ++ t = PCI_CRP_CMD_WRITE | (where & ~3); ++ t |= ar71xx_pci_get_ble(where, size, 1); + -+endchoice ++ DBG("PCI: wr local cfg, ad_cbe:%08x, value:%08x\n", t, value); + -+config MIPS_MT -+ bool ++ __raw_writel(t, base + PCI_REG_CRP_AD_CBE); ++ __raw_writel(value, base + PCI_REG_CRP_WRDATA); ++ } else { ++ int err; + -+config SCHED_SMT -+ bool "SMT (multithreading) scheduler support" -+ depends on SYS_SUPPORTS_SCHED_SMT -+ default n -+ help -+ SMT scheduler support improves the CPU scheduler's decision making -+ when dealing with MIPS MT enabled cores at a cost of slightly -+ increased overhead in some places. If unsure say N here. ++ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, ++ PCI_CFG_CMD_WRITE); + -+config SYS_SUPPORTS_SCHED_SMT -+ bool ++ if (err == 0) ++ __raw_writel(value, base + PCI_REG_CFG_WRDATA); ++ else ++ ret = PCIBIOS_DEVICE_NOT_FOUND; ++ } ++ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); + ++ return ret; ++} + -+config SYS_SUPPORTS_MULTITHREADING -+ bool ++static void ar71xx_pci_fixup(struct pci_dev *dev) ++{ ++ u32 t; + -+config MIPS_MT_FPAFF -+ bool "Dynamic FPU affinity for FP-intensive threads" -+ default y -+ depends on MIPS_MT_SMP || MIPS_MT_SMTC -+ -+config MIPS_VPE_LOADER -+ bool "VPE loader support." -+ depends on SYS_SUPPORTS_MULTITHREADING -+ select CPU_MIPSR2_IRQ_VI -+ select CPU_MIPSR2_IRQ_EI -+ select MIPS_MT -+ help -+ Includes a loader for loading an elf relocatable object -+ onto another VPE and running it. ++ if (!ar71xx_pci_fixup_enable) ++ return; + -+config MIPS_MT_SMTC_IM_BACKSTOP -+ bool "Use per-TC register bits as backstop for inhibited IM bits" -+ depends on MIPS_MT_SMTC -+ default n -+ help -+ To support multiple TC microthreads acting as "CPUs" within -+ a VPE, VPE-wide interrupt mask bits must be specially manipulated -+ during interrupt handling. To support legacy drivers and interrupt -+ controller management code, SMTC has a "backstop" to track and -+ if necessary restore the interrupt mask. This has some performance -+ impact on interrupt service overhead. -+ -+config MIPS_MT_SMTC_IRQAFF -+ bool "Support IRQ affinity API" -+ depends on MIPS_MT_SMTC -+ default n -+ help -+ Enables SMP IRQ affinity API (/proc/irq/*/smp_affinity, etc.) -+ for SMTC Linux kernel. Requires platform support, of which -+ an example can be found in the MIPS kernel i8259 and Malta -+ platform code. Adds some overhead to interrupt dispatch, and -+ should be used only if you know what you are doing. -+ -+config MIPS_VPE_LOADER_TOM -+ bool "Load VPE program into memory hidden from linux" -+ depends on MIPS_VPE_LOADER -+ default y -+ help -+ The loader can use memory that is present but has been hidden from -+ Linux using the kernel command line option "mem=xxMB". It's up to -+ you to ensure the amount you put in the option and the space your -+ program requires is less or equal to the amount physically present. -+ -+# this should possibly be in drivers/char, but it is rather cpu related. Hmmm -+config MIPS_VPE_APSP_API -+ bool "Enable support for AP/SP API (RTLX)" -+ depends on MIPS_VPE_LOADER -+ help ++ if (dev->bus->number != 0 || dev->devfn != 0) ++ return; + -+config MIPS_APSP_KSPD -+ bool "Enable KSPD" -+ depends on MIPS_VPE_APSP_API -+ default y -+ help -+ KSPD is a kernel daemon that accepts syscall requests from the SP -+ side, actions them and returns the results. It also handles the -+ "exit" syscall notifying other kernel modules the SP program is -+ exiting. You probably want to say yes here. -+ -+config MIPS_CMP -+ bool "MIPS CMP framework support" -+ depends on SYS_SUPPORTS_MIPS_CMP -+ select SYNC_R4K -+ select SYS_SUPPORTS_SMP -+ select SYS_SUPPORTS_SCHED_SMT if SMP -+ select WEAK_ORDERING -+ default n -+ help -+ This is a placeholder option for the GCMP work. It will need to -+ be handled differently... ++ DBG("PCI: fixup host controller %s (%04x:%04x)\n", pci_name(dev), ++ dev->vendor, dev->device); + -+config SB1_PASS_1_WORKAROUNDS -+ bool -+ depends on CPU_SB1_PASS_1 -+ default y ++ /* setup COMMAND register */ ++ t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE ++ | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; + -+config SB1_PASS_2_WORKAROUNDS -+ bool -+ depends on CPU_SB1 && (CPU_SB1_PASS_2_2 || CPU_SB1_PASS_2) -+ default y ++ pci_write_config_word(dev, PCI_COMMAND, t); ++} ++DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar71xx_pci_fixup); + -+config SB1_PASS_2_1_WORKAROUNDS -+ bool -+ depends on CPU_SB1 && CPU_SB1_PASS_2 -+ default y ++int __init ar71xx_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, ++ uint8_t pin) ++{ ++ int irq = -1; ++ int i; + -+config 64BIT_PHYS_ADDR -+ bool ++ slot -= PCI_IDSEL_ADL_START - PCI_IDSEL_BASE; + -+config ARCH_PHYS_ADDR_T_64BIT -+ def_bool 64BIT_PHYS_ADDR ++ for (i = 0; i < ar71xx_pci_nr_irqs; i++) { ++ struct ar71xx_pci_irq *entry; + -+config CPU_HAS_SMARTMIPS -+ depends on SYS_SUPPORTS_SMARTMIPS -+ bool "Support for the SmartMIPS ASE" -+ help -+ SmartMIPS is a extension of the MIPS32 architecture aimed at -+ increased security at both hardware and software level for -+ smartcards. Enabling this option will allow proper use of the -+ SmartMIPS instructions by Linux applications. However a kernel with -+ this option will not work on a MIPS core without SmartMIPS core. If -+ you don't know you probably don't have SmartMIPS and should say N -+ here. -+ -+config CPU_HAS_WB -+ bool ++ entry = &ar71xx_pci_irq_map[i]; ++ if (entry->slot == slot && entry->pin == pin) { ++ irq = entry->irq; ++ break; ++ } ++ } + -+# -+# Vectored interrupt mode is an R2 feature -+# -+config CPU_MIPSR2_IRQ_VI -+ bool ++ if (irq < 0) { ++ printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n", ++ pin, pci_name((struct pci_dev *)dev)); ++ } else { ++ printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n", ++ irq, pin, pci_name((struct pci_dev *)dev)); ++ } + -+# -+# Extended interrupt mode is an R2 feature -+# -+config CPU_MIPSR2_IRQ_EI -+ bool ++ return irq; ++} + -+config CPU_HAS_SYNC -+ bool -+ depends on !CPU_R3000 -+ default y ++static struct pci_ops ar71xx_pci_ops = { ++ .read = ar71xx_pci_read_config, ++ .write = ar71xx_pci_write_config, ++}; + -+config GENERIC_CLOCKEVENTS_BROADCAST -+ bool ++static struct resource ar71xx_pci_io_resource = { ++ .name = "PCI IO space", ++ .start = 0, ++ .end = 0, ++ .flags = IORESOURCE_IO, ++}; + -+# -+# CPU non-features -+# -+config CPU_DADDI_WORKAROUNDS -+ bool ++static struct resource ar71xx_pci_mem_resource = { ++ .name = "PCI memory space", ++ .start = AR71XX_PCI_MEM_BASE, ++ .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, ++ .flags = IORESOURCE_MEM ++}; + -+config CPU_R4000_WORKAROUNDS -+ bool -+ select CPU_R4400_WORKAROUNDS ++static struct pci_controller ar71xx_pci_controller = { ++ .pci_ops = &ar71xx_pci_ops, ++ .mem_resource = &ar71xx_pci_mem_resource, ++ .io_resource = &ar71xx_pci_io_resource, ++}; + -+config CPU_R4400_WORKAROUNDS -+ bool ++static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) ++{ ++ void __iomem *base = ar71xx_reset_base; ++ u32 pending; + -+# -+# - Highmem only makes sense for the 32-bit kernel. -+# - The current highmem code will only work properly on physically indexed -+# caches such as R3000, SB1, R7000 or those that look like they're virtually -+# indexed such as R4000/R4400 SC and MC versions or R10000. So for the -+# moment we protect the user and offer the highmem option only on machines -+# where it's known to be safe. This will not offer highmem on a few systems -+# such as MIPS32 and MIPS64 CPUs which may have virtual and physically -+# indexed CPUs but we're playing safe. -+# - We use SYS_SUPPORTS_HIGHMEM to offer highmem only for systems where we -+# know they might have memory configurations that could make use of highmem -+# support. -+# -+config HIGHMEM -+ bool "High Memory Support" -+ depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM ++ pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) & ++ __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); + -+config CPU_SUPPORTS_HIGHMEM -+ bool ++ if (pending & PCI_INT_DEV0) ++ generic_handle_irq(AR71XX_PCI_IRQ_DEV0); + -+config SYS_SUPPORTS_HIGHMEM -+ bool ++ else if (pending & PCI_INT_DEV1) ++ generic_handle_irq(AR71XX_PCI_IRQ_DEV1); + -+config SYS_SUPPORTS_SMARTMIPS -+ bool ++ else if (pending & PCI_INT_DEV2) ++ generic_handle_irq(AR71XX_PCI_IRQ_DEV2); + -+config ARCH_FLATMEM_ENABLE -+ def_bool y -+ depends on !NUMA && !CPU_LOONGSON2 ++ else if (pending & PCI_INT_CORE) ++ generic_handle_irq(AR71XX_PCI_IRQ_CORE); + -+config ARCH_DISCONTIGMEM_ENABLE -+ bool -+ default y if SGI_IP27 -+ help -+ Say Y to support efficient handling of discontiguous physical memory, -+ for architectures which are either NUMA (Non-Uniform Memory Access) -+ or have huge holes in the physical address space for other reasons. -+ See for more. ++ else ++ spurious_interrupt(); ++} + -+config ARCH_POPULATES_NODE_MAP -+ def_bool y ++static void ar71xx_pci_irq_unmask(struct irq_data *d) ++{ ++ unsigned int irq = d->irq - AR71XX_PCI_IRQ_BASE; ++ void __iomem *base = ar71xx_reset_base; ++ u32 t; + -+config ARCH_SPARSEMEM_ENABLE -+ bool -+ select SPARSEMEM_STATIC ++ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); + -+config NUMA -+ bool "NUMA Support" -+ depends on SYS_SUPPORTS_NUMA -+ help -+ Say Y to compile the kernel to support NUMA (Non-Uniform Memory -+ Access). This option improves performance on systems with more -+ than two nodes; on two node systems it is generally better to -+ leave it disabled; on single node systems disable this option -+ disabled. ++ /* flush write */ ++ (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++} + -+config SYS_SUPPORTS_NUMA -+ bool ++static void ar71xx_pci_irq_mask(struct irq_data *d) ++{ ++ unsigned int irq = d->irq - AR71XX_PCI_IRQ_BASE; ++ void __iomem *base = ar71xx_reset_base; ++ u32 t; + -+config NODES_SHIFT -+ int -+ default "6" -+ depends on NEED_MULTIPLE_NODES ++ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); + -+config HW_PERF_EVENTS -+ bool "Enable hardware performance counter support for perf events" -+ depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && CPU_MIPS32 -+ default y -+ help -+ Enable hardware performance counter support for perf events. If -+ disabled, perf events will use software events only. ++ /* flush write */ ++ (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++} + -+source "mm/Kconfig" ++static struct irq_chip ar71xx_pci_irq_chip = { ++ .name = "AR71XX PCI ", ++ .irq_mask = ar71xx_pci_irq_mask, ++ .irq_unmask = ar71xx_pci_irq_unmask, ++ .irq_mask_ack = ar71xx_pci_irq_mask, ++}; + -+config SMP -+ bool "Multi-Processing support" -+ depends on SYS_SUPPORTS_SMP -+ select IRQ_PER_CPU -+ select USE_GENERIC_SMP_HELPERS -+ help -+ This enables support for systems with more than one CPU. If you have -+ a system with only one CPU, like most personal computers, say N. If -+ you have a system with more than one CPU, say Y. ++static void __init ar71xx_pci_irq_init(void) ++{ ++ void __iomem *base = ar71xx_reset_base; ++ int i; + -+ If you say N here, the kernel will run on single and multiprocessor -+ machines, but will use only one CPU of a multiprocessor machine. If -+ you say Y here, the kernel will run on many, but not all, -+ singleprocessor machines. On a singleprocessor machine, the kernel -+ will run faster if you say N here. ++ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS); + -+ People using multiprocessor machines who say Y here should also say -+ Y to "Enhanced Real Time Clock Support", below. ++ for (i = AR71XX_PCI_IRQ_BASE; ++ i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) ++ irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip, ++ handle_level_irq); + -+ See also the SMP-HOWTO available at -+ . ++ irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar71xx_pci_irq_handler); ++} + -+ If you don't know what to do here, say N. ++int __init ar71xx_pcibios_init(void) ++{ ++ void __iomem *ddr_base = ar71xx_ddr_base; + -+config SMP_UP -+ bool ++ ar71xx_device_stop(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE); ++ ar71xx_pci_delay(); + -+config SYS_SUPPORTS_MIPS_CMP -+ bool ++ ar71xx_device_start(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE); ++ ar71xx_pci_delay(); + -+config SYS_SUPPORTS_SMP -+ bool ++ ar71xx_pcicfg_base = ioremap_nocache(AR71XX_PCI_CFG_BASE, ++ AR71XX_PCI_CFG_SIZE); ++ if (ar71xx_pcicfg_base == NULL) ++ return -ENOMEM; + -+config NR_CPUS_DEFAULT_1 -+ bool ++ __raw_writel(PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0); ++ __raw_writel(PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1); ++ __raw_writel(PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2); ++ __raw_writel(PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3); ++ __raw_writel(PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4); ++ __raw_writel(PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5); ++ __raw_writel(PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6); ++ __raw_writel(PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7); + -+config NR_CPUS_DEFAULT_2 -+ bool ++ ar71xx_pci_delay(); + -+config NR_CPUS_DEFAULT_4 -+ bool ++ /* clear bus errors */ ++ (void)ar71xx_pci_be_handler(1); + -+config NR_CPUS_DEFAULT_8 -+ bool ++ ar71xx_pci_fixup_enable = 1; ++ ar71xx_pci_irq_init(); ++ register_pci_controller(&ar71xx_pci_controller); + -+config NR_CPUS_DEFAULT_16 -+ bool -+ -+config NR_CPUS_DEFAULT_32 -+ bool ++ return 0; ++} +diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c linux-2.6.39/arch/mips/pci/pci-ar724x.c +--- linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/arch/mips/pci/pci-ar724x.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,389 @@ ++/* ++ * Atheros AR724x PCI host controller driver ++ * ++ * Copyright (C) 2009-2010 Gabor Juhos ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+config NR_CPUS_DEFAULT_64 -+ bool ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+config NR_CPUS -+ int "Maximum number of CPUs (2-64)" -+ range 1 64 if NR_CPUS_DEFAULT_1 -+ depends on SMP -+ default "1" if NR_CPUS_DEFAULT_1 -+ default "2" if NR_CPUS_DEFAULT_2 -+ default "4" if NR_CPUS_DEFAULT_4 -+ default "8" if NR_CPUS_DEFAULT_8 -+ default "16" if NR_CPUS_DEFAULT_16 -+ default "32" if NR_CPUS_DEFAULT_32 -+ default "64" if NR_CPUS_DEFAULT_64 -+ help -+ This allows you to specify the maximum number of CPUs which this -+ kernel will support. The maximum supported value is 32 for 32-bit -+ kernel and 64 for 64-bit kernels; the minimum value which makes -+ sense is 1 for Qemu (useful only for kernel debugging purposes) -+ and 2 for all others. ++#include ++#include + -+ This is purely to save memory - each supported CPU adds -+ approximately eight kilobytes to the kernel image. For best -+ performance should round up your number of processors to the next -+ power of two. ++#undef DEBUG ++#ifdef DEBUG ++#define DBG(fmt, args...) printk(KERN_INFO fmt, ## args) ++#else ++#define DBG(fmt, args...) ++#endif + -+source "kernel/time/Kconfig" ++static void __iomem *ar724x_pci_localcfg_base; ++static void __iomem *ar724x_pci_devcfg_base; ++static void __iomem *ar724x_pci_ctrl_base; ++static int ar724x_pci_fixup_enable; + -+# -+# Timer Interrupt Frequency Configuration -+# ++static DEFINE_SPINLOCK(ar724x_pci_lock); + -+choice -+ prompt "Timer frequency" -+ default HZ_250 -+ help -+ Allows the configuration of the timer frequency. ++static void ar724x_pci_read(void __iomem *base, int where, int size, u32 *value) ++{ ++ unsigned long flags; ++ u32 data; + -+ config HZ_48 -+ bool "48 HZ" if SYS_SUPPORTS_48HZ || SYS_SUPPORTS_ARBIT_HZ ++ spin_lock_irqsave(&ar724x_pci_lock, flags); ++ data = __raw_readl(base + (where & ~3)); + -+ config HZ_100 -+ bool "100 HZ" if SYS_SUPPORTS_100HZ || SYS_SUPPORTS_ARBIT_HZ ++ switch (size) { ++ case 1: ++ if (where & 1) ++ data >>= 8; ++ if (where & 2) ++ data >>= 16; ++ data &= 0xFF; ++ break; ++ case 2: ++ if (where & 2) ++ data >>= 16; ++ data &= 0xFFFF; ++ break; ++ } + -+ config HZ_128 -+ bool "128 HZ" if SYS_SUPPORTS_128HZ || SYS_SUPPORTS_ARBIT_HZ ++ *value = data; ++ spin_unlock_irqrestore(&ar724x_pci_lock, flags); ++} + -+ config HZ_250 -+ bool "250 HZ" if SYS_SUPPORTS_250HZ || SYS_SUPPORTS_ARBIT_HZ ++static void ar724x_pci_write(void __iomem *base, int where, int size, u32 value) ++{ ++ unsigned long flags; ++ u32 data; ++ int s; + -+ config HZ_256 -+ bool "256 HZ" if SYS_SUPPORTS_256HZ || SYS_SUPPORTS_ARBIT_HZ ++ spin_lock_irqsave(&ar724x_pci_lock, flags); ++ data = __raw_readl(base + (where & ~3)); + -+ config HZ_1000 -+ bool "1000 HZ" if SYS_SUPPORTS_1000HZ || SYS_SUPPORTS_ARBIT_HZ ++ switch (size) { ++ case 1: ++ s = ((where & 3) << 3); ++ data &= ~(0xFF << s); ++ data |= ((value & 0xFF) << s); ++ break; ++ case 2: ++ s = ((where & 2) << 3); ++ data &= ~(0xFFFF << s); ++ data |= ((value & 0xFFFF) << s); ++ break; ++ case 4: ++ data = value; ++ break; ++ } + -+ config HZ_1024 -+ bool "1024 HZ" if SYS_SUPPORTS_1024HZ || SYS_SUPPORTS_ARBIT_HZ ++ __raw_writel(data, base + (where & ~3)); ++ /* flush write */ ++ (void)__raw_readl(base + (where & ~3)); ++ spin_unlock_irqrestore(&ar724x_pci_lock, flags); ++} + -+endchoice ++static int ar724x_pci_read_config(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 *value) ++{ + -+config SYS_SUPPORTS_48HZ -+ bool ++ if (bus->number != 0 || devfn != 0) ++ return PCIBIOS_DEVICE_NOT_FOUND; + -+config SYS_SUPPORTS_100HZ -+ bool ++ ar724x_pci_read(ar724x_pci_devcfg_base, where, size, value); + -+config SYS_SUPPORTS_128HZ -+ bool ++ DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d, value=%08x\n", ++ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), ++ where, size, *value); + -+config SYS_SUPPORTS_250HZ -+ bool ++ /* ++ * WAR for BAR issue - We are unable to access the PCI device space ++ * if we set the BAR with proper base address ++ */ ++ if ((where == 0x10) && (size == 4)) { ++ u32 val; ++ val = (ar71xx_soc == AR71XX_SOC_AR7240) ? 0xffff : 0x1000ffff; ++ ar724x_pci_write(ar724x_pci_devcfg_base, where, size, val); ++ } + -+config SYS_SUPPORTS_256HZ -+ bool ++ return PCIBIOS_SUCCESSFUL; ++} + -+config SYS_SUPPORTS_1000HZ -+ bool ++static int ar724x_pci_write_config(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 value) ++{ ++ if (bus->number != 0 || devfn != 0) ++ return PCIBIOS_DEVICE_NOT_FOUND; + -+config SYS_SUPPORTS_1024HZ -+ bool ++ DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d, value=%08x\n", ++ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), ++ where, size, value); + -+config SYS_SUPPORTS_ARBIT_HZ -+ bool -+ default y if !SYS_SUPPORTS_48HZ && !SYS_SUPPORTS_100HZ && \ -+ !SYS_SUPPORTS_128HZ && !SYS_SUPPORTS_250HZ && \ -+ !SYS_SUPPORTS_256HZ && !SYS_SUPPORTS_1000HZ && \ -+ !SYS_SUPPORTS_1024HZ -+ -+config HZ -+ int -+ default 48 if HZ_48 -+ default 100 if HZ_100 -+ default 128 if HZ_128 -+ default 250 if HZ_250 -+ default 256 if HZ_256 -+ default 1000 if HZ_1000 -+ default 1024 if HZ_1024 -+ -+source "kernel/Kconfig.preempt" -+ -+config MIPS_INSANE_LARGE -+ bool "Support for large 64-bit configurations" -+ depends on CPU_R10000 && 64BIT -+ help -+ MIPS R10000 does support a 44 bit / 16TB address space as opposed to -+ previous 64-bit processors which only supported 40 bit / 1TB. If you -+ need processes of more than 1TB virtual address space, say Y here. -+ This will result in additional memory usage, so it is not -+ recommended for normal users. -+ -+config KEXEC -+ bool "Kexec system call (EXPERIMENTAL)" -+ depends on EXPERIMENTAL -+ help -+ kexec is a system call that implements the ability to shutdown your -+ current kernel, and to start another kernel. It is like a reboot -+ but it is independent of the system firmware. And like a reboot -+ you can start any kernel with it, not just Linux. -+ -+ The name comes from the similarity to the exec system call. -+ -+ It is an ongoing process to be certain the hardware in a machine -+ is properly shutdown, so do not be surprised if this code does not -+ initially work for you. It may help to enable device hotplugging -+ support. As of this writing the exact hardware interface is -+ strongly in flux, so no good recommendation can be made. -+ -+config SECCOMP -+ bool "Enable seccomp to safely compute untrusted bytecode" -+ depends on PROC_FS -+ default y -+ help -+ This kernel feature is useful for number crunching applications -+ that may need to compute untrusted bytecode during their -+ execution. By using pipes or other transports made available to -+ the process as file descriptors supporting the read/write -+ syscalls, it's possible to isolate those applications in -+ their own address space using seccomp. Once seccomp is -+ enabled via /proc//seccomp, it cannot be disabled -+ and the task is only allowed to execute a few safe syscalls -+ defined by each seccomp mode. -+ -+ If unsure, say Y. Only embedded should say N here. -+ -+config USE_OF -+ bool "Flattened Device Tree support" -+ select OF -+ select OF_EARLY_FLATTREE -+ help -+ Include support for flattened device tree machine descriptions. ++ ar724x_pci_write(ar724x_pci_devcfg_base, where, size, value); + -+endmenu ++ return PCIBIOS_SUCCESSFUL; ++} + -+config LOCKDEP_SUPPORT -+ bool -+ default y ++static void ar724x_pci_fixup(struct pci_dev *dev) ++{ ++ u16 cmd; + -+config STACKTRACE_SUPPORT -+ bool -+ default y ++ if (!ar724x_pci_fixup_enable) ++ return; + -+source "init/Kconfig" ++ if (dev->bus->number != 0 || dev->devfn != 0) ++ return; + -+source "kernel/Kconfig.freezer" ++ /* setup COMMAND register */ ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | ++ PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | ++ PCI_COMMAND_FAST_BACK; + -+menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++} ++DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar724x_pci_fixup); + -+config HW_HAS_EISA -+ bool -+config HW_HAS_PCI -+ bool ++int __init ar724x_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, ++ uint8_t pin) ++{ ++ int irq = -1; ++ int i; + -+config PCI -+ bool "Support for PCI controller" -+ depends on HW_HAS_PCI -+ select PCI_DOMAINS -+ help -+ Find out whether you have a PCI motherboard. PCI is the name of a -+ bus system, i.e. the way the CPU talks to the other stuff inside -+ your box. Other bus systems are ISA, EISA, or VESA. If you have PCI, -+ say Y, otherwise N. ++ for (i = 0; i < ar71xx_pci_nr_irqs; i++) { ++ struct ar71xx_pci_irq *entry; ++ entry = &ar71xx_pci_irq_map[i]; + -+config PCI_DOMAINS -+ bool ++ if (entry->slot == slot && entry->pin == pin) { ++ irq = entry->irq; ++ break; ++ } ++ } + -+source "drivers/pci/Kconfig" ++ if (irq < 0) ++ printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n", ++ pin, pci_name((struct pci_dev *)dev)); ++ else ++ printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n", ++ irq, pin, pci_name((struct pci_dev *)dev)); + -+# -+# ISA support is now enabled via select. Too many systems still have the one -+# or other ISA chip on the board that users don't know about so don't expect -+# users to choose the right thing ... -+# -+config ISA -+ bool ++ return irq; ++} + -+config EISA -+ bool "EISA support" -+ depends on HW_HAS_EISA -+ select ISA -+ select GENERIC_ISA_DMA -+ ---help--- -+ The Extended Industry Standard Architecture (EISA) bus was -+ developed as an open alternative to the IBM MicroChannel bus. ++static struct pci_ops ar724x_pci_ops = { ++ .read = ar724x_pci_read_config, ++ .write = ar724x_pci_write_config, ++}; + -+ The EISA bus provided some of the features of the IBM MicroChannel -+ bus while maintaining backward compatibility with cards made for -+ the older ISA bus. The EISA bus saw limited use between 1988 and -+ 1995 when it was made obsolete by the PCI bus. ++static struct resource ar724x_pci_io_resource = { ++ .name = "PCI IO space", ++ .start = 0, ++ .end = 0, ++ .flags = IORESOURCE_IO, ++}; + -+ Say Y here if you are building a kernel for an EISA-based machine. ++static struct resource ar724x_pci_mem_resource = { ++ .name = "PCI memory space", ++ .start = AR71XX_PCI_MEM_BASE, ++ .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, ++ .flags = IORESOURCE_MEM ++}; + -+ Otherwise, say N. ++static struct pci_controller ar724x_pci_controller = { ++ .pci_ops = &ar724x_pci_ops, ++ .mem_resource = &ar724x_pci_mem_resource, ++ .io_resource = &ar724x_pci_io_resource, ++}; + -+source "drivers/eisa/Kconfig" ++static void __init ar724x_pci_reset(void) ++{ ++ ar71xx_device_stop(AR724X_RESET_PCIE); ++ ar71xx_device_stop(AR724X_RESET_PCIE_PHY); ++ ar71xx_device_stop(AR724X_RESET_PCIE_PHY_SERIAL); ++ udelay(100); + -+config TC -+ bool "TURBOchannel support" -+ depends on MACH_DECSTATION -+ help -+ TURBOchannel is a DEC (now Compaq (now HP)) bus for Alpha and MIPS -+ processors. TURBOchannel programming specifications are available -+ at: -+ -+ and: -+ -+ Linux driver support status is documented at: -+ -+ -+#config ACCESSBUS -+# bool "Access.Bus support" -+# depends on TC -+ -+config MMU -+ bool -+ default y ++ ar71xx_device_start(AR724X_RESET_PCIE_PHY_SERIAL); ++ udelay(100); ++ ar71xx_device_start(AR724X_RESET_PCIE_PHY); ++ ar71xx_device_start(AR724X_RESET_PCIE); ++} + -+config I8253 -+ bool -+ select MIPS_EXTERNAL_TIMER ++static int __init ar724x_pci_setup(void) ++{ ++ void __iomem *base = ar724x_pci_ctrl_base; ++ u32 t; + -+config ZONE_DMA32 -+ bool ++ /* setup COMMAND register */ ++ t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | ++ PCI_COMMAND_PARITY|PCI_COMMAND_SERR|PCI_COMMAND_FAST_BACK; + -+source "drivers/pcmcia/Kconfig" ++ ar724x_pci_write(ar724x_pci_localcfg_base, PCI_COMMAND, 4, t); ++ ar724x_pci_write(ar724x_pci_localcfg_base, 0x20, 4, 0x1ff01000); ++ ar724x_pci_write(ar724x_pci_localcfg_base, 0x24, 4, 0x1ff01000); + -+source "drivers/pci/hotplug/Kconfig" ++ t = __raw_readl(base + AR724X_PCI_REG_RESET); ++ if (t != 0x7) { ++ udelay(100000); ++ __raw_writel(0, base + AR724X_PCI_REG_RESET); ++ udelay(100); ++ __raw_writel(4, base + AR724X_PCI_REG_RESET); ++ udelay(100000); ++ } + -+config RAPIDIO -+ bool "RapidIO support" -+ depends on PCI -+ default n -+ help -+ If you say Y here, the kernel will include drivers and -+ infrastructure code to support RapidIO interconnect devices. ++ if (ar71xx_soc == AR71XX_SOC_AR7240) ++ t = AR724X_PCI_APP_LTSSM_ENABLE; ++ else ++ t = 0x1ffc1; ++ __raw_writel(t, base + AR724X_PCI_REG_APP); ++ /* flush write */ ++ (void) __raw_readl(base + AR724X_PCI_REG_APP); ++ udelay(1000); + -+source "drivers/rapidio/Kconfig" ++ t = __raw_readl(base + AR724X_PCI_REG_RESET); ++ if ((t & AR724X_PCI_RESET_LINK_UP) == 0x0) { ++ printk(KERN_WARNING "PCI: no PCIe module found\n"); ++ return -ENODEV; ++ } + -+endmenu -+ -+menu "Executable file formats" -+ -+source "fs/Kconfig.binfmt" -+ -+config TRAD_SIGNALS -+ bool -+ -+config MIPS32_COMPAT -+ bool "Kernel support for Linux/MIPS 32-bit binary compatibility" -+ depends on 64BIT -+ help -+ Select this option if you want Linux/MIPS 32-bit binary -+ compatibility. Since all software available for Linux/MIPS is -+ currently 32-bit you should say Y here. -+ -+config COMPAT -+ bool -+ depends on MIPS32_COMPAT -+ default y ++ if (ar71xx_soc == AR71XX_SOC_AR7241 || ++ ar71xx_soc == AR71XX_SOC_AR7242) { ++ t = __raw_readl(base + AR724X_PCI_REG_APP); ++ t |= BIT(16); ++ __raw_writel(t, base + AR724X_PCI_REG_APP); ++ } + -+config SYSVIPC_COMPAT -+ bool -+ depends on COMPAT && SYSVIPC -+ default y ++ return 0; ++} + -+config MIPS32_O32 -+ bool "Kernel support for o32 binaries" -+ depends on MIPS32_COMPAT -+ help -+ Select this option if you want to run o32 binaries. These are pure -+ 32-bit binaries as used by the 32-bit Linux/MIPS port. Most of -+ existing binaries are in this format. ++static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) ++{ ++ void __iomem *base = ar724x_pci_ctrl_base; ++ u32 pending; + -+ If unsure, say Y. ++ pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & ++ __raw_readl(base + AR724X_PCI_REG_INT_MASK); + -+config MIPS32_N32 -+ bool "Kernel support for n32 binaries" -+ depends on MIPS32_COMPAT -+ help -+ Select this option if you want to run n32 binaries. These are -+ 64-bit binaries using 32-bit quantities for addressing and certain -+ data that would normally be 64-bit. They are used in special -+ cases. ++ if (pending & AR724X_PCI_INT_DEV0) ++ generic_handle_irq(AR71XX_PCI_IRQ_DEV0); + -+ If unsure, say N. ++ else ++ spurious_interrupt(); ++} + -+config BINFMT_ELF32 -+ bool -+ default y if MIPS32_O32 || MIPS32_N32 ++static void ar724x_pci_irq_unmask(struct irq_data *d) ++{ ++ void __iomem *base = ar724x_pci_ctrl_base; ++ u32 t; + -+endmenu ++ switch (d->irq) { ++ case AR71XX_PCI_IRQ_DEV0: ++ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ __raw_writel(t | AR724X_PCI_INT_DEV0, ++ base + AR724X_PCI_REG_INT_MASK); ++ /* flush write */ ++ (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ } ++} + -+menu "Power management options" ++static void ar724x_pci_irq_mask(struct irq_data *d) ++{ ++ void __iomem *base = ar724x_pci_ctrl_base; ++ u32 t; + -+config ARCH_HIBERNATION_POSSIBLE -+ def_bool y -+ depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP ++ switch (d->irq) { ++ case AR71XX_PCI_IRQ_DEV0: ++ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ __raw_writel(t & ~AR724X_PCI_INT_DEV0, ++ base + AR724X_PCI_REG_INT_MASK); + -+config ARCH_SUSPEND_POSSIBLE -+ def_bool y -+ depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP ++ /* flush write */ ++ (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK); + -+source "kernel/power/Kconfig" ++ t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS); ++ __raw_writel(t | AR724X_PCI_INT_DEV0, ++ base + AR724X_PCI_REG_INT_STATUS); + -+endmenu ++ /* flush write */ ++ (void) __raw_readl(base + AR724X_PCI_REG_INT_STATUS); ++ } ++} + -+source "arch/mips/kernel/cpufreq/Kconfig" ++static struct irq_chip ar724x_pci_irq_chip = { ++ .name = "AR724X PCI ", ++ .irq_mask = ar724x_pci_irq_mask, ++ .irq_unmask = ar724x_pci_irq_unmask, ++ .irq_mask_ack = ar724x_pci_irq_mask, ++}; + -+source "net/Kconfig" ++static void __init ar724x_pci_irq_init(void) ++{ ++ void __iomem *base = ar724x_pci_ctrl_base; ++ u32 t; ++ int i; + -+source "drivers/Kconfig" ++ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); ++ if (t & (AR724X_RESET_PCIE | AR724X_RESET_PCIE_PHY | ++ AR724X_RESET_PCIE_PHY_SERIAL)) { ++ return; ++ } + -+source "fs/Kconfig" ++ __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); ++ __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); + -+source "arch/mips/Kconfig.debug" ++ for (i = AR71XX_PCI_IRQ_BASE; ++ i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) ++ irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, ++ handle_level_irq); + -+source "security/Kconfig" ++ irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar724x_pci_irq_handler); ++} + -+source "crypto/Kconfig" ++int __init ar724x_pcibios_init(void) ++{ ++ int ret = -ENOMEM; + -+menuconfig VIRTUALIZATION -+ bool "Virtualization" -+ default n -+ ---help--- -+ Say Y here to get to see options for using your Linux host to run other -+ operating systems inside virtual machines (guests). -+ This option alone does not add any kernel code. ++ ar724x_pci_localcfg_base = ioremap_nocache(AR724X_PCI_CRP_BASE, ++ AR724X_PCI_CRP_SIZE); ++ if (ar724x_pci_localcfg_base == NULL) ++ goto err; + -+ If you say N, all options in this submenu will be skipped and disabled. ++ ar724x_pci_devcfg_base = ioremap_nocache(AR724X_PCI_CFG_BASE, ++ AR724X_PCI_CFG_SIZE); ++ if (ar724x_pci_devcfg_base == NULL) ++ goto err_unmap_localcfg; + -+if VIRTUALIZATION ++ ar724x_pci_ctrl_base = ioremap_nocache(AR724X_PCI_CTRL_BASE, ++ AR724X_PCI_CTRL_SIZE); ++ if (ar724x_pci_ctrl_base == NULL) ++ goto err_unmap_devcfg; + -+source drivers/virtio/Kconfig ++ ar724x_pci_reset(); ++ ret = ar724x_pci_setup(); ++ if (ret) ++ goto err_unmap_ctrl; + -+endif # VIRTUALIZATION ++ ar724x_pci_fixup_enable = 1; ++ ar724x_pci_irq_init(); ++ register_pci_controller(&ar724x_pci_controller); + -+source "lib/Kconfig" -diff -Nur linux-2.6.39.orig/arch/mips/kernel/traps.c linux-2.6.39/arch/mips/kernel/traps.c ---- linux-2.6.39.orig/arch/mips/kernel/traps.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/kernel/traps.c 2011-08-24 05:53:05.179230891 +0200 -@@ -54,6 +54,7 @@ - #include - #include - #include -+#include - - extern void check_wait(void); - extern asmlinkage void r4k_wait(void); -@@ -1576,6 +1577,8 @@ - if (cpu_has_mips_r2) { - cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; - cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; -+ if (get_c0_compare_irq) -+ cp0_compare_irq = get_c0_compare_irq(); - cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7; - if (cp0_perfcount_irq == cp0_compare_irq) - cp0_perfcount_irq = -1; -diff -Nur linux-2.6.39.orig/arch/mips/Makefile linux-2.6.39/arch/mips/Makefile ---- linux-2.6.39.orig/arch/mips/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/Makefile 2011-08-24 02:42:39.917989402 +0200 -@@ -158,6 +158,13 @@ - endif - cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1 - -+# -+# Atheros AR71xx -+# -+core-$(CONFIG_ATHEROS_AR71XX) += arch/mips/ar71xx/ -+cflags-$(CONFIG_ATHEROS_AR71XX) += -I$(srctree)/arch/mips/include/asm/mach-ar71xx -+load-$(CONFIG_ATHEROS_AR71XX) += 0xffffffff80060000 ++ return 0; + - cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,) - cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,) - cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,) -@@ -174,6 +181,7 @@ - # - libs-$(CONFIG_ARC) += arch/mips/fw/arc/ - libs-$(CONFIG_CFE) += arch/mips/fw/cfe/ -+libs-$(CONFIG_MYLOADER) += arch/mips/fw/myloader/ - libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/ - libs-y += arch/mips/fw/lib/ - -diff -Nur linux-2.6.39.orig/arch/mips/pci/Makefile linux-2.6.39/arch/mips/pci/Makefile ---- linux-2.6.39.orig/arch/mips/pci/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/mips/pci/Makefile 2011-08-22 16:21:37.437981205 +0200 -@@ -18,6 +18,7 @@ - obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o - obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ - ops-bcm63xx.o -+obj-$(CONFIG_ATHEROS_AR71XX) += pci-ar71xx.o pci-ar724x.o - - # - # These are still pretty much in the old state, watch, go blind. -diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c linux-2.6.39/arch/mips/pci/pci-ar71xx.c ---- linux-2.6.39.orig/arch/mips/pci/pci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/pci/pci-ar71xx.c 2011-08-06 09:32:37.098016752 +0200 -@@ -0,0 +1,415 @@ ++err_unmap_ctrl: ++ iounmap(ar724x_pci_ctrl_base); ++err_unmap_devcfg: ++ iounmap(ar724x_pci_devcfg_base); ++err_unmap_localcfg: ++ iounmap(ar724x_pci_localcfg_base); ++err: ++ return ret; ++} +diff -Nur linux-2.6.39.orig/drivers/Makefile linux-2.6.39/drivers/Makefile +--- linux-2.6.39.orig/drivers/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/Makefile 2011-08-24 18:17:24.000000000 +0200 +@@ -46,8 +46,8 @@ + obj-$(CONFIG_SCSI) += scsi/ + obj-$(CONFIG_ATA) += ata/ + obj-$(CONFIG_TARGET_CORE) += target/ +-obj-$(CONFIG_MTD) += mtd/ + obj-$(CONFIG_SPI) += spi/ ++obj-$(CONFIG_MTD) += mtd/ + obj-y += net/ + obj-$(CONFIG_ATM) += atm/ + obj-$(CONFIG_FUSION) += message/ +diff -Nur linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c linux-2.6.39/drivers/gpio/nxp_74hc153.c +--- linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/gpio/nxp_74hc153.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,247 @@ +/* -+ * Atheros AR71xx PCI host controller driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz ++ * NXP 74HC153 - Dual 4-input multiplexer GPIO driver + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Copyright (C) 2010 Gabor Juhos + * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. + */ + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#undef DEBUG -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+#define AR71XX_PCI_DELAY 100 /* msecs */ ++#include ++#include ++#include ++#include ++#include ++#include + -+#if 0 -+#define PCI_IDSEL_BASE PCI_IDSEL_ADL_START -+#else -+#define PCI_IDSEL_BASE 0 -+#endif ++#define NXP_74HC153_NUM_GPIOS 8 ++#define NXP_74HC153_S0_MASK 0x1 ++#define NXP_74HC153_S1_MASK 0x2 ++#define NXP_74HC153_BANK_MASK 0x4 + -+static void __iomem *ar71xx_pcicfg_base; -+static DEFINE_SPINLOCK(ar71xx_pci_lock); -+static int ar71xx_pci_fixup_enable; ++struct nxp_74hc153_chip { ++ struct device *parent; ++ struct gpio_chip gpio_chip; ++ struct mutex lock; ++}; + -+static inline void ar71xx_pci_delay(void) ++static struct nxp_74hc153_chip *gpio_to_nxp(struct gpio_chip *gc) +{ -+ mdelay(AR71XX_PCI_DELAY); ++ return container_of(gc, struct nxp_74hc153_chip, gpio_chip); +} + -+/* Byte lane enable bits */ -+static u8 ble_table[4][4] = { -+ {0x0, 0xf, 0xf, 0xf}, -+ {0xe, 0xd, 0xb, 0x7}, -+ {0xc, 0xf, 0x3, 0xf}, -+ {0xf, 0xf, 0xf, 0xf}, -+}; -+ -+static inline u32 ar71xx_pci_get_ble(int where, int size, int local) ++static int nxp_74hc153_direction_input(struct gpio_chip *gc, unsigned offset) +{ -+ u32 t; ++ return 0; ++} + -+ t = ble_table[size & 3][where & 3]; -+ BUG_ON(t == 0xf); -+ t <<= (local) ? 20 : 4; -+ return t; ++static int nxp_74hc153_direction_output(struct gpio_chip *gc, ++ unsigned offset, int val) ++{ ++ return -EINVAL; +} + -+static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn, -+ int where) ++static int nxp_74hc153_get_value(struct gpio_chip *gc, unsigned offset) +{ -+ u32 ret; ++ struct nxp_74hc153_chip *nxp; ++ struct nxp_74hc153_platform_data *pdata; ++ unsigned s0; ++ unsigned s1; ++ unsigned pin; ++ int ret; + -+ if (!bus->number) { -+ /* type 0 */ -+ ret = (1 << (PCI_IDSEL_BASE + PCI_SLOT(devfn))) -+ | (PCI_FUNC(devfn) << 8) | (where & ~3); -+ } else { -+ /* type 1 */ -+ ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11) -+ | (PCI_FUNC(devfn) << 8) | (where & ~3) | 1; -+ } ++ nxp = gpio_to_nxp(gc); ++ pdata = nxp->parent->platform_data; ++ ++ s0 = !!(offset & NXP_74HC153_S0_MASK); ++ s1 = !!(offset & NXP_74HC153_S1_MASK); ++ pin = (offset & NXP_74HC153_BANK_MASK) ? pdata->gpio_pin_2y ++ : pdata->gpio_pin_1y; ++ ++ mutex_lock(&nxp->lock); ++ gpio_set_value(pdata->gpio_pin_s0, s0); ++ gpio_set_value(pdata->gpio_pin_s1, s1); ++ ret = gpio_get_value(pin); ++ mutex_unlock(&nxp->lock); + + return ret; +} + -+int ar71xx_pci_be_handler(int is_fixup) ++static void nxp_74hc153_set_value(struct gpio_chip *gc, ++ unsigned offset, int val) +{ -+ void __iomem *base = ar71xx_pcicfg_base; -+ u32 pci_err; -+ u32 ahb_err; ++ /* not supported */ ++} + -+ pci_err = __raw_readl(base + PCI_REG_PCI_ERR) & 3; -+ if (pci_err) { -+ if (!is_fixup) -+ printk(KERN_ALERT "PCI error %d at PCI addr 0x%x\n", -+ pci_err, -+ __raw_readl(base + PCI_REG_PCI_ERR_ADDR)); ++static int __devinit nxp_74hc153_probe(struct platform_device *pdev) ++{ ++ struct nxp_74hc153_platform_data *pdata; ++ struct nxp_74hc153_chip *nxp; ++ struct gpio_chip *gc; ++ int err; + -+ __raw_writel(pci_err, base + PCI_REG_PCI_ERR); ++ pdata = pdev->dev.platform_data; ++ if (pdata == NULL) { ++ dev_dbg(&pdev->dev, "no platform data specified\n"); ++ return -EINVAL; + } + -+ ahb_err = __raw_readl(base + PCI_REG_AHB_ERR) & 1; -+ if (ahb_err) { -+ if (!is_fixup) -+ printk(KERN_ALERT "AHB error at AHB address 0x%x\n", -+ __raw_readl(base + PCI_REG_AHB_ERR_ADDR)); ++ nxp = kzalloc(sizeof(struct nxp_74hc153_chip), GFP_KERNEL); ++ if (nxp == NULL) { ++ dev_err(&pdev->dev, "no memory for private data\n"); ++ return -ENOMEM; ++ } + -+ __raw_writel(ahb_err, base + PCI_REG_AHB_ERR); ++ err = gpio_request(pdata->gpio_pin_s0, dev_name(&pdev->dev)); ++ if (err) { ++ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++ pdata->gpio_pin_s0, err); ++ goto err_free_nxp; + } + -+ return (ahb_err | pci_err) ? 1 : 0; -+} ++ err = gpio_request(pdata->gpio_pin_s1, dev_name(&pdev->dev)); ++ if (err) { ++ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++ pdata->gpio_pin_s1, err); ++ goto err_free_s0; ++ } + -+static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus, -+ unsigned int devfn, int where, int size, u32 cmd) -+{ -+ void __iomem *base = ar71xx_pcicfg_base; -+ u32 addr; ++ err = gpio_request(pdata->gpio_pin_1y, dev_name(&pdev->dev)); ++ if (err) { ++ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++ pdata->gpio_pin_1y, err); ++ goto err_free_s1; ++ } + -+ addr = ar71xx_pci_bus_addr(bus, devfn, where); ++ err = gpio_request(pdata->gpio_pin_2y, dev_name(&pdev->dev)); ++ if (err) { ++ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++ pdata->gpio_pin_2y, err); ++ goto err_free_1y; ++ } + -+ DBG("PCI: set cfgaddr: %02x:%02x.%01x/%02x:%01d, addr=%08x\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), -+ where, size, addr); ++ err = gpio_direction_output(pdata->gpio_pin_s0, 0); ++ if (err) { ++ dev_err(&pdev->dev, ++ "unable to set direction of gpio %u, err=%d\n", ++ pdata->gpio_pin_s0, err); ++ goto err_free_2y; ++ } + -+ __raw_writel(addr, base + PCI_REG_CFG_AD); -+ __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0), -+ base + PCI_REG_CFG_CBE); ++ err = gpio_direction_output(pdata->gpio_pin_s1, 0); ++ if (err) { ++ dev_err(&pdev->dev, ++ "unable to set direction of gpio %u, err=%d\n", ++ pdata->gpio_pin_s1, err); ++ goto err_free_2y; ++ } + -+ return ar71xx_pci_be_handler(1); -+} ++ err = gpio_direction_input(pdata->gpio_pin_1y); ++ if (err) { ++ dev_err(&pdev->dev, ++ "unable to set direction of gpio %u, err=%d\n", ++ pdata->gpio_pin_1y, err); ++ goto err_free_2y; ++ } + -+static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 *value) -+{ -+ void __iomem *base = ar71xx_pcicfg_base; -+ static u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0}; -+ unsigned long flags; -+ u32 data; -+ int retry = 0; -+ int ret; ++ err = gpio_direction_input(pdata->gpio_pin_2y); ++ if (err) { ++ dev_err(&pdev->dev, ++ "unable to set direction of gpio %u, err=%d\n", ++ pdata->gpio_pin_2y, err); ++ goto err_free_2y; ++ } + -+ ret = PCIBIOS_SUCCESSFUL; ++ nxp->parent = &pdev->dev; ++ mutex_init(&nxp->lock); + -+ DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d\n", bus->number, -+ PCI_SLOT(devfn), PCI_FUNC(devfn), where, size); ++ gc = &nxp->gpio_chip; + -+retry: -+ spin_lock_irqsave(&ar71xx_pci_lock, flags); ++ gc->direction_input = nxp_74hc153_direction_input; ++ gc->direction_output = nxp_74hc153_direction_output; ++ gc->get = nxp_74hc153_get_value; ++ gc->set = nxp_74hc153_set_value; ++ gc->can_sleep = 1; + -+ if (bus->number == 0 && devfn == 0) { -+ u32 t; ++ gc->base = pdata->gpio_base; ++ gc->ngpio = NXP_74HC153_NUM_GPIOS; ++ gc->label = dev_name(nxp->parent); ++ gc->dev = nxp->parent; ++ gc->owner = THIS_MODULE; + -+ t = PCI_CRP_CMD_READ | (where & ~3); ++ err = gpiochip_add(&nxp->gpio_chip); ++ if (err) { ++ dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); ++ goto err_free_2y; ++ } + -+ __raw_writel(t, base + PCI_REG_CRP_AD_CBE); -+ data = __raw_readl(base + PCI_REG_CRP_RDDATA); ++ platform_set_drvdata(pdev, nxp); ++ return 0; + -+ DBG("PCI: rd local cfg, ad_cbe:%08x, data:%08x\n", t, data); ++err_free_2y: ++ gpio_free(pdata->gpio_pin_2y); ++err_free_1y: ++ gpio_free(pdata->gpio_pin_1y); ++err_free_s1: ++ gpio_free(pdata->gpio_pin_s1); ++err_free_s0: ++ gpio_free(pdata->gpio_pin_s0); ++err_free_nxp: ++ kfree(nxp); ++ return err; ++} + -+ } else { -+ int err; ++static int nxp_74hc153_remove(struct platform_device *pdev) ++{ ++ struct nxp_74hc153_chip *nxp = platform_get_drvdata(pdev); ++ struct nxp_74hc153_platform_data *pdata = pdev->dev.platform_data; + -+ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, -+ PCI_CFG_CMD_READ); ++ if (nxp) { ++ int err; + -+ if (err == 0) { -+ data = __raw_readl(base + PCI_REG_CFG_RDDATA); -+ } else { -+ ret = PCIBIOS_DEVICE_NOT_FOUND; -+ data = ~0; ++ err = gpiochip_remove(&nxp->gpio_chip); ++ if (err) { ++ dev_err(&pdev->dev, ++ "unable to remove gpio chip, err=%d\n", ++ err); ++ return err; + } -+ } -+ -+ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); -+ -+ DBG("PCI: read config: data=%08x raw=%08x\n", -+ (data >> (8 * (where & 3))) & mask[size & 7], data); + -+ *value = (data >> (8 * (where & 3))) & mask[size & 7]; ++ gpio_free(pdata->gpio_pin_2y); ++ gpio_free(pdata->gpio_pin_1y); ++ gpio_free(pdata->gpio_pin_s1); ++ gpio_free(pdata->gpio_pin_s0); + -+ /* -+ * PCI controller bug: sometimes reads to the PCI_COMMAND register -+ * return 0xffff, even though the PCI trace shows the correct value. -+ * Work around this by retrying reads to this register -+ */ -+ if (where == PCI_COMMAND && (*value & 0xffff) == 0xffff && retry++ < 2) -+ goto retry; ++ kfree(nxp); ++ platform_set_drvdata(pdev, NULL); ++ } + -+ return ret; ++ return 0; +} + -+static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 value) -+{ -+ void __iomem *base = ar71xx_pcicfg_base; -+ unsigned long flags; -+ int ret; -+ -+ DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d value=%08x\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), -+ where, size, value); ++static struct platform_driver nxp_74hc153_driver = { ++ .probe = nxp_74hc153_probe, ++ .remove = __devexit_p(nxp_74hc153_remove), ++ .driver = { ++ .name = NXP_74HC153_DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; + -+ value = value << (8 * (where & 3)); -+ ret = PCIBIOS_SUCCESSFUL; ++static int __init nxp_74hc153_init(void) ++{ ++ return platform_driver_register(&nxp_74hc153_driver); ++} ++subsys_initcall(nxp_74hc153_init); + -+ spin_lock_irqsave(&ar71xx_pci_lock, flags); -+ if (bus->number == 0 && devfn == 0) { -+ u32 t; ++static void __exit nxp_74hc153_exit(void) ++{ ++ platform_driver_unregister(&nxp_74hc153_driver); ++} ++module_exit(nxp_74hc153_exit); + -+ t = PCI_CRP_CMD_WRITE | (where & ~3); -+ t |= ar71xx_pci_get_ble(where, size, 1); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC153"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" NXP_74HC153_DRIVER_NAME); +diff -Nur linux-2.6.39.orig/drivers/leds/leds-rb750.c linux-2.6.39/drivers/leds/leds-rb750.c +--- linux-2.6.39.orig/drivers/leds/leds-rb750.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/leds/leds-rb750.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,141 @@ ++/* ++ * LED driver for the RouterBOARD 750 ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include + -+ DBG("PCI: wr local cfg, ad_cbe:%08x, value:%08x\n", t, value); ++#include + -+ __raw_writel(t, base + PCI_REG_CRP_AD_CBE); -+ __raw_writel(value, base + PCI_REG_CRP_WRDATA); -+ } else { -+ int err; ++#define DRV_NAME "leds-rb750" + -+ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, -+ PCI_CFG_CMD_WRITE); ++struct rb750_led_dev { ++ struct led_classdev cdev; ++ u32 mask; ++ int active_low; ++}; + -+ if (err == 0) -+ __raw_writel(value, base + PCI_REG_CFG_WRDATA); -+ else -+ ret = PCIBIOS_DEVICE_NOT_FOUND; -+ } -+ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); ++struct rb750_led_drvdata { ++ struct rb750_led_dev *led_devs; ++ int num_leds; ++}; + -+ return ret; ++static inline struct rb750_led_dev *to_rbled(struct led_classdev *led_cdev) ++{ ++ return (struct rb750_led_dev *)container_of(led_cdev, ++ struct rb750_led_dev, cdev); +} + -+static void ar71xx_pci_fixup(struct pci_dev *dev) ++static void rb750_led_brightness_set(struct led_classdev *led_cdev, ++ enum led_brightness value) +{ -+ u32 t; -+ -+ if (!ar71xx_pci_fixup_enable) -+ return; -+ -+ if (dev->bus->number != 0 || dev->devfn != 0) -+ return; -+ -+ DBG("PCI: fixup host controller %s (%04x:%04x)\n", pci_name(dev), -+ dev->vendor, dev->device); ++ struct rb750_led_dev *rbled = to_rbled(led_cdev); ++ int level; + -+ /* setup COMMAND register */ -+ t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE -+ | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; ++ level = (value == LED_OFF) ? 0 : 1; ++ level ^= rbled->active_low; + -+ pci_write_config_word(dev, PCI_COMMAND, t); ++ if (level) ++ rb750_latch_change(0, rbled->mask); ++ else ++ rb750_latch_change(rbled->mask, 0); +} -+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar71xx_pci_fixup); + -+int __init ar71xx_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, -+ uint8_t pin) ++static int __devinit rb750_led_probe(struct platform_device *pdev) +{ -+ int irq = -1; ++ struct rb750_led_platform_data *pdata; ++ struct rb750_led_drvdata *drvdata; ++ int ret = 0; + int i; + -+ slot -= PCI_IDSEL_ADL_START - PCI_IDSEL_BASE; ++ pdata = pdev->dev.platform_data; ++ if (!pdata) ++ return -EINVAL; + -+ for (i = 0; i < ar71xx_pci_nr_irqs; i++) { -+ struct ar71xx_pci_irq *entry; ++ drvdata = kzalloc(sizeof(struct rb750_led_drvdata) + ++ sizeof(struct rb750_led_dev) * pdata->num_leds, ++ GFP_KERNEL); ++ if (!drvdata) ++ return -ENOMEM; + -+ entry = &ar71xx_pci_irq_map[i]; -+ if (entry->slot == slot && entry->pin == pin) { -+ irq = entry->irq; -+ break; -+ } -+ } ++ drvdata->num_leds = pdata->num_leds; ++ drvdata->led_devs = (struct rb750_led_dev *) &drvdata[1]; + -+ if (irq < 0) { -+ printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n", -+ pin, pci_name((struct pci_dev *)dev)); -+ } else { -+ printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n", -+ irq, pin, pci_name((struct pci_dev *)dev)); ++ for (i = 0; i < drvdata->num_leds; i++) { ++ struct rb750_led_dev *rbled = &drvdata->led_devs[i]; ++ struct rb750_led_data *led_data = &pdata->leds[i]; ++ ++ rbled->cdev.name = led_data->name; ++ rbled->cdev.default_trigger = led_data->default_trigger; ++ rbled->cdev.brightness_set = rb750_led_brightness_set; ++ rbled->cdev.brightness = LED_OFF; ++ ++ rbled->mask = led_data->mask; ++ rbled->active_low = !!led_data->active_low; ++ ++ ret = led_classdev_register(&pdev->dev, &rbled->cdev); ++ if (ret) ++ goto err; + } + -+ return irq; ++ platform_set_drvdata(pdev, drvdata); ++ return 0; ++ ++err: ++ for (i = i - 1; i >= 0; i--) ++ led_classdev_unregister(&drvdata->led_devs[i].cdev); ++ ++ kfree(drvdata); ++ return ret; +} + -+static struct pci_ops ar71xx_pci_ops = { -+ .read = ar71xx_pci_read_config, -+ .write = ar71xx_pci_write_config, -+}; ++static int __devexit rb750_led_remove(struct platform_device *pdev) ++{ ++ struct rb750_led_drvdata *drvdata; ++ int i; + -+static struct resource ar71xx_pci_io_resource = { -+ .name = "PCI IO space", -+ .start = 0, -+ .end = 0, -+ .flags = IORESOURCE_IO, -+}; ++ drvdata = platform_get_drvdata(pdev); ++ for (i = 0; i < drvdata->num_leds; i++) ++ led_classdev_unregister(&drvdata->led_devs[i].cdev); + -+static struct resource ar71xx_pci_mem_resource = { -+ .name = "PCI memory space", -+ .start = AR71XX_PCI_MEM_BASE, -+ .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, -+ .flags = IORESOURCE_MEM -+}; ++ kfree(drvdata); ++ return 0; ++} + -+static struct pci_controller ar71xx_pci_controller = { -+ .pci_ops = &ar71xx_pci_ops, -+ .mem_resource = &ar71xx_pci_mem_resource, -+ .io_resource = &ar71xx_pci_io_resource, ++static struct platform_driver rb750_led_driver = { ++ .probe = rb750_led_probe, ++ .remove = __devexit_p(rb750_led_remove), ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, +}; + -+static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) ++MODULE_ALIAS("platform:leds-rb750"); ++ ++static int __init rb750_led_init(void) +{ -+ void __iomem *base = ar71xx_reset_base; -+ u32 pending; ++ return platform_driver_register(&rb750_led_driver); ++} + -+ pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) & -+ __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++static void __exit rb750_led_exit(void) ++{ ++ platform_driver_unregister(&rb750_led_driver); ++} + -+ if (pending & PCI_INT_DEV0) -+ generic_handle_irq(AR71XX_PCI_IRQ_DEV0); ++module_init(rb750_led_init); ++module_exit(rb750_led_exit); + -+ else if (pending & PCI_INT_DEV1) -+ generic_handle_irq(AR71XX_PCI_IRQ_DEV1); ++MODULE_DESCRIPTION(DRV_NAME); ++MODULE_DESCRIPTION("LED driver for the RouterBOARD 750"); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c linux-2.6.39/drivers/leds/leds-wndr3700-usb.c +--- linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/leds/leds-wndr3700-usb.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,75 @@ ++/* ++ * USB LED driver for the NETGEAR WNDR3700 ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ else if (pending & PCI_INT_DEV2) -+ generic_handle_irq(AR71XX_PCI_IRQ_DEV2); ++#include ++#include ++#include + -+ else if (pending & PCI_INT_CORE) -+ generic_handle_irq(AR71XX_PCI_IRQ_CORE); ++#include + ++#define DRIVER_NAME "wndr3700-led-usb" ++ ++static void wndr3700_usb_led_set(struct led_classdev *cdev, ++ enum led_brightness brightness) ++{ ++ if (brightness) ++ ar71xx_device_start(RESET_MODULE_GE1_PHY); + else -+ spurious_interrupt(); ++ ar71xx_device_stop(RESET_MODULE_GE1_PHY); +} + -+static void ar71xx_pci_irq_unmask(struct irq_data *d) ++static enum led_brightness wndr3700_usb_led_get(struct led_classdev *cdev) +{ -+ unsigned int irq = d->irq - AR71XX_PCI_IRQ_BASE; -+ void __iomem *base = ar71xx_reset_base; -+ u32 t; ++ return ar71xx_device_stopped(RESET_MODULE_GE1_PHY) ? LED_OFF : LED_FULL; ++} + -+ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); -+ __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++static struct led_classdev wndr3700_usb_led = { ++ .name = "wndr3700:green:usb", ++ .brightness_set = wndr3700_usb_led_set, ++ .brightness_get = wndr3700_usb_led_get, ++}; + -+ /* flush write */ -+ (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++static int __devinit wndr3700_usb_led_probe(struct platform_device *pdev) ++{ ++ return led_classdev_register(&pdev->dev, &wndr3700_usb_led); +} + -+static void ar71xx_pci_irq_mask(struct irq_data *d) ++static int __devexit wndr3700_usb_led_remove(struct platform_device *pdev) +{ -+ unsigned int irq = d->irq - AR71XX_PCI_IRQ_BASE; -+ void __iomem *base = ar71xx_reset_base; -+ u32 t; -+ -+ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); -+ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); -+ -+ /* flush write */ -+ (void) __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ led_classdev_unregister(&wndr3700_usb_led); ++ return 0; +} + -+static struct irq_chip ar71xx_pci_irq_chip = { -+ .name = "AR71XX PCI ", -+ .irq_mask = ar71xx_pci_irq_mask, -+ .irq_unmask = ar71xx_pci_irq_unmask, -+ .irq_mask_ack = ar71xx_pci_irq_mask, ++static struct platform_driver wndr3700_usb_led_driver = { ++ .probe = wndr3700_usb_led_probe, ++ .remove = __devexit_p(wndr3700_usb_led_remove), ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, +}; + -+static void __init ar71xx_pci_irq_init(void) ++static int __init wndr3700_usb_led_init(void) +{ -+ void __iomem *base = ar71xx_reset_base; -+ int i; -+ -+ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE); -+ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS); -+ -+ for (i = AR71XX_PCI_IRQ_BASE; -+ i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) -+ irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip, -+ handle_level_irq); -+ -+ irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar71xx_pci_irq_handler); ++ return platform_driver_register(&wndr3700_usb_led_driver); +} + -+int __init ar71xx_pcibios_init(void) ++static void __exit wndr3700_usb_led_exit(void) +{ -+ void __iomem *ddr_base = ar71xx_ddr_base; -+ -+ ar71xx_device_stop(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE); -+ ar71xx_pci_delay(); -+ -+ ar71xx_device_start(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE); -+ ar71xx_pci_delay(); -+ -+ ar71xx_pcicfg_base = ioremap_nocache(AR71XX_PCI_CFG_BASE, -+ AR71XX_PCI_CFG_SIZE); -+ if (ar71xx_pcicfg_base == NULL) -+ return -ENOMEM; -+ -+ __raw_writel(PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0); -+ __raw_writel(PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1); -+ __raw_writel(PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2); -+ __raw_writel(PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3); -+ __raw_writel(PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4); -+ __raw_writel(PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5); -+ __raw_writel(PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6); -+ __raw_writel(PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7); -+ -+ ar71xx_pci_delay(); ++ platform_driver_unregister(&wndr3700_usb_led_driver); ++} + -+ /* clear bus errors */ -+ (void)ar71xx_pci_be_handler(1); ++module_init(wndr3700_usb_led_init); ++module_exit(wndr3700_usb_led_exit); + -+ ar71xx_pci_fixup_enable = 1; -+ ar71xx_pci_irq_init(); -+ register_pci_controller(&ar71xx_pci_controller); ++MODULE_DESCRIPTION("USB LED driver for the NETGEAR WNDR3700"); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRIVER_NAME); +diff -Nur linux-2.6.39.orig/drivers/mtd/chips/cfi_cmdset_0002.c linux-2.6.39/drivers/mtd/chips/cfi_cmdset_0002.c +--- linux-2.6.39.orig/drivers/mtd/chips/cfi_cmdset_0002.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/mtd/chips/cfi_cmdset_0002.c 2011-08-24 18:17:24.000000000 +0200 +@@ -39,7 +39,7 @@ + #include + + #define AMD_BOOTLOC_BUG +-#define FORCE_WORD_WRITE 0 ++#define FORCE_WORD_WRITE 1 + + #define MAX_WORD_RETRIES 3 + +@@ -50,7 +50,9 @@ + + static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); + static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); ++#if !FORCE_WORD_WRITE + static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); ++#endif + static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *); + static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *); + static void cfi_amdstd_sync (struct mtd_info *); +@@ -186,6 +188,7 @@ + } + #endif + ++#if !FORCE_WORD_WRITE + static void fixup_use_write_buffers(struct mtd_info *mtd) + { + struct map_info *map = mtd->priv; +@@ -195,6 +198,7 @@ + mtd->write = cfi_amdstd_write_buffers; + } + } ++#endif /* !FORCE_WORD_WRITE */ + + /* Atmel chips don't use the same PRI format as AMD chips */ + static void fixup_convert_atmel_pri(struct mtd_info *mtd) +@@ -1377,6 +1381,7 @@ + /* + * FIXME: interleaved mode not tested, and probably not supported! + */ ++#if !FORCE_WORD_WRITE + static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, + unsigned long adr, const u_char *buf, + int len) +@@ -1487,7 +1492,6 @@ + return ret; + } + +- + static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) + { +@@ -1566,6 +1570,7 @@ + + return 0; + } ++#endif /* !FORCE_WORD_WRITE */ + + + /* +diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Kconfig linux-2.6.39/drivers/mtd/maps/Kconfig +--- linux-2.6.39.orig/drivers/mtd/maps/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/mtd/maps/Kconfig 2011-08-24 18:17:24.000000000 +0200 +@@ -260,6 +260,13 @@ + Support for parsing CFE image tag and creating MTD partitions on + Broadcom BCM63xx boards. + ++config MTD_AR91XX_FLASH ++ tristate "Atheros AR91xx parallel flash support" ++ depends on ATHEROS_AR71XX ++ select MTD_COMPLEX_MAPPINGS ++ help ++ Parallel flash driver for the Atheros AR91xx based boards. + -+ return 0; -+} -diff -Nur linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c linux-2.6.39/arch/mips/pci/pci-ar724x.c ---- linux-2.6.39.orig/arch/mips/pci/pci-ar724x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/arch/mips/pci/pci-ar724x.c 2011-08-06 09:32:37.088017079 +0200 -@@ -0,0 +1,389 @@ + config MTD_DILNETPC + tristate "CFI Flash device mapped on DIL/Net PC" + depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN +diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Makefile linux-2.6.39/drivers/mtd/maps/Makefile +--- linux-2.6.39.orig/drivers/mtd/maps/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/mtd/maps/Makefile 2011-08-24 18:17:24.000000000 +0200 +@@ -40,6 +40,7 @@ + obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.o + obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o + obj-$(CONFIG_MTD_PCI) += pci.o ++obj-$(CONFIG_MTD_AR91XX_FLASH) += ar91xx_flash.o + obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o + obj-$(CONFIG_MTD_EDB7312) += edb7312.o + obj-$(CONFIG_MTD_IMPA7) += impa7.o +diff -Nur linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c +--- linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,310 @@ +/* -+ * Atheros AR724x PCI host controller driver ++ * Parallel flash driver for the Atheros AR91xx SoC + * -+ * Copyright (C) 2009-2010 Gabor Juhos ++ * Copyright (C) 2009 Gabor Juhos + * -+ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. + * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. + */ + -+#include ++#include +#include -+#include -+#include -+#include -+#include -+#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + +#include -+#include -+ -+#undef DEBUG -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_INFO fmt, ## args) -+#else -+#define DBG(fmt, args...) -+#endif ++#include + -+static void __iomem *ar724x_pci_localcfg_base; -+static void __iomem *ar724x_pci_devcfg_base; -+static void __iomem *ar724x_pci_ctrl_base; -+static int ar724x_pci_fixup_enable; ++#define DRV_NAME "ar91xx-flash" + -+static DEFINE_SPINLOCK(ar724x_pci_lock); ++struct ar91xx_flash_info { ++ struct mtd_info *mtd; ++ struct map_info map; ++#ifdef CONFIG_MTD_PARTITIONS ++ int nr_parts; ++ struct mtd_partition *parts; ++#endif ++}; + -+static void ar724x_pci_read(void __iomem *base, int where, int size, u32 *value) ++static map_word ar91xx_flash_read(struct map_info *map, unsigned long ofs) +{ -+ unsigned long flags; -+ u32 data; ++ map_word val; + -+ spin_lock_irqsave(&ar724x_pci_lock, flags); -+ data = __raw_readl(base + (where & ~3)); ++ if (map_bankwidth_is_1(map)) ++ val.x[0] = __raw_readb(map->virt + (ofs ^ 3)); ++ else if (map_bankwidth_is_2(map)) ++ val.x[0] = __raw_readw(map->virt + (ofs ^ 2)); ++ else ++ val = map_word_ff(map); + -+ switch (size) { -+ case 1: -+ if (where & 1) -+ data >>= 8; -+ if (where & 2) -+ data >>= 16; -+ data &= 0xFF; -+ break; -+ case 2: -+ if (where & 2) -+ data >>= 16; -+ data &= 0xFFFF; -+ break; -+ } -+ -+ *value = data; -+ spin_unlock_irqrestore(&ar724x_pci_lock, flags); ++ return val; +} + -+static void ar724x_pci_write(void __iomem *base, int where, int size, u32 value) ++static void ar91xx_flash_write(struct map_info *map, map_word d, ++ unsigned long ofs) +{ -+ unsigned long flags; -+ u32 data; -+ int s; -+ -+ spin_lock_irqsave(&ar724x_pci_lock, flags); -+ data = __raw_readl(base + (where & ~3)); -+ -+ switch (size) { -+ case 1: -+ s = ((where & 3) << 3); -+ data &= ~(0xFF << s); -+ data |= ((value & 0xFF) << s); -+ break; -+ case 2: -+ s = ((where & 2) << 3); -+ data &= ~(0xFFFF << s); -+ data |= ((value & 0xFFFF) << s); -+ break; -+ case 4: -+ data = value; -+ break; -+ } ++ if (map_bankwidth_is_1(map)) ++ __raw_writeb(d.x[0], map->virt + (ofs ^ 3)); ++ else if (map_bankwidth_is_2(map)) ++ __raw_writew(d.x[0], map->virt + (ofs ^ 2)); + -+ __raw_writel(data, base + (where & ~3)); -+ /* flush write */ -+ (void)__raw_readl(base + (where & ~3)); -+ spin_unlock_irqrestore(&ar724x_pci_lock, flags); ++ mb(); +} + -+static int ar724x_pci_read_config(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 *value) ++static map_word ar91xx_flash_read_lock(struct map_info *map, unsigned long ofs) +{ ++ map_word ret; + -+ if (bus->number != 0 || devfn != 0) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ -+ ar724x_pci_read(ar724x_pci_devcfg_base, where, size, value); -+ -+ DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d, value=%08x\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), -+ where, size, *value); -+ -+ /* -+ * WAR for BAR issue - We are unable to access the PCI device space -+ * if we set the BAR with proper base address -+ */ -+ if ((where == 0x10) && (size == 4)) { -+ u32 val; -+ val = (ar71xx_soc == AR71XX_SOC_AR7240) ? 0xffff : 0x1000ffff; -+ ar724x_pci_write(ar724x_pci_devcfg_base, where, size, val); -+ } ++ ar71xx_flash_acquire(); ++ ret = ar91xx_flash_read(map, ofs); ++ ar71xx_flash_release(); + -+ return PCIBIOS_SUCCESSFUL; ++ return ret; +} + -+static int ar724x_pci_write_config(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 value) ++static void ar91xx_flash_write_lock(struct map_info *map, map_word d, ++ unsigned long ofs) +{ -+ if (bus->number != 0 || devfn != 0) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ -+ DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d, value=%08x\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), -+ where, size, value); ++ ar71xx_flash_acquire(); ++ ar91xx_flash_write(map, d, ofs); ++ ar71xx_flash_release(); ++} + -+ ar724x_pci_write(ar724x_pci_devcfg_base, where, size, value); ++static void ar91xx_flash_copy_from_lock(struct map_info *map, void *to, ++ unsigned long from, ssize_t len) ++{ ++ ar71xx_flash_acquire(); ++ inline_map_copy_from(map, to, from, len); ++ ar71xx_flash_release(); ++} + -+ return PCIBIOS_SUCCESSFUL; ++static void ar91xx_flash_copy_to_lock(struct map_info *map, unsigned long to, ++ const void *from, ssize_t len) ++{ ++ ar71xx_flash_acquire(); ++ inline_map_copy_to(map, to, from, len); ++ ar71xx_flash_release(); +} + -+static void ar724x_pci_fixup(struct pci_dev *dev) ++static int ar91xx_flash_remove(struct platform_device *pdev) +{ -+ u16 cmd; ++ struct ar91xx_flash_platform_data *pdata; ++ struct ar91xx_flash_info *info; + -+ if (!ar724x_pci_fixup_enable) -+ return; ++ info = platform_get_drvdata(pdev); ++ if (info == NULL) ++ return 0; + -+ if (dev->bus->number != 0 || dev->devfn != 0) -+ return; ++ platform_set_drvdata(pdev, NULL); + -+ /* setup COMMAND register */ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | -+ PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | -+ PCI_COMMAND_FAST_BACK; ++ if (info->mtd == NULL) ++ return 0; + -+ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ pdata = pdev->dev.platform_data; ++#ifdef CONFIG_MTD_PARTITIONS ++ if (info->nr_parts) { ++ del_mtd_partitions(info->mtd); ++ kfree(info->parts); ++ } else if (pdata->nr_parts) { ++ del_mtd_partitions(info->mtd); ++ } else { ++ del_mtd_device(info->mtd); ++ } ++#else ++ del_mtd_device(info->mtd); ++#endif ++ map_destroy(info->mtd); ++ ++ return 0; +} -+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar724x_pci_fixup); + -+int __init ar724x_pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, -+ uint8_t pin) ++static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; ++#ifdef CONFIG_MTD_PARTITIONS ++static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; ++#endif ++ ++static int ar91xx_flash_probe(struct platform_device *pdev) +{ -+ int irq = -1; -+ int i; ++ struct ar91xx_flash_platform_data *pdata; ++ struct ar91xx_flash_info *info; ++ struct resource *res; ++ struct resource *region; ++ const char **probe_type; ++ int err = 0; + -+ for (i = 0; i < ar71xx_pci_nr_irqs; i++) { -+ struct ar71xx_pci_irq *entry; -+ entry = &ar71xx_pci_irq_map[i]; ++ pdata = pdev->dev.platform_data; ++ if (pdata == NULL) ++ return -EINVAL; + -+ if (entry->slot == slot && entry->pin == pin) { -+ irq = entry->irq; -+ break; -+ } ++ info = devm_kzalloc(&pdev->dev, sizeof(struct ar91xx_flash_info), ++ GFP_KERNEL); ++ if (info == NULL) { ++ err = -ENOMEM; ++ goto err_out; + } + -+ if (irq < 0) -+ printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n", -+ pin, pci_name((struct pci_dev *)dev)); -+ else -+ printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n", -+ irq, pin, pci_name((struct pci_dev *)dev)); ++ platform_set_drvdata(pdev, info); + -+ return irq; -+} ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (res == NULL) { ++ err = -ENOENT; ++ goto err_out; ++ } + -+static struct pci_ops ar724x_pci_ops = { -+ .read = ar724x_pci_read_config, -+ .write = ar724x_pci_write_config, -+}; ++ dev_info(&pdev->dev, "%.8llx at %.8llx\n", ++ (unsigned long long)(res->end - res->start + 1), ++ (unsigned long long)res->start); + -+static struct resource ar724x_pci_io_resource = { -+ .name = "PCI IO space", -+ .start = 0, -+ .end = 0, -+ .flags = IORESOURCE_IO, -+}; ++ region = devm_request_mem_region(&pdev->dev, ++ res->start, res->end - res->start + 1, ++ dev_name(&pdev->dev)); ++ if (region == NULL) { ++ dev_err(&pdev->dev, "could not reserve memory region\n"); ++ err = -ENOMEM; ++ goto err_out; ++ } + -+static struct resource ar724x_pci_mem_resource = { -+ .name = "PCI memory space", -+ .start = AR71XX_PCI_MEM_BASE, -+ .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, -+ .flags = IORESOURCE_MEM -+}; ++ info->map.name = dev_name(&pdev->dev); ++ info->map.phys = res->start; ++ info->map.size = res->end - res->start + 1; ++ info->map.bankwidth = pdata->width; + -+static struct pci_controller ar724x_pci_controller = { -+ .pci_ops = &ar724x_pci_ops, -+ .mem_resource = &ar724x_pci_mem_resource, -+ .io_resource = &ar724x_pci_io_resource, -+}; ++ info->map.virt = devm_ioremap(&pdev->dev, info->map.phys, ++ info->map.size); ++ if (info->map.virt == NULL) { ++ dev_err(&pdev->dev, "failed to ioremap flash region\n"); ++ err = -EIO; ++ goto err_out; ++ } + -+static void __init ar724x_pci_reset(void) -+{ -+ ar71xx_device_stop(AR724X_RESET_PCIE); -+ ar71xx_device_stop(AR724X_RESET_PCIE_PHY); -+ ar71xx_device_stop(AR724X_RESET_PCIE_PHY_SERIAL); -+ udelay(100); ++ simple_map_init(&info->map); ++ if (pdata->is_shared) { ++ info->map.read = ar91xx_flash_read_lock; ++ info->map.write = ar91xx_flash_write_lock; ++ info->map.copy_from = ar91xx_flash_copy_from_lock; ++ info->map.copy_to = ar91xx_flash_copy_to_lock; ++ } else { ++ info->map.read = ar91xx_flash_read; ++ info->map.write = ar91xx_flash_write; ++ } + -+ ar71xx_device_start(AR724X_RESET_PCIE_PHY_SERIAL); -+ udelay(100); -+ ar71xx_device_start(AR724X_RESET_PCIE_PHY); -+ ar71xx_device_start(AR724X_RESET_PCIE); -+} ++ probe_type = rom_probe_types; ++ for (; info->mtd == NULL && *probe_type != NULL; probe_type++) ++ info->mtd = do_map_probe(*probe_type, &info->map); + -+static int __init ar724x_pci_setup(void) -+{ -+ void __iomem *base = ar724x_pci_ctrl_base; -+ u32 t; -+ -+ /* setup COMMAND register */ -+ t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | -+ PCI_COMMAND_PARITY|PCI_COMMAND_SERR|PCI_COMMAND_FAST_BACK; -+ -+ ar724x_pci_write(ar724x_pci_localcfg_base, PCI_COMMAND, 4, t); -+ ar724x_pci_write(ar724x_pci_localcfg_base, 0x20, 4, 0x1ff01000); -+ ar724x_pci_write(ar724x_pci_localcfg_base, 0x24, 4, 0x1ff01000); -+ -+ t = __raw_readl(base + AR724X_PCI_REG_RESET); -+ if (t != 0x7) { -+ udelay(100000); -+ __raw_writel(0, base + AR724X_PCI_REG_RESET); -+ udelay(100); -+ __raw_writel(4, base + AR724X_PCI_REG_RESET); -+ udelay(100000); ++ if (info->mtd == NULL) { ++ dev_err(&pdev->dev, "map_probe failed\n"); ++ err = -ENXIO; ++ goto err_out; + } + -+ if (ar71xx_soc == AR71XX_SOC_AR7240) -+ t = AR724X_PCI_APP_LTSSM_ENABLE; -+ else -+ t = 0x1ffc1; -+ __raw_writel(t, base + AR724X_PCI_REG_APP); -+ /* flush write */ -+ (void) __raw_readl(base + AR724X_PCI_REG_APP); -+ udelay(1000); ++ info->mtd->owner = THIS_MODULE; + -+ t = __raw_readl(base + AR724X_PCI_REG_RESET); -+ if ((t & AR724X_PCI_RESET_LINK_UP) == 0x0) { -+ printk(KERN_WARNING "PCI: no PCIe module found\n"); -+ return -ENODEV; ++#ifdef CONFIG_MTD_PARTITIONS ++ if (pdata->nr_parts) { ++ dev_info(&pdev->dev, "using static partition mapping\n"); ++ add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); ++ return 0; + } + -+ if (ar71xx_soc == AR71XX_SOC_AR7241 || -+ ar71xx_soc == AR71XX_SOC_AR7242) { -+ t = __raw_readl(base + AR724X_PCI_REG_APP); -+ t |= BIT(16); -+ __raw_writel(t, base + AR724X_PCI_REG_APP); ++ err = parse_mtd_partitions(info->mtd, part_probe_types, ++ &info->parts, 0); ++ if (err > 0) { ++ add_mtd_partitions(info->mtd, info->parts, err); ++ return 0; + } ++#endif + ++ add_mtd_device(info->mtd); + return 0; ++ ++err_out: ++ ar91xx_flash_remove(pdev); ++ return err; +} + -+static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) ++#ifdef CONFIG_PM ++static int ar91xx_flash_suspend(struct platform_device *dev, pm_message_t state) +{ -+ void __iomem *base = ar724x_pci_ctrl_base; -+ u32 pending; -+ -+ pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & -+ __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ struct ar91xx_flash_info *info = platform_get_drvdata(dev); ++ int ret = 0; + -+ if (pending & AR724X_PCI_INT_DEV0) -+ generic_handle_irq(AR71XX_PCI_IRQ_DEV0); ++ if (info->mtd->suspend) ++ ret = info->mtd->suspend(info->mtd); + -+ else -+ spurious_interrupt(); -+} ++ if (ret) ++ goto fail; + -+static void ar724x_pci_irq_unmask(struct irq_data *d) -+{ -+ void __iomem *base = ar724x_pci_ctrl_base; -+ u32 t; ++ return 0; + -+ switch (d->irq) { -+ case AR71XX_PCI_IRQ_DEV0: -+ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); -+ __raw_writel(t | AR724X_PCI_INT_DEV0, -+ base + AR724X_PCI_REG_INT_MASK); -+ /* flush write */ -+ (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++fail: ++ if (info->mtd->suspend) { ++ BUG_ON(!info->mtd->resume); ++ info->mtd->resume(info->mtd); + } ++ ++ return ret; +} + -+static void ar724x_pci_irq_mask(struct irq_data *d) ++static int ar91xx_flash_resume(struct platform_device *pdev) +{ -+ void __iomem *base = ar724x_pci_ctrl_base; -+ u32 t; ++ struct ar91xx_flash_info *info = platform_get_drvdata(pdev); + -+ switch (d->irq) { -+ case AR71XX_PCI_IRQ_DEV0: -+ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); -+ __raw_writel(t & ~AR724X_PCI_INT_DEV0, -+ base + AR724X_PCI_REG_INT_MASK); ++ if (info->mtd->resume) ++ info->mtd->resume(info->mtd); + -+ /* flush write */ -+ (void) __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ return 0; ++} + -+ t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS); -+ __raw_writel(t | AR724X_PCI_INT_DEV0, -+ base + AR724X_PCI_REG_INT_STATUS); ++static void ar91xx_flash_shutdown(struct platform_device *pdev) ++{ ++ struct ar91xx_flash_info *info = platform_get_drvdata(pdev); + -+ /* flush write */ -+ (void) __raw_readl(base + AR724X_PCI_REG_INT_STATUS); -+ } ++ if (info->mtd->suspend && info->mtd->resume) ++ if (info->mtd->suspend(info->mtd) == 0) ++ info->mtd->resume(info->mtd); +} ++#else ++#define ar91xx_flash_suspend NULL ++#define ar91xx_flash_resume NULL ++#define ar91xx_flash_shutdown NULL ++#endif + -+static struct irq_chip ar724x_pci_irq_chip = { -+ .name = "AR724X PCI ", -+ .irq_mask = ar724x_pci_irq_mask, -+ .irq_unmask = ar724x_pci_irq_unmask, -+ .irq_mask_ack = ar724x_pci_irq_mask, ++static struct platform_driver ar91xx_flash_driver = { ++ .probe = ar91xx_flash_probe, ++ .remove = ar91xx_flash_remove, ++ .suspend = ar91xx_flash_suspend, ++ .resume = ar91xx_flash_resume, ++ .shutdown = ar91xx_flash_shutdown, ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, +}; + -+static void __init ar724x_pci_irq_init(void) ++static int __init ar91xx_flash_init(void) +{ -+ void __iomem *base = ar724x_pci_ctrl_base; -+ u32 t; -+ int i; -+ -+ t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE); -+ if (t & (AR724X_RESET_PCIE | AR724X_RESET_PCIE_PHY | -+ AR724X_RESET_PCIE_PHY_SERIAL)) { -+ return; -+ } -+ -+ __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); -+ __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); -+ -+ for (i = AR71XX_PCI_IRQ_BASE; -+ i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) -+ irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, -+ handle_level_irq); -+ -+ irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar724x_pci_irq_handler); ++ return platform_driver_register(&ar91xx_flash_driver); +} + -+int __init ar724x_pcibios_init(void) ++static void __exit ar91xx_flash_exit(void) +{ -+ int ret = -ENOMEM; -+ -+ ar724x_pci_localcfg_base = ioremap_nocache(AR724X_PCI_CRP_BASE, -+ AR724X_PCI_CRP_SIZE); -+ if (ar724x_pci_localcfg_base == NULL) -+ goto err; -+ -+ ar724x_pci_devcfg_base = ioremap_nocache(AR724X_PCI_CFG_BASE, -+ AR724X_PCI_CFG_SIZE); -+ if (ar724x_pci_devcfg_base == NULL) -+ goto err_unmap_localcfg; -+ -+ ar724x_pci_ctrl_base = ioremap_nocache(AR724X_PCI_CTRL_BASE, -+ AR724X_PCI_CTRL_SIZE); -+ if (ar724x_pci_ctrl_base == NULL) -+ goto err_unmap_devcfg; -+ -+ ar724x_pci_reset(); -+ ret = ar724x_pci_setup(); -+ if (ret) -+ goto err_unmap_ctrl; ++ platform_driver_unregister(&ar91xx_flash_driver); ++} + -+ ar724x_pci_fixup_enable = 1; -+ ar724x_pci_irq_init(); -+ register_pci_controller(&ar724x_pci_controller); ++module_init(ar91xx_flash_init); ++module_exit(ar91xx_flash_exit); + -+ return 0; ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_DESCRIPTION("Parallel flash driver for the Atheros AR91xx SoC"); ++MODULE_ALIAS("platform:" DRV_NAME); +diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Kconfig linux-2.6.39/drivers/mtd/nand/Kconfig +--- linux-2.6.39.orig/drivers/mtd/nand/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/mtd/nand/Kconfig 2011-08-24 18:17:24.000000000 +0200 +@@ -531,4 +531,9 @@ + Enables support for NAND Flash chips on the ST Microelectronics + Flexible Static Memory Controller (FSMC) + ++config MTD_NAND_RB4XX ++ tristate "NAND flash driver for RouterBoard 4xx series" ++ depends on MTD_NAND && AR71XX_MACH_RB4XX ++ select SPI_AR71XX + -+err_unmap_ctrl: -+ iounmap(ar724x_pci_ctrl_base); -+err_unmap_devcfg: -+ iounmap(ar724x_pci_devcfg_base); -+err_unmap_localcfg: -+ iounmap(ar724x_pci_localcfg_base); -+err: -+ return ret; -+} -diff -Nur linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c linux-2.6.39/drivers/gpio/nxp_74hc153.c ---- linux-2.6.39.orig/drivers/gpio/nxp_74hc153.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/gpio/nxp_74hc153.c 2011-04-27 12:19:22.327664626 +0200 -@@ -0,0 +1,247 @@ + endif # MTD_NAND +diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Makefile linux-2.6.39/drivers/mtd/nand/Makefile +--- linux-2.6.39.orig/drivers/mtd/nand/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/mtd/nand/Makefile 2011-08-24 18:17:24.000000000 +0200 +@@ -34,6 +34,7 @@ + obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o + obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o + obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o ++obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o + obj-$(CONFIG_MTD_ALAUDA) += alauda.o + obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o + obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o +diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c +--- linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,311 @@ +/* -+ * NXP 74HC153 - Dual 4-input multiplexer GPIO driver ++ * NAND flash driver for the MikroTik RouterBoard 4xx series + * -+ * Copyright (C) 2010 Gabor Juhos ++ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. ++ * This file was based on the driver for Linux 2.6.22 published by ++ * MikroTik for their RouterBoard 4xx series devices. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + */ + -+#include +#include ++#include ++#include ++#include ++#include ++#include ++#include +#include +#include -+#include -+#include + -+#define NXP_74HC153_NUM_GPIOS 8 -+#define NXP_74HC153_S0_MASK 0x1 -+#define NXP_74HC153_S1_MASK 0x2 -+#define NXP_74HC153_BANK_MASK 0x4 ++#include ++#include + -+struct nxp_74hc153_chip { -+ struct device *parent; -+ struct gpio_chip gpio_chip; -+ struct mutex lock; ++#define DRV_NAME "rb4xx-nand" ++#define DRV_VERSION "0.2.0" ++#define DRV_DESC "NAND flash driver for RouterBoard 4xx series" ++ ++#define RB4XX_NAND_GPIO_READY 5 ++#define RB4XX_NAND_GPIO_ALE 37 ++#define RB4XX_NAND_GPIO_CLE 38 ++#define RB4XX_NAND_GPIO_NCE 39 ++ ++struct rb4xx_nand_info { ++ struct nand_chip chip; ++ struct mtd_info mtd; +}; + -+static struct nxp_74hc153_chip *gpio_to_nxp(struct gpio_chip *gc) ++/* ++ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader ++ * will not be able to find the kernel that we load. ++ */ ++static struct nand_ecclayout rb4xx_nand_ecclayout = { ++ .eccbytes = 6, ++ .eccpos = { 8, 9, 10, 13, 14, 15 }, ++ .oobavail = 9, ++ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } ++}; ++ ++static struct mtd_partition rb4xx_nand_partitions[] = { ++ { ++ .name = "booter", ++ .offset = 0, ++ .size = (256 * 1024), ++ .mask_flags = MTD_WRITEABLE, ++ }, ++ { ++ .name = "kernel", ++ .offset = (256 * 1024), ++ .size = (6 * 1024 * 1024) - (256 * 1024), ++ }, ++ { ++ .name = "rootfs", ++ .offset = MTDPART_OFS_NXTBLK, ++ .size = MTDPART_SIZ_FULL, ++ }, ++}; ++ ++static int rb4xx_nand_dev_ready(struct mtd_info *mtd) +{ -+ return container_of(gc, struct nxp_74hc153_chip, gpio_chip); ++ return gpio_get_value_cansleep(RB4XX_NAND_GPIO_READY); +} + -+static int nxp_74hc153_direction_input(struct gpio_chip *gc, unsigned offset) ++static void rb4xx_nand_write_cmd(unsigned char cmd) +{ -+ return 0; ++ unsigned char data = cmd; ++ int err; ++ ++ err = rb4xx_cpld_write(&data, 1); ++ if (err) ++ pr_err("rb4xx_nand: write cmd failed, err=%d\n", err); +} + -+static int nxp_74hc153_direction_output(struct gpio_chip *gc, -+ unsigned offset, int val) ++static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, ++ unsigned int ctrl) +{ -+ return -EINVAL; ++ if (ctrl & NAND_CTRL_CHANGE) { ++ gpio_set_value_cansleep(RB4XX_NAND_GPIO_CLE, ++ (ctrl & NAND_CLE) ? 1 : 0); ++ gpio_set_value_cansleep(RB4XX_NAND_GPIO_ALE, ++ (ctrl & NAND_ALE) ? 1 : 0); ++ gpio_set_value_cansleep(RB4XX_NAND_GPIO_NCE, ++ (ctrl & NAND_NCE) ? 0 : 1); ++ } ++ ++ if (cmd != NAND_CMD_NONE) ++ rb4xx_nand_write_cmd(cmd); +} + -+static int nxp_74hc153_get_value(struct gpio_chip *gc, unsigned offset) ++static unsigned char rb4xx_nand_read_byte(struct mtd_info *mtd) +{ -+ struct nxp_74hc153_chip *nxp; -+ struct nxp_74hc153_platform_data *pdata; -+ unsigned s0; -+ unsigned s1; -+ unsigned pin; -+ int ret; ++ unsigned char data = 0; ++ int err; + -+ nxp = gpio_to_nxp(gc); -+ pdata = nxp->parent->platform_data; ++ err = rb4xx_cpld_read(&data, NULL, 1); ++ if (err) { ++ pr_err("rb4xx_nand: read data failed, err=%d\n", err); ++ data = 0xff; ++ } + -+ s0 = !!(offset & NXP_74HC153_S0_MASK); -+ s1 = !!(offset & NXP_74HC153_S1_MASK); -+ pin = (offset & NXP_74HC153_BANK_MASK) ? pdata->gpio_pin_2y -+ : pdata->gpio_pin_1y; ++ return data; ++} + -+ mutex_lock(&nxp->lock); -+ gpio_set_value(pdata->gpio_pin_s0, s0); -+ gpio_set_value(pdata->gpio_pin_s1, s1); -+ ret = gpio_get_value(pin); -+ mutex_unlock(&nxp->lock); ++static void rb4xx_nand_write_buf(struct mtd_info *mtd, const unsigned char *buf, ++ int len) ++{ ++ int err; + -+ return ret; ++ err = rb4xx_cpld_write(buf, len); ++ if (err) ++ pr_err("rb4xx_nand: write buf failed, err=%d\n", err); +} + -+static void nxp_74hc153_set_value(struct gpio_chip *gc, -+ unsigned offset, int val) ++static void rb4xx_nand_read_buf(struct mtd_info *mtd, unsigned char *buf, ++ int len) +{ -+ /* not supported */ ++ int err; ++ ++ err = rb4xx_cpld_read(buf, NULL, len); ++ if (err) ++ pr_err("rb4xx_nand: read buf failed, err=%d\n", err); +} + -+static int __devinit nxp_74hc153_probe(struct platform_device *pdev) ++static int __init rb4xx_nand_probe(struct platform_device *pdev) +{ -+ struct nxp_74hc153_platform_data *pdata; -+ struct nxp_74hc153_chip *nxp; -+ struct gpio_chip *gc; -+ int err; ++ struct rb4xx_nand_info *info; ++ int ret; + -+ pdata = pdev->dev.platform_data; -+ if (pdata == NULL) { -+ dev_dbg(&pdev->dev, "no platform data specified\n"); -+ return -EINVAL; -+ } ++ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); + -+ nxp = kzalloc(sizeof(struct nxp_74hc153_chip), GFP_KERNEL); -+ if (nxp == NULL) { -+ dev_err(&pdev->dev, "no memory for private data\n"); -+ return -ENOMEM; ++ ret = gpio_request(RB4XX_NAND_GPIO_READY, "NAND RDY"); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to request gpio %d\n", ++ RB4XX_NAND_GPIO_READY); ++ goto err; + } + -+ err = gpio_request(pdata->gpio_pin_s0, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_s0, err); -+ goto err_free_nxp; ++ ret = gpio_direction_input(RB4XX_NAND_GPIO_READY); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set input mode on gpio %d\n", ++ RB4XX_NAND_GPIO_READY); ++ goto err_free_gpio_ready; + } + -+ err = gpio_request(pdata->gpio_pin_s1, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_s1, err); -+ goto err_free_s0; ++ ret = gpio_request(RB4XX_NAND_GPIO_ALE, "NAND ALE"); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to request gpio %d\n", ++ RB4XX_NAND_GPIO_ALE); ++ goto err_free_gpio_ready; + } + -+ err = gpio_request(pdata->gpio_pin_1y, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_1y, err); -+ goto err_free_s1; ++ ret = gpio_direction_output(RB4XX_NAND_GPIO_ALE, 0); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", ++ RB4XX_NAND_GPIO_ALE); ++ goto err_free_gpio_ale; + } + -+ err = gpio_request(pdata->gpio_pin_2y, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_2y, err); -+ goto err_free_1y; ++ ret = gpio_request(RB4XX_NAND_GPIO_CLE, "NAND CLE"); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to request gpio %d\n", ++ RB4XX_NAND_GPIO_CLE); ++ goto err_free_gpio_ale; + } + -+ err = gpio_direction_output(pdata->gpio_pin_s0, 0); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_s0, err); -+ goto err_free_2y; ++ ret = gpio_direction_output(RB4XX_NAND_GPIO_CLE, 0); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", ++ RB4XX_NAND_GPIO_CLE); ++ goto err_free_gpio_cle; + } + -+ err = gpio_direction_output(pdata->gpio_pin_s1, 0); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_s1, err); -+ goto err_free_2y; ++ ret = gpio_request(RB4XX_NAND_GPIO_NCE, "NAND NCE"); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to request gpio %d\n", ++ RB4XX_NAND_GPIO_NCE); ++ goto err_free_gpio_cle; + } + -+ err = gpio_direction_input(pdata->gpio_pin_1y); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_1y, err); -+ goto err_free_2y; ++ ret = gpio_direction_output(RB4XX_NAND_GPIO_NCE, 1); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", ++ RB4XX_NAND_GPIO_ALE); ++ goto err_free_gpio_nce; + } + -+ err = gpio_direction_input(pdata->gpio_pin_2y); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_2y, err); -+ goto err_free_2y; ++ info = kzalloc(sizeof(*info), GFP_KERNEL); ++ if (!info) { ++ dev_err(&pdev->dev, "rb4xx-nand: no memory for private data\n"); ++ ret = -ENOMEM; ++ goto err_free_gpio_nce; + } + -+ nxp->parent = &pdev->dev; -+ mutex_init(&nxp->lock); ++ info->chip.priv = &info; ++ info->mtd.priv = &info->chip; ++ info->mtd.owner = THIS_MODULE; + -+ gc = &nxp->gpio_chip; ++ info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl; ++ info->chip.dev_ready = rb4xx_nand_dev_ready; ++ info->chip.read_byte = rb4xx_nand_read_byte; ++ info->chip.write_buf = rb4xx_nand_write_buf; ++ info->chip.read_buf = rb4xx_nand_read_buf; ++#if 0 ++ info->chip.verify_buf = rb4xx_nand_verify_buf; ++#endif + -+ gc->direction_input = nxp_74hc153_direction_input; -+ gc->direction_output = nxp_74hc153_direction_output; -+ gc->get = nxp_74hc153_get_value; -+ gc->set = nxp_74hc153_set_value; -+ gc->can_sleep = 1; ++ info->chip.chip_delay = 25; ++ info->chip.ecc.mode = NAND_ECC_SOFT; ++ info->chip.options |= NAND_NO_AUTOINCR; + -+ gc->base = pdata->gpio_base; -+ gc->ngpio = NXP_74HC153_NUM_GPIOS; -+ gc->label = dev_name(nxp->parent); -+ gc->dev = nxp->parent; -+ gc->owner = THIS_MODULE; ++ platform_set_drvdata(pdev, info); + -+ err = gpiochip_add(&nxp->gpio_chip); -+ if (err) { -+ dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); -+ goto err_free_2y; ++ ret = nand_scan_ident(&info->mtd, 1, NULL); ++ if (ret) { ++ ret = -ENXIO; ++ goto err_free_info; + } + -+ platform_set_drvdata(pdev, nxp); -+ return 0; ++ if (info->mtd.writesize == 512) ++ info->chip.ecc.layout = &rb4xx_nand_ecclayout; + -+err_free_2y: -+ gpio_free(pdata->gpio_pin_2y); -+err_free_1y: -+ gpio_free(pdata->gpio_pin_1y); -+err_free_s1: -+ gpio_free(pdata->gpio_pin_s1); -+err_free_s0: -+ gpio_free(pdata->gpio_pin_s0); -+err_free_nxp: -+ kfree(nxp); -+ return err; -+} ++ ret = nand_scan_tail(&info->mtd); ++ if (ret) { ++ return -ENXIO; ++ goto err_set_drvdata; ++ } + -+static int nxp_74hc153_remove(struct platform_device *pdev) -+{ -+ struct nxp_74hc153_chip *nxp = platform_get_drvdata(pdev); -+ struct nxp_74hc153_platform_data *pdata = pdev->dev.platform_data; ++#ifdef CONFIG_MTD_PARTITIONS ++ ret = add_mtd_partitions(&info->mtd, rb4xx_nand_partitions, ++ ARRAY_SIZE(rb4xx_nand_partitions)); ++#else ++ ret = add_mtd_device(&info->mtd); ++#endif ++ if (ret) ++ goto err_release_nand; + -+ if (nxp) { -+ int err; ++ return 0; + -+ err = gpiochip_remove(&nxp->gpio_chip); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to remove gpio chip, err=%d\n", -+ err); -+ return err; -+ } ++err_release_nand: ++ nand_release(&info->mtd); ++err_set_drvdata: ++ platform_set_drvdata(pdev, NULL); ++err_free_info: ++ kfree(info); ++err_free_gpio_nce: ++ gpio_free(RB4XX_NAND_GPIO_NCE); ++err_free_gpio_cle: ++ gpio_free(RB4XX_NAND_GPIO_CLE); ++err_free_gpio_ale: ++ gpio_free(RB4XX_NAND_GPIO_ALE); ++err_free_gpio_ready: ++ gpio_free(RB4XX_NAND_GPIO_READY); ++err: ++ return ret; ++} + -+ gpio_free(pdata->gpio_pin_2y); -+ gpio_free(pdata->gpio_pin_1y); -+ gpio_free(pdata->gpio_pin_s1); -+ gpio_free(pdata->gpio_pin_s0); ++static int __devexit rb4xx_nand_remove(struct platform_device *pdev) ++{ ++ struct rb4xx_nand_info *info = platform_get_drvdata(pdev); + -+ kfree(nxp); -+ platform_set_drvdata(pdev, NULL); -+ } ++ nand_release(&info->mtd); ++ platform_set_drvdata(pdev, NULL); ++ kfree(info); ++ gpio_free(RB4XX_NAND_GPIO_NCE); ++ gpio_free(RB4XX_NAND_GPIO_CLE); ++ gpio_free(RB4XX_NAND_GPIO_ALE); ++ gpio_free(RB4XX_NAND_GPIO_READY); + + return 0; +} + -+static struct platform_driver nxp_74hc153_driver = { -+ .probe = nxp_74hc153_probe, -+ .remove = __devexit_p(nxp_74hc153_remove), -+ .driver = { -+ .name = NXP_74HC153_DRIVER_NAME, ++static struct platform_driver rb4xx_nand_driver = { ++ .probe = rb4xx_nand_probe, ++ .remove = __devexit_p(rb4xx_nand_remove), ++ .driver = { ++ .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + -+static int __init nxp_74hc153_init(void) ++static int __init rb4xx_nand_init(void) +{ -+ return platform_driver_register(&nxp_74hc153_driver); ++ return platform_driver_register(&rb4xx_nand_driver); +} -+subsys_initcall(nxp_74hc153_init); + -+static void __exit nxp_74hc153_exit(void) ++static void __exit rb4xx_nand_exit(void) +{ -+ platform_driver_unregister(&nxp_74hc153_driver); ++ platform_driver_unregister(&rb4xx_nand_driver); +} -+module_exit(nxp_74hc153_exit); + ++module_init(rb4xx_nand_init); ++module_exit(rb4xx_nand_exit); ++ ++MODULE_DESCRIPTION(DRV_DESC); ++MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("Gabor Juhos "); -+MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC153"); ++MODULE_AUTHOR("Imre Kaloz "); +MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" NXP_74HC153_DRIVER_NAME); -diff -Nur linux-2.6.39.orig/drivers/leds/leds-rb750.c linux-2.6.39/drivers/leds/leds-rb750.c ---- linux-2.6.39.orig/drivers/leds/leds-rb750.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/leds/leds-rb750.c 2011-04-27 12:19:22.267661616 +0200 -@@ -0,0 +1,141 @@ +diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c linux-2.6.39/drivers/mtd/nand/rb750_nand.c +--- linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/mtd/nand/rb750_nand.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,361 @@ +/* -+ * LED driver for the RouterBOARD 750 -+ * -+ * Copyright (C) 2010 Gabor Juhos ++ * NAND flash driver for the MikroTik RouterBOARD 750 + * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. ++ * Copyright (C) 2010 Gabor Juhos + * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. + */ -+#include ++ +#include ++#include ++#include ++#include +#include -+#include ++#include +#include + ++#include +#include + -+#define DRV_NAME "leds-rb750" ++#define DRV_NAME "rb750-nand" ++#define DRV_VERSION "0.1.0" ++#define DRV_DESC "NAND flash driver for the RouterBOARD 750" + -+struct rb750_led_dev { -+ struct led_classdev cdev; -+ u32 mask; -+ int active_low; ++#define RB750_NAND_IO0 BIT(RB750_GPIO_NAND_IO0) ++#define RB750_NAND_ALE BIT(RB750_GPIO_NAND_ALE) ++#define RB750_NAND_CLE BIT(RB750_GPIO_NAND_CLE) ++#define RB750_NAND_NRE BIT(RB750_GPIO_NAND_NRE) ++#define RB750_NAND_NWE BIT(RB750_GPIO_NAND_NWE) ++#define RB750_NAND_RDY BIT(RB750_GPIO_NAND_RDY) ++#define RB750_NAND_NCE BIT(RB750_GPIO_NAND_NCE) ++ ++#define RB750_NAND_DATA_SHIFT 1 ++#define RB750_NAND_DATA_BITS (0xff << RB750_NAND_DATA_SHIFT) ++#define RB750_NAND_INPUT_BITS (RB750_NAND_DATA_BITS | RB750_NAND_RDY) ++#define RB750_NAND_OUTPUT_BITS (RB750_NAND_ALE | RB750_NAND_CLE | \ ++ RB750_NAND_NRE | RB750_NAND_NWE | \ ++ RB750_NAND_NCE) ++ ++struct rb750_nand_info { ++ struct nand_chip chip; ++ struct mtd_info mtd; +}; + -+struct rb750_led_drvdata { -+ struct rb750_led_dev *led_devs; -+ int num_leds; ++/* ++ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader ++ * will not be able to find the kernel that we load. ++ */ ++static struct nand_ecclayout rb750_nand_ecclayout = { ++ .eccbytes = 6, ++ .eccpos = { 8, 9, 10, 13, 14, 15 }, ++ .oobavail = 9, ++ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } +}; + -+static inline struct rb750_led_dev *to_rbled(struct led_classdev *led_cdev) -+{ -+ return (struct rb750_led_dev *)container_of(led_cdev, -+ struct rb750_led_dev, cdev); -+} ++static struct mtd_partition rb750_nand_partitions[] = { ++ { ++ .name = "booter", ++ .offset = 0, ++ .size = (256 * 1024), ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "kernel", ++ .offset = (256 * 1024), ++ .size = (4 * 1024 * 1024) - (256 * 1024), ++ }, { ++ .name = "rootfs", ++ .offset = MTDPART_OFS_NXTBLK, ++ .size = MTDPART_SIZ_FULL, ++ }, ++}; + -+static void rb750_led_brightness_set(struct led_classdev *led_cdev, -+ enum led_brightness value) ++static void rb750_nand_write(const u8 *buf, unsigned len) +{ -+ struct rb750_led_dev *rbled = to_rbled(led_cdev); -+ int level; ++ void __iomem *base = ar71xx_gpio_base; ++ u32 out; ++ unsigned i; + -+ level = (value == LED_OFF) ? 0 : 1; -+ level ^= rbled->active_low; ++ /* set data lines to output mode */ ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_DATA_BITS, ++ base + GPIO_REG_OE); + -+ if (level) -+ rb750_latch_change(0, rbled->mask); -+ else -+ rb750_latch_change(rbled->mask, 0); ++ out = __raw_readl(base + GPIO_REG_OUT); ++ out &= ~(RB750_NAND_DATA_BITS | RB750_NAND_NWE); ++ for (i = 0; i != len; i++) { ++ u32 data; ++ ++ data = buf[i]; ++ data <<= RB750_NAND_DATA_SHIFT; ++ data |= out; ++ __raw_writel(data, base + GPIO_REG_OUT); ++ ++ __raw_writel(data | RB750_NAND_NWE, base + GPIO_REG_OUT); ++ /* flush write */ ++ __raw_readl(base + GPIO_REG_OUT); ++ } ++ ++ /* set data lines to input mode */ ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~RB750_NAND_DATA_BITS, ++ base + GPIO_REG_OE); ++ /* flush write */ ++ __raw_readl(base + GPIO_REG_OE); +} + -+static int __devinit rb750_led_probe(struct platform_device *pdev) ++static int rb750_nand_read_verify(u8 *read_buf, unsigned len, ++ const u8 *verify_buf) +{ -+ struct rb750_led_platform_data *pdata; -+ struct rb750_led_drvdata *drvdata; -+ int ret = 0; -+ int i; ++ void __iomem *base = ar71xx_gpio_base; ++ unsigned i; + -+ pdata = pdev->dev.platform_data; -+ if (!pdata) -+ return -EINVAL; ++ for (i = 0; i < len; i++) { ++ u8 data; + -+ drvdata = kzalloc(sizeof(struct rb750_led_drvdata) + -+ sizeof(struct rb750_led_dev) * pdata->num_leds, -+ GFP_KERNEL); -+ if (!drvdata) -+ return -ENOMEM; -+ -+ drvdata->num_leds = pdata->num_leds; -+ drvdata->led_devs = (struct rb750_led_dev *) &drvdata[1]; -+ -+ for (i = 0; i < drvdata->num_leds; i++) { -+ struct rb750_led_dev *rbled = &drvdata->led_devs[i]; -+ struct rb750_led_data *led_data = &pdata->leds[i]; ++ /* activate RE line */ ++ __raw_writel(RB750_NAND_NRE, base + GPIO_REG_CLEAR); ++ /* flush write */ ++ __raw_readl(base + GPIO_REG_CLEAR); + -+ rbled->cdev.name = led_data->name; -+ rbled->cdev.default_trigger = led_data->default_trigger; -+ rbled->cdev.brightness_set = rb750_led_brightness_set; -+ rbled->cdev.brightness = LED_OFF; ++ /* read input lines */ ++ data = __raw_readl(base + GPIO_REG_IN) >> RB750_NAND_DATA_SHIFT; + -+ rbled->mask = led_data->mask; -+ rbled->active_low = !!led_data->active_low; ++ /* deactivate RE line */ ++ __raw_writel(RB750_NAND_NRE, base + GPIO_REG_SET); + -+ ret = led_classdev_register(&pdev->dev, &rbled->cdev); -+ if (ret) -+ goto err; ++ if (read_buf) ++ read_buf[i] = data; ++ else if (verify_buf && verify_buf[i] != data) ++ return -EFAULT; + } + -+ platform_set_drvdata(pdev, drvdata); + return 0; -+ -+err: -+ for (i = i - 1; i >= 0; i--) -+ led_classdev_unregister(&drvdata->led_devs[i].cdev); -+ -+ kfree(drvdata); -+ return ret; +} + -+static int __devexit rb750_led_remove(struct platform_device *pdev) ++static void rb750_nand_select_chip(struct mtd_info *mtd, int chip) +{ -+ struct rb750_led_drvdata *drvdata; -+ int i; ++ void __iomem *base = ar71xx_gpio_base; ++ u32 func; + -+ drvdata = platform_get_drvdata(pdev); -+ for (i = 0; i < drvdata->num_leds; i++) -+ led_classdev_unregister(&drvdata->led_devs[i].cdev); ++ func = __raw_readl(base + GPIO_REG_FUNC); ++ if (chip >= 0) { ++ /* disable latch */ ++ rb750_latch_change(RB750_LVC573_LE, 0); + -+ kfree(drvdata); -+ return 0; -+} ++ /* disable alternate functions */ ++ ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, ++ AR724X_GPIO_FUNC_SPI_EN); + -+static struct platform_driver rb750_led_driver = { -+ .probe = rb750_led_probe, -+ .remove = __devexit_p(rb750_led_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; ++ /* set input mode for data lines */ ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ++ ~RB750_NAND_INPUT_BITS, ++ base + GPIO_REG_OE); + -+MODULE_ALIAS("platform:leds-rb750"); ++ /* deactivate RE and WE lines */ ++ __raw_writel(RB750_NAND_NRE | RB750_NAND_NWE, ++ base + GPIO_REG_SET); ++ /* flush write */ ++ (void) __raw_readl(base + GPIO_REG_SET); + -+static int __init rb750_led_init(void) -+{ -+ return platform_driver_register(&rb750_led_driver); ++ /* activate CE line */ ++ __raw_writel(RB750_NAND_NCE, base + GPIO_REG_CLEAR); ++ } else { ++ /* deactivate CE line */ ++ __raw_writel(RB750_NAND_NCE, base + GPIO_REG_SET); ++ /* flush write */ ++ (void) __raw_readl(base + GPIO_REG_SET); ++ ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) | ++ RB750_NAND_IO0 | RB750_NAND_RDY, ++ base + GPIO_REG_OE); ++ ++ /* restore alternate functions */ ++ ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN, ++ AR724X_GPIO_FUNC_JTAG_DISABLE); ++ ++ /* enable latch */ ++ rb750_latch_change(0, RB750_LVC573_LE); ++ } +} + -+static void __exit rb750_led_exit(void) ++static int rb750_nand_dev_ready(struct mtd_info *mtd) +{ -+ platform_driver_unregister(&rb750_led_driver); ++ void __iomem *base = ar71xx_gpio_base; ++ ++ return !!(__raw_readl(base + GPIO_REG_IN) & RB750_NAND_RDY); +} + -+module_init(rb750_led_init); -+module_exit(rb750_led_exit); ++static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, ++ unsigned int ctrl) ++{ ++ if (ctrl & NAND_CTRL_CHANGE) { ++ void __iomem *base = ar71xx_gpio_base; ++ u32 t; + -+MODULE_DESCRIPTION(DRV_NAME); -+MODULE_DESCRIPTION("LED driver for the RouterBOARD 750"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c linux-2.6.39/drivers/leds/leds-wndr3700-usb.c ---- linux-2.6.39.orig/drivers/leds/leds-wndr3700-usb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/leds/leds-wndr3700-usb.c 2011-04-27 12:19:22.267661616 +0200 -@@ -0,0 +1,75 @@ -+/* -+ * USB LED driver for the NETGEAR WNDR3700 -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ t = __raw_readl(base + GPIO_REG_OUT); + -+#include -+#include -+#include ++ t &= ~(RB750_NAND_CLE | RB750_NAND_ALE); ++ t |= (ctrl & NAND_CLE) ? RB750_NAND_CLE : 0; ++ t |= (ctrl & NAND_ALE) ? RB750_NAND_ALE : 0; + -+#include ++ __raw_writel(t, base + GPIO_REG_OUT); ++ /* flush write */ ++ __raw_readl(base + GPIO_REG_OUT); ++ } + -+#define DRIVER_NAME "wndr3700-led-usb" ++ if (cmd != NAND_CMD_NONE) { ++ u8 t = cmd; ++ rb750_nand_write(&t, 1); ++ } ++} + -+static void wndr3700_usb_led_set(struct led_classdev *cdev, -+ enum led_brightness brightness) ++static u8 rb750_nand_read_byte(struct mtd_info *mtd) +{ -+ if (brightness) -+ ar71xx_device_start(RESET_MODULE_GE1_PHY); -+ else -+ ar71xx_device_stop(RESET_MODULE_GE1_PHY); ++ u8 data = 0; ++ rb750_nand_read_verify(&data, 1, NULL); ++ return data; +} + -+static enum led_brightness wndr3700_usb_led_get(struct led_classdev *cdev) ++static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) +{ -+ return ar71xx_device_stopped(RESET_MODULE_GE1_PHY) ? LED_OFF : LED_FULL; ++ rb750_nand_read_verify(buf, len, NULL); +} + -+static struct led_classdev wndr3700_usb_led = { -+ .name = "wndr3700:green:usb", -+ .brightness_set = wndr3700_usb_led_set, -+ .brightness_get = wndr3700_usb_led_get, -+}; -+ -+static int __devinit wndr3700_usb_led_probe(struct platform_device *pdev) ++static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) +{ -+ return led_classdev_register(&pdev->dev, &wndr3700_usb_led); ++ rb750_nand_write(buf, len); +} + -+static int __devexit wndr3700_usb_led_remove(struct platform_device *pdev) ++static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len) +{ -+ led_classdev_unregister(&wndr3700_usb_led); -+ return 0; ++ return rb750_nand_read_verify(NULL, len, buf); +} + -+static struct platform_driver wndr3700_usb_led_driver = { -+ .probe = wndr3700_usb_led_probe, -+ .remove = __devexit_p(wndr3700_usb_led_remove), -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init wndr3700_usb_led_init(void) ++static void __init rb750_nand_gpio_init(void) +{ -+ return platform_driver_register(&wndr3700_usb_led_driver); ++ void __iomem *base = ar71xx_gpio_base; ++ u32 out; ++ ++ out = __raw_readl(base + GPIO_REG_OUT); ++ ++ /* setup output levels */ ++ __raw_writel(RB750_NAND_NCE | RB750_NAND_NRE | RB750_NAND_NWE, ++ base + GPIO_REG_SET); ++ ++ __raw_writel(RB750_NAND_ALE | RB750_NAND_CLE, ++ base + GPIO_REG_CLEAR); ++ ++ /* setup input lines */ ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(RB750_NAND_INPUT_BITS), ++ base + GPIO_REG_OE); ++ ++ /* setup output lines */ ++ __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_OUTPUT_BITS, ++ base + GPIO_REG_OE); ++ ++ rb750_latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0); +} + -+static void __exit wndr3700_usb_led_exit(void) ++static int __init rb750_nand_probe(struct platform_device *pdev) +{ -+ platform_driver_unregister(&wndr3700_usb_led_driver); -+} ++ struct rb750_nand_info *info; ++ int ret; + -+module_init(wndr3700_usb_led_init); -+module_exit(wndr3700_usb_led_exit); ++ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); + -+MODULE_DESCRIPTION("USB LED driver for the NETGEAR WNDR3700"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" DRIVER_NAME); -diff -Nur linux-2.6.39.orig/drivers/Makefile linux-2.6.39/drivers/Makefile ---- linux-2.6.39.orig/drivers/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/Makefile 2011-08-23 15:10:42.370478643 +0200 -@@ -46,8 +46,8 @@ - obj-$(CONFIG_SCSI) += scsi/ - obj-$(CONFIG_ATA) += ata/ - obj-$(CONFIG_TARGET_CORE) += target/ --obj-$(CONFIG_MTD) += mtd/ - obj-$(CONFIG_SPI) += spi/ -+obj-$(CONFIG_MTD) += mtd/ - obj-y += net/ - obj-$(CONFIG_ATM) += atm/ - obj-$(CONFIG_FUSION) += message/ -diff -Nur linux-2.6.39.orig/drivers/mtd/chips/cfi_cmdset_0002.c linux-2.6.39/drivers/mtd/chips/cfi_cmdset_0002.c ---- linux-2.6.39.orig/drivers/mtd/chips/cfi_cmdset_0002.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/mtd/chips/cfi_cmdset_0002.c 2011-08-22 16:22:28.477979654 +0200 -@@ -39,7 +39,7 @@ - #include - - #define AMD_BOOTLOC_BUG --#define FORCE_WORD_WRITE 0 -+#define FORCE_WORD_WRITE 1 - - #define MAX_WORD_RETRIES 3 - -@@ -50,7 +50,9 @@ - - static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); - static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); -+#if !FORCE_WORD_WRITE - static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); -+#endif - static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *); - static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *); - static void cfi_amdstd_sync (struct mtd_info *); -@@ -186,6 +188,7 @@ - } - #endif - -+#if !FORCE_WORD_WRITE - static void fixup_use_write_buffers(struct mtd_info *mtd) - { - struct map_info *map = mtd->priv; -@@ -195,6 +198,7 @@ - mtd->write = cfi_amdstd_write_buffers; - } - } -+#endif /* !FORCE_WORD_WRITE */ - - /* Atmel chips don't use the same PRI format as AMD chips */ - static void fixup_convert_atmel_pri(struct mtd_info *mtd) -@@ -1377,6 +1381,7 @@ - /* - * FIXME: interleaved mode not tested, and probably not supported! - */ -+#if !FORCE_WORD_WRITE - static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, - unsigned long adr, const u_char *buf, - int len) -@@ -1487,7 +1492,6 @@ - return ret; - } - -- - static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) - { -@@ -1566,6 +1570,7 @@ - - return 0; - } -+#endif /* !FORCE_WORD_WRITE */ - - - /* -diff -Nur linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c ---- linux-2.6.39.orig/drivers/mtd/maps/ar91xx_flash.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/mtd/maps/ar91xx_flash.c 2011-04-27 12:19:22.177661504 +0200 -@@ -0,0 +1,310 @@ -+/* -+ * Parallel flash driver for the Atheros AR91xx SoC -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ rb750_nand_gpio_init(); + -+#include -+#include ++ info = kzalloc(sizeof(*info), GFP_KERNEL); ++ if (!info) ++ return -ENOMEM; + -+#define DRV_NAME "ar91xx-flash" ++ info->chip.priv = &info; ++ info->mtd.priv = &info->chip; ++ info->mtd.owner = THIS_MODULE; + -+struct ar91xx_flash_info { -+ struct mtd_info *mtd; -+ struct map_info map; -+#ifdef CONFIG_MTD_PARTITIONS -+ int nr_parts; -+ struct mtd_partition *parts; -+#endif -+}; ++ info->chip.select_chip = rb750_nand_select_chip; ++ info->chip.cmd_ctrl = rb750_nand_cmd_ctrl; ++ info->chip.dev_ready = rb750_nand_dev_ready; ++ info->chip.read_byte = rb750_nand_read_byte; ++ info->chip.write_buf = rb750_nand_write_buf; ++ info->chip.read_buf = rb750_nand_read_buf; ++ info->chip.verify_buf = rb750_nand_verify_buf; + -+static map_word ar91xx_flash_read(struct map_info *map, unsigned long ofs) -+{ -+ map_word val; ++ info->chip.chip_delay = 25; ++ info->chip.ecc.mode = NAND_ECC_SOFT; ++ info->chip.options |= NAND_NO_AUTOINCR; + -+ if (map_bankwidth_is_1(map)) -+ val.x[0] = __raw_readb(map->virt + (ofs ^ 3)); -+ else if (map_bankwidth_is_2(map)) -+ val.x[0] = __raw_readw(map->virt + (ofs ^ 2)); -+ else -+ val = map_word_ff(map); ++ platform_set_drvdata(pdev, info); + -+ return val; -+} ++ ret = nand_scan_ident(&info->mtd, 1); ++ if (ret) { ++ ret = -ENXIO; ++ goto err_free_info; ++ } + -+static void ar91xx_flash_write(struct map_info *map, map_word d, -+ unsigned long ofs) -+{ -+ if (map_bankwidth_is_1(map)) -+ __raw_writeb(d.x[0], map->virt + (ofs ^ 3)); -+ else if (map_bankwidth_is_2(map)) -+ __raw_writew(d.x[0], map->virt + (ofs ^ 2)); ++ if (info->mtd.writesize == 512) ++ info->chip.ecc.layout = &rb750_nand_ecclayout; + -+ mb(); -+} ++ ret = nand_scan_tail(&info->mtd); ++ if (ret) { ++ return -ENXIO; ++ goto err_set_drvdata; ++ } + -+static map_word ar91xx_flash_read_lock(struct map_info *map, unsigned long ofs) -+{ -+ map_word ret; ++#ifdef CONFIG_MTD_PARTITIONS ++ ret = add_mtd_partitions(&info->mtd, rb750_nand_partitions, ++ ARRAY_SIZE(rb750_nand_partitions)); ++#else ++ ret = add_mtd_device(&info->mtd); ++#endif ++ if (ret) ++ goto err_release_nand; + -+ ar71xx_flash_acquire(); -+ ret = ar91xx_flash_read(map, ofs); -+ ar71xx_flash_release(); ++ return 0; + ++err_release_nand: ++ nand_release(&info->mtd); ++err_set_drvdata: ++ platform_set_drvdata(pdev, NULL); ++err_free_info: ++ kfree(info); + return ret; +} + -+static void ar91xx_flash_write_lock(struct map_info *map, map_word d, -+ unsigned long ofs) ++static int __devexit rb750_nand_remove(struct platform_device *pdev) +{ -+ ar71xx_flash_acquire(); -+ ar91xx_flash_write(map, d, ofs); -+ ar71xx_flash_release(); -+} ++ struct rb750_nand_info *info = platform_get_drvdata(pdev); + -+static void ar91xx_flash_copy_from_lock(struct map_info *map, void *to, -+ unsigned long from, ssize_t len) -+{ -+ ar71xx_flash_acquire(); -+ inline_map_copy_from(map, to, from, len); -+ ar71xx_flash_release(); ++ nand_release(&info->mtd); ++ platform_set_drvdata(pdev, NULL); ++ kfree(info); ++ ++ return 0; +} + -+static void ar91xx_flash_copy_to_lock(struct map_info *map, unsigned long to, -+ const void *from, ssize_t len) ++static struct platform_driver rb750_nand_driver = { ++ .probe = rb750_nand_probe, ++ .remove = __devexit_p(rb750_nand_remove), ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init rb750_nand_init(void) +{ -+ ar71xx_flash_acquire(); -+ inline_map_copy_to(map, to, from, len); -+ ar71xx_flash_release(); ++ return platform_driver_register(&rb750_nand_driver); +} + -+static int ar91xx_flash_remove(struct platform_device *pdev) ++static void __exit rb750_nand_exit(void) +{ -+ struct ar91xx_flash_platform_data *pdata; -+ struct ar91xx_flash_info *info; ++ platform_driver_unregister(&rb750_nand_driver); ++} + -+ info = platform_get_drvdata(pdev); -+ if (info == NULL) -+ return 0; ++module_init(rb750_nand_init); ++module_exit(rb750_nand_exit); + -+ platform_set_drvdata(pdev, NULL); ++MODULE_DESCRIPTION(DRV_DESC); ++MODULE_VERSION(DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c linux-2.6.39/drivers/mtd/wrt160nl_part.c +--- linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/mtd/wrt160nl_part.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,190 @@ ++/* ++ * Copyright (C) 2009 Christian Daniel ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * 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. ++ * ++ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ * TRX flash partition table. ++ * Based on ar7 map by Felix Fietkau ++ * ++ */ + -+ if (info->mtd == NULL) -+ return 0; ++#include ++#include ++#include + -+ pdata = pdev->dev.platform_data; -+#ifdef CONFIG_MTD_PARTITIONS -+ if (info->nr_parts) { -+ del_mtd_partitions(info->mtd); -+ kfree(info->parts); -+ } else if (pdata->nr_parts) { -+ del_mtd_partitions(info->mtd); -+ } else { -+ del_mtd_device(info->mtd); -+ } -+#else -+ del_mtd_device(info->mtd); -+#endif -+ map_destroy(info->mtd); ++#include ++#include + -+ return 0; -+} ++struct cybertan_header { ++ char magic[4]; ++ u8 res1[4]; ++ char fw_date[3]; ++ char fw_ver[3]; ++ char id[4]; ++ char hw_ver; ++ char unused; ++ u8 flags[2]; ++ u8 res2[10]; ++}; + -+static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; -+#ifdef CONFIG_MTD_PARTITIONS -+static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; -+#endif ++#define TRX_PARTS 6 ++#define TRX_MAGIC 0x30524448 ++#define TRX_MAX_OFFSET 3 + -+static int ar91xx_flash_probe(struct platform_device *pdev) -+{ -+ struct ar91xx_flash_platform_data *pdata; -+ struct ar91xx_flash_info *info; -+ struct resource *res; -+ struct resource *region; -+ const char **probe_type; -+ int err = 0; ++struct trx_header { ++ uint32_t magic; /* "HDR0" */ ++ uint32_t len; /* Length of file including header */ ++ uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ ++ uint32_t flag_version; /* 0:15 flags, 16:31 version */ ++ uint32_t offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ ++}; + -+ pdata = pdev->dev.platform_data; -+ if (pdata == NULL) -+ return -EINVAL; ++#define IH_MAGIC 0x27051956 /* Image Magic Number */ ++#define IH_NMLEN 32 /* Image Name Length */ + -+ info = devm_kzalloc(&pdev->dev, sizeof(struct ar91xx_flash_info), -+ GFP_KERNEL); -+ if (info == NULL) { -+ err = -ENOMEM; -+ goto err_out; -+ } ++struct uimage_header { ++ uint32_t ih_magic; /* Image Header Magic Number */ ++ uint32_t ih_hcrc; /* Image Header CRC Checksum */ ++ uint32_t ih_time; /* Image Creation Timestamp */ ++ uint32_t ih_size; /* Image Data Size */ ++ uint32_t ih_load; /* Data» Load Address */ ++ uint32_t ih_ep; /* Entry Point Address */ ++ uint32_t ih_dcrc; /* Image Data CRC Checksum */ ++ uint8_t ih_os; /* Operating System */ ++ uint8_t ih_arch; /* CPU architecture */ ++ uint8_t ih_type; /* Image Type */ ++ uint8_t ih_comp; /* Compression Type */ ++ uint8_t ih_name[IH_NMLEN]; /* Image Name */ ++}; + -+ platform_set_drvdata(pdev, info); ++struct wrt160nl_header { ++ struct cybertan_header cybertan; ++ struct trx_header trx; ++ struct uimage_header uimage; ++} __attribute__ ((packed)); + -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (res == NULL) { -+ err = -ENOENT; -+ goto err_out; -+ } ++static struct mtd_partition trx_parts[TRX_PARTS]; + -+ dev_info(&pdev->dev, "%.8llx at %.8llx\n", -+ (unsigned long long)(res->end - res->start + 1), -+ (unsigned long long)res->start); ++#define WRT160NL_UBOOT_LEN 0x40000 ++#define WRT160NL_ART_LEN 0x10000 ++#define WRT160NL_NVRAM_LEN 0x10000 + -+ region = devm_request_mem_region(&pdev->dev, -+ res->start, res->end - res->start + 1, -+ dev_name(&pdev->dev)); -+ if (region == NULL) { -+ dev_err(&pdev->dev, "could not reserve memory region\n"); -+ err = -ENOMEM; -+ goto err_out; ++static int wrt160nl_parse_partitions(struct mtd_info *master, ++ struct mtd_partition **pparts, ++ unsigned long origin) ++{ ++ struct wrt160nl_header *header; ++ struct trx_header *theader; ++ struct uimage_header *uheader; ++ size_t retlen; ++ unsigned int kernel_len; ++ unsigned int uboot_len = max(master->erasesize, WRT160NL_UBOOT_LEN); ++ unsigned int nvram_len = max(master->erasesize, WRT160NL_NVRAM_LEN); ++ unsigned int art_len = max(master->erasesize, WRT160NL_ART_LEN); ++ int ret; ++ ++ header = vmalloc(sizeof(*header)); ++ if (!header) { ++ return -ENOMEM; ++ goto out; + } + -+ info->map.name = dev_name(&pdev->dev); -+ info->map.phys = res->start; -+ info->map.size = res->end - res->start + 1; -+ info->map.bankwidth = pdata->width; ++ ret = master->read(master, uboot_len, sizeof(*header), ++ &retlen, (void *) header); ++ if (ret) ++ goto free_hdr; + -+ info->map.virt = devm_ioremap(&pdev->dev, info->map.phys, -+ info->map.size); -+ if (info->map.virt == NULL) { -+ dev_err(&pdev->dev, "failed to ioremap flash region\n"); -+ err = -EIO; -+ goto err_out; ++ if (retlen != sizeof(*header)) { ++ ret = -EIO; ++ goto free_hdr; + } + -+ simple_map_init(&info->map); -+ if (pdata->is_shared) { -+ info->map.read = ar91xx_flash_read_lock; -+ info->map.write = ar91xx_flash_write_lock; -+ info->map.copy_from = ar91xx_flash_copy_from_lock; -+ info->map.copy_to = ar91xx_flash_copy_to_lock; -+ } else { -+ info->map.read = ar91xx_flash_read; -+ info->map.write = ar91xx_flash_write; ++ if (strncmp(header->cybertan.magic, "NL16", 4) != 0) { ++ printk(KERN_NOTICE "%s: no WRT160NL signature found\n", ++ master->name); ++ goto free_hdr; + } + -+ probe_type = rom_probe_types; -+ for (; info->mtd == NULL && *probe_type != NULL; probe_type++) -+ info->mtd = do_map_probe(*probe_type, &info->map); -+ -+ if (info->mtd == NULL) { -+ dev_err(&pdev->dev, "map_probe failed\n"); -+ err = -ENXIO; -+ goto err_out; ++ theader = &header->trx; ++ if (le32_to_cpu(theader->magic) != TRX_MAGIC) { ++ printk(KERN_NOTICE "%s: no TRX header found\n", master->name); ++ goto free_hdr; + } + -+ info->mtd->owner = THIS_MODULE; -+ -+#ifdef CONFIG_MTD_PARTITIONS -+ if (pdata->nr_parts) { -+ dev_info(&pdev->dev, "using static partition mapping\n"); -+ add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); -+ return 0; ++ uheader = &header->uimage; ++ if (uheader->ih_magic != IH_MAGIC) { ++ printk(KERN_NOTICE "%s: no uImage found\n", master->name); ++ goto free_hdr; + } + -+ err = parse_mtd_partitions(info->mtd, part_probe_types, -+ &info->parts, 0); -+ if (err > 0) { -+ add_mtd_partitions(info->mtd, info->parts, err); -+ return 0; -+ } -+#endif ++ kernel_len = le32_to_cpu(theader->offsets[1]) + ++ sizeof(struct cybertan_header); + -+ add_mtd_device(info->mtd); -+ return 0; ++ trx_parts[0].name = "u-boot"; ++ trx_parts[0].offset = 0; ++ trx_parts[0].size = uboot_len; ++ trx_parts[0].mask_flags = MTD_WRITEABLE; + -+err_out: -+ ar91xx_flash_remove(pdev); -+ return err; -+} ++ trx_parts[1].name = "kernel"; ++ trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size; ++ trx_parts[1].size = kernel_len; ++ trx_parts[1].mask_flags = 0; + -+#ifdef CONFIG_PM -+static int ar91xx_flash_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ struct ar91xx_flash_info *info = platform_get_drvdata(dev); -+ int ret = 0; ++ trx_parts[2].name = "rootfs"; ++ trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size; ++ trx_parts[2].size = master->size - uboot_len - nvram_len - art_len - ++ trx_parts[1].size; ++ trx_parts[2].mask_flags = 0; + -+ if (info->mtd->suspend) -+ ret = info->mtd->suspend(info->mtd); ++ trx_parts[3].name = "nvram"; ++ trx_parts[3].offset = master->size - nvram_len - art_len; ++ trx_parts[3].size = nvram_len; ++ trx_parts[3].mask_flags = MTD_WRITEABLE; + -+ if (ret) -+ goto fail; ++ trx_parts[4].name = "art"; ++ trx_parts[4].offset = master->size - art_len; ++ trx_parts[4].size = art_len; ++ trx_parts[4].mask_flags = MTD_WRITEABLE; + -+ return 0; ++ trx_parts[5].name = "firmware"; ++ trx_parts[5].offset = uboot_len; ++ trx_parts[5].size = master->size - uboot_len - nvram_len - art_len; ++ trx_parts[5].mask_flags = 0; + -+fail: -+ if (info->mtd->suspend) { -+ BUG_ON(!info->mtd->resume); -+ info->mtd->resume(info->mtd); -+ } ++ *pparts = trx_parts; ++ ret = TRX_PARTS; + ++free_hdr: ++ vfree(header); ++out: + return ret; +} + -+static int ar91xx_flash_resume(struct platform_device *pdev) -+{ -+ struct ar91xx_flash_info *info = platform_get_drvdata(pdev); -+ -+ if (info->mtd->resume) -+ info->mtd->resume(info->mtd); -+ -+ return 0; -+} -+ -+static void ar91xx_flash_shutdown(struct platform_device *pdev) -+{ -+ struct ar91xx_flash_info *info = platform_get_drvdata(pdev); -+ -+ if (info->mtd->suspend && info->mtd->resume) -+ if (info->mtd->suspend(info->mtd) == 0) -+ info->mtd->resume(info->mtd); -+} -+#else -+#define ar91xx_flash_suspend NULL -+#define ar91xx_flash_resume NULL -+#define ar91xx_flash_shutdown NULL -+#endif -+ -+static struct platform_driver ar91xx_flash_driver = { -+ .probe = ar91xx_flash_probe, -+ .remove = ar91xx_flash_remove, -+ .suspend = ar91xx_flash_suspend, -+ .resume = ar91xx_flash_resume, -+ .shutdown = ar91xx_flash_shutdown, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, ++static struct mtd_part_parser wrt160nl_parser = { ++ .owner = THIS_MODULE, ++ .parse_fn = wrt160nl_parse_partitions, ++ .name = "wrt160nl", +}; + -+static int __init ar91xx_flash_init(void) -+{ -+ return platform_driver_register(&ar91xx_flash_driver); -+} -+ -+static void __exit ar91xx_flash_exit(void) ++static int __init wrt160nl_parser_init(void) +{ -+ platform_driver_unregister(&ar91xx_flash_driver); ++ return register_mtd_parser(&wrt160nl_parser); +} + -+module_init(ar91xx_flash_init); -+module_exit(ar91xx_flash_exit); ++module_init(wrt160nl_parser_init); + -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_DESCRIPTION("Parallel flash driver for the Atheros AR91xx SoC"); -+MODULE_ALIAS("platform:" DRV_NAME); -diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Kconfig linux-2.6.39/drivers/mtd/maps/Kconfig ---- linux-2.6.39.orig/drivers/mtd/maps/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/mtd/maps/Kconfig 2011-08-22 16:22:06.367979538 +0200 -@@ -260,6 +260,13 @@ - Support for parsing CFE image tag and creating MTD partitions on - Broadcom BCM63xx boards. ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Christian Daniel "); +diff -Nur linux-2.6.39.orig/drivers/net/Kconfig linux-2.6.39/drivers/net/Kconfig +--- linux-2.6.39.orig/drivers/net/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/Kconfig 2011-08-24 18:17:24.000000000 +0200 +@@ -2071,6 +2071,8 @@ -+config MTD_AR91XX_FLASH -+ tristate "Atheros AR91xx parallel flash support" + The safe and default value for this is N. + ++source drivers/net/ag71xx/Kconfig ++ + config DL2K + tristate "DL2000/TC902x-based Gigabit Ethernet support" + depends on PCI +diff -Nur linux-2.6.39.orig/drivers/net/Makefile linux-2.6.39/drivers/net/Makefile +--- linux-2.6.39.orig/drivers/net/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/Makefile 2011-08-24 18:17:24.000000000 +0200 +@@ -112,6 +112,7 @@ + # end link order section + # + ++obj-$(CONFIG_AG71XX) += ag71xx/ + obj-$(CONFIG_SUNDANCE) += sundance.o + obj-$(CONFIG_HAMACHI) += hamachi.o + obj-$(CONFIG_NET) += Space.o loopback.o +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Kconfig linux-2.6.39/drivers/net/ag71xx/Kconfig +--- linux-2.6.39.orig/drivers/net/ag71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/Kconfig 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,33 @@ ++config AG71XX ++ tristate "Atheros AR71xx built-in ethernet mac support" + depends on ATHEROS_AR71XX -+ select MTD_COMPLEX_MAPPINGS ++ select PHYLIB + help -+ Parallel flash driver for the Atheros AR91xx based boards. ++ If you wish to compile a kernel for AR71xx/91xx and enable ++ ethernet support, then you should always answer Y to this. + - config MTD_DILNETPC - tristate "CFI Flash device mapped on DIL/Net PC" - depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN -diff -Nur linux-2.6.39.orig/drivers/mtd/maps/Makefile linux-2.6.39/drivers/mtd/maps/Makefile ---- linux-2.6.39.orig/drivers/mtd/maps/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/mtd/maps/Makefile 2011-08-22 16:22:06.387979567 +0200 -@@ -40,6 +40,7 @@ - obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.o - obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o - obj-$(CONFIG_MTD_PCI) += pci.o -+obj-$(CONFIG_MTD_AR91XX_FLASH) += ar91xx_flash.o - obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o - obj-$(CONFIG_MTD_EDB7312) += edb7312.o - obj-$(CONFIG_MTD_IMPA7) += impa7.o -diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Kconfig linux-2.6.39/drivers/mtd/nand/Kconfig ---- linux-2.6.39.orig/drivers/mtd/nand/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/mtd/nand/Kconfig 2011-08-23 14:22:33.407989933 +0200 -@@ -531,4 +531,9 @@ - Enables support for NAND Flash chips on the ST Microelectronics - Flexible Static Memory Controller (FSMC) - -+config MTD_NAND_RB4XX -+ tristate "NAND flash driver for RouterBoard 4xx series" -+ depends on MTD_NAND && AR71XX_MACH_RB4XX -+ select SPI_AR71XX ++if AG71XX + - endif # MTD_NAND -diff -Nur linux-2.6.39.orig/drivers/mtd/nand/Makefile linux-2.6.39/drivers/mtd/nand/Makefile ---- linux-2.6.39.orig/drivers/mtd/nand/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/mtd/nand/Makefile 2011-08-22 16:22:41.217981942 +0200 -@@ -34,6 +34,7 @@ - obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o - obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o - obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o -+obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o - obj-$(CONFIG_MTD_ALAUDA) += alauda.o - obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o - obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o -diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c ---- linux-2.6.39.orig/drivers/mtd/nand/rb4xx_nand.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/mtd/nand/rb4xx_nand.c 2011-08-23 11:36:58.637983055 +0200 -@@ -0,0 +1,311 @@ ++config AG71XX_DEBUG ++ bool "Atheros AR71xx built-in ethernet driver debugging" ++ default n ++ help ++ Atheros AR71xx built-in ethernet driver debugging messages. ++ ++config AG71XX_DEBUG_FS ++ bool "Atheros AR71xx built-in ethernet driver debugfs support" ++ depends on DEBUG_FS ++ default n ++ help ++ Say Y, if you need access to various statistics provided by ++ the ag71xx driver. ++ ++config AG71XX_AR8216_SUPPORT ++ bool "special support for the Atheros AR8216 switch" ++ default n ++ default y if AR71XX_MACH_WNR2000 || AR71XX_MACH_MZK_W04NU ++ help ++ Say 'y' here if you want to enable special support for the ++ Atheros AR8216 switch found on some boards. ++ ++endif +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Makefile linux-2.6.39/drivers/net/ag71xx/Makefile +--- linux-2.6.39.orig/drivers/net/ag71xx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/Makefile 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,15 @@ ++# ++# Makefile for the Atheros AR71xx built-in ethernet macs ++# ++ ++ag71xx-y += ag71xx_main.o ++ag71xx-y += ag71xx_ethtool.o ++ag71xx-y += ag71xx_phy.o ++ag71xx-y += ag71xx_mdio.o ++ag71xx-y += ag71xx_ar7240.o ++ ++ag71xx-$(CONFIG_AG71XX_DEBUG_FS) += ag71xx_debugfs.o ++ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o ++ ++obj-$(CONFIG_AG71XX) += ag71xx.o ++ +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h linux-2.6.39/drivers/net/ag71xx/ag71xx.h +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx.h 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,518 @@ +/* -+ * NAND flash driver for the MikroTik RouterBoard 4xx series ++ * Atheros AR71xx built-in ethernet mac driver + * -+ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * -+ * This file was based on the driver for Linux 2.6.22 published by -+ * MikroTik for their RouterBoard 4xx series devices. ++ * Based on Atheros' AG7100 driver + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + ++#ifndef __AG71XX_H ++#define __AG71XX_H ++ ++#include ++#include ++#include +#include -+#include -+#include -+#include ++#include ++#include ++#include ++#include +#include -+#include -+#include -+#include -+#include -+ -+#include -+#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+#define DRV_NAME "rb4xx-nand" -+#define DRV_VERSION "0.2.0" -+#define DRV_DESC "NAND flash driver for RouterBoard 4xx series" ++#include + -+#define RB4XX_NAND_GPIO_READY 5 -+#define RB4XX_NAND_GPIO_ALE 37 -+#define RB4XX_NAND_GPIO_CLE 38 -+#define RB4XX_NAND_GPIO_NCE 39 ++#include ++#include + -+struct rb4xx_nand_info { -+ struct nand_chip chip; -+ struct mtd_info mtd; -+}; ++#define AG71XX_DRV_NAME "ag71xx" ++#define AG71XX_DRV_VERSION "0.5.35" + -+/* -+ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader -+ * will not be able to find the kernel that we load. -+ */ -+static struct nand_ecclayout rb4xx_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; ++#define AG71XX_NAPI_WEIGHT 64 ++#define AG71XX_OOM_REFILL (1 + HZ/10) + -+static struct mtd_partition rb4xx_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (6 * 1024 * 1024) - (256 * 1024), -+ }, -+ { -+ .name = "rootfs", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; ++#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE) ++#define AG71XX_INT_TX (AG71XX_INT_TX_PS) ++#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF) + -+static int rb4xx_nand_dev_ready(struct mtd_info *mtd) -+{ -+ return gpio_get_value_cansleep(RB4XX_NAND_GPIO_READY); -+} ++#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX) ++#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL) + -+static void rb4xx_nand_write_cmd(unsigned char cmd) -+{ -+ unsigned char data = cmd; -+ int err; ++#define AG71XX_TX_MTU_LEN 1540 ++#define AG71XX_RX_PKT_RESERVE 64 ++#define AG71XX_RX_PKT_SIZE \ ++ (AG71XX_RX_PKT_RESERVE + ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) + -+ err = rb4xx_cpld_write(&data, 1); -+ if (err) -+ pr_err("rb4xx_nand: write cmd failed, err=%d\n", err); -+} ++#define AG71XX_TX_RING_SIZE_DEFAULT 64 ++#define AG71XX_RX_RING_SIZE_DEFAULT 128 + -+static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ gpio_set_value_cansleep(RB4XX_NAND_GPIO_CLE, -+ (ctrl & NAND_CLE) ? 1 : 0); -+ gpio_set_value_cansleep(RB4XX_NAND_GPIO_ALE, -+ (ctrl & NAND_ALE) ? 1 : 0); -+ gpio_set_value_cansleep(RB4XX_NAND_GPIO_NCE, -+ (ctrl & NAND_NCE) ? 0 : 1); -+ } ++#define AG71XX_TX_RING_SIZE_MAX 256 ++#define AG71XX_RX_RING_SIZE_MAX 256 + -+ if (cmd != NAND_CMD_NONE) -+ rb4xx_nand_write_cmd(cmd); -+} ++#ifdef CONFIG_AG71XX_DEBUG ++#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args) ++#else ++#define DBG(fmt, args...) do {} while (0) ++#endif + -+static unsigned char rb4xx_nand_read_byte(struct mtd_info *mtd) -+{ -+ unsigned char data = 0; -+ int err; ++#define ag71xx_assert(_cond) \ ++do { \ ++ if (_cond) \ ++ break; \ ++ printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \ ++ BUG(); \ ++} while (0) + -+ err = rb4xx_cpld_read(&data, NULL, 1); -+ if (err) { -+ pr_err("rb4xx_nand: read data failed, err=%d\n", err); -+ data = 0xff; -+ } -+ -+ return data; -+} -+ -+static void rb4xx_nand_write_buf(struct mtd_info *mtd, const unsigned char *buf, -+ int len) -+{ -+ int err; ++struct ag71xx_desc { ++ u32 data; ++ u32 ctrl; ++#define DESC_EMPTY BIT(31) ++#define DESC_MORE BIT(24) ++#define DESC_PKTLEN_M 0xfff ++ u32 next; ++ u32 pad; ++} __attribute__((aligned(4))); + -+ err = rb4xx_cpld_write(buf, len); -+ if (err) -+ pr_err("rb4xx_nand: write buf failed, err=%d\n", err); -+} ++struct ag71xx_buf { ++ struct sk_buff *skb; ++ struct ag71xx_desc *desc; ++ dma_addr_t dma_addr; ++ unsigned long timestamp; ++}; + -+static void rb4xx_nand_read_buf(struct mtd_info *mtd, unsigned char *buf, -+ int len) -+{ -+ int err; ++struct ag71xx_ring { ++ struct ag71xx_buf *buf; ++ u8 *descs_cpu; ++ dma_addr_t descs_dma; ++ unsigned int desc_size; ++ unsigned int curr; ++ unsigned int dirty; ++ unsigned int size; ++}; + -+ err = rb4xx_cpld_read(buf, NULL, len); -+ if (err) -+ pr_err("rb4xx_nand: read buf failed, err=%d\n", err); -+} ++struct ag71xx_mdio { ++ struct mii_bus *mii_bus; ++ int mii_irq[PHY_MAX_ADDR]; ++ void __iomem *mdio_base; ++ struct ag71xx_mdio_platform_data *pdata; ++}; + -+static int __init rb4xx_nand_probe(struct platform_device *pdev) -+{ -+ struct rb4xx_nand_info *info; -+ int ret; ++struct ag71xx_int_stats { ++ unsigned long rx_pr; ++ unsigned long rx_be; ++ unsigned long rx_of; ++ unsigned long tx_ps; ++ unsigned long tx_be; ++ unsigned long tx_ur; ++ unsigned long total; ++}; + -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); ++struct ag71xx_napi_stats { ++ unsigned long napi_calls; ++ unsigned long rx_count; ++ unsigned long rx_packets; ++ unsigned long rx_packets_max; ++ unsigned long tx_count; ++ unsigned long tx_packets; ++ unsigned long tx_packets_max; + -+ ret = gpio_request(RB4XX_NAND_GPIO_READY, "NAND RDY"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_READY); -+ goto err; -+ } ++ unsigned long rx[AG71XX_NAPI_WEIGHT + 1]; ++ unsigned long tx[AG71XX_NAPI_WEIGHT + 1]; ++}; + -+ ret = gpio_direction_input(RB4XX_NAND_GPIO_READY); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set input mode on gpio %d\n", -+ RB4XX_NAND_GPIO_READY); -+ goto err_free_gpio_ready; -+ } ++struct ag71xx_debug { ++ struct dentry *debugfs_dir; + -+ ret = gpio_request(RB4XX_NAND_GPIO_ALE, "NAND ALE"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_ALE); -+ goto err_free_gpio_ready; -+ } ++ struct ag71xx_int_stats int_stats; ++ struct ag71xx_napi_stats napi_stats; ++}; + -+ ret = gpio_direction_output(RB4XX_NAND_GPIO_ALE, 0); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", -+ RB4XX_NAND_GPIO_ALE); -+ goto err_free_gpio_ale; -+ } ++struct ag71xx { ++ void __iomem *mac_base; ++ void __iomem *mii_ctrl; + -+ ret = gpio_request(RB4XX_NAND_GPIO_CLE, "NAND CLE"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_CLE); -+ goto err_free_gpio_ale; -+ } ++ spinlock_t lock; ++ struct platform_device *pdev; ++ struct net_device *dev; ++ struct napi_struct napi; ++ u32 msg_enable; + -+ ret = gpio_direction_output(RB4XX_NAND_GPIO_CLE, 0); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", -+ RB4XX_NAND_GPIO_CLE); -+ goto err_free_gpio_cle; -+ } ++ struct ag71xx_desc *stop_desc; ++ dma_addr_t stop_desc_dma; + -+ ret = gpio_request(RB4XX_NAND_GPIO_NCE, "NAND NCE"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_NCE); -+ goto err_free_gpio_cle; -+ } ++ struct ag71xx_ring rx_ring; ++ struct ag71xx_ring tx_ring; + -+ ret = gpio_direction_output(RB4XX_NAND_GPIO_NCE, 1); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", -+ RB4XX_NAND_GPIO_ALE); -+ goto err_free_gpio_nce; -+ } ++ struct mii_bus *mii_bus; ++ struct phy_device *phy_dev; ++ void *phy_priv; + -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) { -+ dev_err(&pdev->dev, "rb4xx-nand: no memory for private data\n"); -+ ret = -ENOMEM; -+ goto err_free_gpio_nce; -+ } ++ unsigned int link; ++ unsigned int speed; ++ int duplex; + -+ info->chip.priv = &info; -+ info->mtd.priv = &info->chip; -+ info->mtd.owner = THIS_MODULE; ++ struct work_struct restart_work; ++ struct delayed_work link_work; ++ struct timer_list oom_timer; + -+ info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl; -+ info->chip.dev_ready = rb4xx_nand_dev_ready; -+ info->chip.read_byte = rb4xx_nand_read_byte; -+ info->chip.write_buf = rb4xx_nand_write_buf; -+ info->chip.read_buf = rb4xx_nand_read_buf; -+#if 0 -+ info->chip.verify_buf = rb4xx_nand_verify_buf; ++#ifdef CONFIG_AG71XX_DEBUG_FS ++ struct ag71xx_debug debug; +#endif ++}; + -+ info->chip.chip_delay = 25; -+ info->chip.ecc.mode = NAND_ECC_SOFT; -+ info->chip.options |= NAND_NO_AUTOINCR; -+ -+ platform_set_drvdata(pdev, info); -+ -+ ret = nand_scan_ident(&info->mtd, 1, NULL); -+ if (ret) { -+ ret = -ENXIO; -+ goto err_free_info; -+ } -+ -+ if (info->mtd.writesize == 512) -+ info->chip.ecc.layout = &rb4xx_nand_ecclayout; -+ -+ ret = nand_scan_tail(&info->mtd); -+ if (ret) { -+ return -ENXIO; -+ goto err_set_drvdata; -+ } ++extern struct ethtool_ops ag71xx_ethtool_ops; ++void ag71xx_link_adjust(struct ag71xx *ag); + -+#ifdef CONFIG_MTD_PARTITIONS -+ ret = add_mtd_partitions(&info->mtd, rb4xx_nand_partitions, -+ ARRAY_SIZE(rb4xx_nand_partitions)); -+#else -+ ret = add_mtd_device(&info->mtd); -+#endif -+ if (ret) -+ goto err_release_nand; ++int ag71xx_mdio_driver_init(void) __init; ++void ag71xx_mdio_driver_exit(void); + -+ return 0; ++int ag71xx_phy_connect(struct ag71xx *ag); ++void ag71xx_phy_disconnect(struct ag71xx *ag); ++void ag71xx_phy_start(struct ag71xx *ag); ++void ag71xx_phy_stop(struct ag71xx *ag); + -+err_release_nand: -+ nand_release(&info->mtd); -+err_set_drvdata: -+ platform_set_drvdata(pdev, NULL); -+err_free_info: -+ kfree(info); -+err_free_gpio_nce: -+ gpio_free(RB4XX_NAND_GPIO_NCE); -+err_free_gpio_cle: -+ gpio_free(RB4XX_NAND_GPIO_CLE); -+err_free_gpio_ale: -+ gpio_free(RB4XX_NAND_GPIO_ALE); -+err_free_gpio_ready: -+ gpio_free(RB4XX_NAND_GPIO_READY); -+err: -+ return ret; ++static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag) ++{ ++ return ag->pdev->dev.platform_data; +} + -+static int __devexit rb4xx_nand_remove(struct platform_device *pdev) ++static inline int ag71xx_desc_empty(struct ag71xx_desc *desc) +{ -+ struct rb4xx_nand_info *info = platform_get_drvdata(pdev); -+ -+ nand_release(&info->mtd); -+ platform_set_drvdata(pdev, NULL); -+ kfree(info); -+ gpio_free(RB4XX_NAND_GPIO_NCE); -+ gpio_free(RB4XX_NAND_GPIO_CLE); -+ gpio_free(RB4XX_NAND_GPIO_ALE); -+ gpio_free(RB4XX_NAND_GPIO_READY); -+ -+ return 0; ++ return (desc->ctrl & DESC_EMPTY) != 0; +} + -+static struct platform_driver rb4xx_nand_driver = { -+ .probe = rb4xx_nand_probe, -+ .remove = __devexit_p(rb4xx_nand_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init rb4xx_nand_init(void) ++static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc) +{ -+ return platform_driver_register(&rb4xx_nand_driver); ++ return desc->ctrl & DESC_PKTLEN_M; +} + -+static void __exit rb4xx_nand_exit(void) -+{ -+ platform_driver_unregister(&rb4xx_nand_driver); -+} ++/* Register offsets */ ++#define AG71XX_REG_MAC_CFG1 0x0000 ++#define AG71XX_REG_MAC_CFG2 0x0004 ++#define AG71XX_REG_MAC_IPG 0x0008 ++#define AG71XX_REG_MAC_HDX 0x000c ++#define AG71XX_REG_MAC_MFL 0x0010 ++#define AG71XX_REG_MII_CFG 0x0020 ++#define AG71XX_REG_MII_CMD 0x0024 ++#define AG71XX_REG_MII_ADDR 0x0028 ++#define AG71XX_REG_MII_CTRL 0x002c ++#define AG71XX_REG_MII_STATUS 0x0030 ++#define AG71XX_REG_MII_IND 0x0034 ++#define AG71XX_REG_MAC_IFCTL 0x0038 ++#define AG71XX_REG_MAC_ADDR1 0x0040 ++#define AG71XX_REG_MAC_ADDR2 0x0044 ++#define AG71XX_REG_FIFO_CFG0 0x0048 ++#define AG71XX_REG_FIFO_CFG1 0x004c ++#define AG71XX_REG_FIFO_CFG2 0x0050 ++#define AG71XX_REG_FIFO_CFG3 0x0054 ++#define AG71XX_REG_FIFO_CFG4 0x0058 ++#define AG71XX_REG_FIFO_CFG5 0x005c ++#define AG71XX_REG_FIFO_RAM0 0x0060 ++#define AG71XX_REG_FIFO_RAM1 0x0064 ++#define AG71XX_REG_FIFO_RAM2 0x0068 ++#define AG71XX_REG_FIFO_RAM3 0x006c ++#define AG71XX_REG_FIFO_RAM4 0x0070 ++#define AG71XX_REG_FIFO_RAM5 0x0074 ++#define AG71XX_REG_FIFO_RAM6 0x0078 ++#define AG71XX_REG_FIFO_RAM7 0x007c + -+module_init(rb4xx_nand_init); -+module_exit(rb4xx_nand_exit); ++#define AG71XX_REG_TX_CTRL 0x0180 ++#define AG71XX_REG_TX_DESC 0x0184 ++#define AG71XX_REG_TX_STATUS 0x0188 ++#define AG71XX_REG_RX_CTRL 0x018c ++#define AG71XX_REG_RX_DESC 0x0190 ++#define AG71XX_REG_RX_STATUS 0x0194 ++#define AG71XX_REG_INT_ENABLE 0x0198 ++#define AG71XX_REG_INT_STATUS 0x019c + -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_AUTHOR("Imre Kaloz "); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c linux-2.6.39/drivers/mtd/nand/rb750_nand.c ---- linux-2.6.39.orig/drivers/mtd/nand/rb750_nand.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/mtd/nand/rb750_nand.c 2011-04-27 12:19:22.177661504 +0200 -@@ -0,0 +1,361 @@ -+/* -+ * NAND flash driver for the MikroTik RouterBOARD 750 -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++#define AG71XX_REG_FIFO_DEPTH 0x01a8 ++#define AG71XX_REG_RX_SM 0x01b0 ++#define AG71XX_REG_TX_SM 0x01b4 + -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#define MAC_CFG1_TXE BIT(0) /* Tx Enable */ ++#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */ ++#define MAC_CFG1_RXE BIT(2) /* Rx Enable */ ++#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */ ++#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */ ++#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */ ++#define MAC_CFG1_LB BIT(8) /* Loopback mode */ ++#define MAC_CFG1_SR BIT(31) /* Soft Reset */ + -+#include -+#include ++#define MAC_CFG2_FDX BIT(0) ++#define MAC_CFG2_CRC_EN BIT(1) ++#define MAC_CFG2_PAD_CRC_EN BIT(2) ++#define MAC_CFG2_LEN_CHECK BIT(4) ++#define MAC_CFG2_HUGE_FRAME_EN BIT(5) ++#define MAC_CFG2_IF_1000 BIT(9) ++#define MAC_CFG2_IF_10_100 BIT(8) + -+#define DRV_NAME "rb750-nand" -+#define DRV_VERSION "0.1.0" -+#define DRV_DESC "NAND flash driver for the RouterBOARD 750" ++#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */ ++#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */ ++#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */ ++#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */ ++#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */ ++#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \ ++ | FIFO_CFG0_TXS | FIFO_CFG0_TXF) + -+#define RB750_NAND_IO0 BIT(RB750_GPIO_NAND_IO0) -+#define RB750_NAND_ALE BIT(RB750_GPIO_NAND_ALE) -+#define RB750_NAND_CLE BIT(RB750_GPIO_NAND_CLE) -+#define RB750_NAND_NRE BIT(RB750_GPIO_NAND_NRE) -+#define RB750_NAND_NWE BIT(RB750_GPIO_NAND_NWE) -+#define RB750_NAND_RDY BIT(RB750_GPIO_NAND_RDY) -+#define RB750_NAND_NCE BIT(RB750_GPIO_NAND_NCE) ++#define FIFO_CFG0_ENABLE_SHIFT 8 + -+#define RB750_NAND_DATA_SHIFT 1 -+#define RB750_NAND_DATA_BITS (0xff << RB750_NAND_DATA_SHIFT) -+#define RB750_NAND_INPUT_BITS (RB750_NAND_DATA_BITS | RB750_NAND_RDY) -+#define RB750_NAND_OUTPUT_BITS (RB750_NAND_ALE | RB750_NAND_CLE | \ -+ RB750_NAND_NRE | RB750_NAND_NWE | \ -+ RB750_NAND_NCE) ++#define FIFO_CFG4_DE BIT(0) /* Drop Event */ ++#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */ ++#define FIFO_CFG4_FC BIT(2) /* False Carrier */ ++#define FIFO_CFG4_CE BIT(3) /* Code Error */ ++#define FIFO_CFG4_CR BIT(4) /* CRC error */ ++#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */ ++#define FIFO_CFG4_LO BIT(6) /* Length out of range */ ++#define FIFO_CFG4_OK BIT(7) /* Packet is OK */ ++#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */ ++#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */ ++#define FIFO_CFG4_DR BIT(10) /* Dribble */ ++#define FIFO_CFG4_LE BIT(11) /* Long Event */ ++#define FIFO_CFG4_CF BIT(12) /* Control Frame */ ++#define FIFO_CFG4_PF BIT(13) /* Pause Frame */ ++#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */ ++#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */ ++#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */ ++#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */ + -+struct rb750_nand_info { -+ struct nand_chip chip; -+ struct mtd_info mtd; -+}; ++#define FIFO_CFG5_DE BIT(0) /* Drop Event */ ++#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */ ++#define FIFO_CFG5_FC BIT(2) /* False Carrier */ ++#define FIFO_CFG5_CE BIT(3) /* Code Error */ ++#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */ ++#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */ ++#define FIFO_CFG5_OK BIT(6) /* Packet is OK */ ++#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */ ++#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */ ++#define FIFO_CFG5_DR BIT(9) /* Dribble */ ++#define FIFO_CFG5_CF BIT(10) /* Control Frame */ ++#define FIFO_CFG5_PF BIT(11) /* Pause Frame */ ++#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */ ++#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */ ++#define FIFO_CFG5_LE BIT(14) /* Long Event */ ++#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */ ++#define FIFO_CFG5_16 BIT(16) /* unknown */ ++#define FIFO_CFG5_17 BIT(17) /* unknown */ ++#define FIFO_CFG5_SF BIT(18) /* Short Frame */ ++#define FIFO_CFG5_BM BIT(19) /* Byte Mode */ + -+/* -+ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader -+ * will not be able to find the kernel that we load. -+ */ -+static struct nand_ecclayout rb750_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; ++#define AG71XX_INT_TX_PS BIT(0) ++#define AG71XX_INT_TX_UR BIT(1) ++#define AG71XX_INT_TX_BE BIT(3) ++#define AG71XX_INT_RX_PR BIT(4) ++#define AG71XX_INT_RX_OF BIT(6) ++#define AG71XX_INT_RX_BE BIT(7) + -+static struct mtd_partition rb750_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, { -+ .name = "rootfs", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; ++#define MAC_IFCTL_SPEED BIT(16) + -+static void rb750_nand_write(const u8 *buf, unsigned len) -+{ -+ void __iomem *base = ar71xx_gpio_base; -+ u32 out; -+ unsigned i; ++#define MII_CFG_CLK_DIV_4 0 ++#define MII_CFG_CLK_DIV_6 2 ++#define MII_CFG_CLK_DIV_8 3 ++#define MII_CFG_CLK_DIV_10 4 ++#define MII_CFG_CLK_DIV_14 5 ++#define MII_CFG_CLK_DIV_20 6 ++#define MII_CFG_CLK_DIV_28 7 ++#define MII_CFG_RESET BIT(31) + -+ /* set data lines to output mode */ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_DATA_BITS, -+ base + GPIO_REG_OE); ++#define MII_CMD_WRITE 0x0 ++#define MII_CMD_READ 0x1 ++#define MII_ADDR_SHIFT 8 ++#define MII_IND_BUSY BIT(0) ++#define MII_IND_INVALID BIT(2) + -+ out = __raw_readl(base + GPIO_REG_OUT); -+ out &= ~(RB750_NAND_DATA_BITS | RB750_NAND_NWE); -+ for (i = 0; i != len; i++) { -+ u32 data; ++#define TX_CTRL_TXE BIT(0) /* Tx Enable */ + -+ data = buf[i]; -+ data <<= RB750_NAND_DATA_SHIFT; -+ data |= out; -+ __raw_writel(data, base + GPIO_REG_OUT); ++#define TX_STATUS_PS BIT(0) /* Packet Sent */ ++#define TX_STATUS_UR BIT(1) /* Tx Underrun */ ++#define TX_STATUS_BE BIT(3) /* Bus Error */ + -+ __raw_writel(data | RB750_NAND_NWE, base + GPIO_REG_OUT); -+ /* flush write */ -+ __raw_readl(base + GPIO_REG_OUT); -+ } ++#define RX_CTRL_RXE BIT(0) /* Rx Enable */ + -+ /* set data lines to input mode */ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~RB750_NAND_DATA_BITS, -+ base + GPIO_REG_OE); -+ /* flush write */ -+ __raw_readl(base + GPIO_REG_OE); -+} ++#define RX_STATUS_PR BIT(0) /* Packet Received */ ++#define RX_STATUS_OF BIT(2) /* Rx Overflow */ ++#define RX_STATUS_BE BIT(3) /* Bus Error */ + -+static int rb750_nand_read_verify(u8 *read_buf, unsigned len, -+ const u8 *verify_buf) ++#define MII_CTRL_IF_MASK 3 ++#define MII_CTRL_SPEED_SHIFT 4 ++#define MII_CTRL_SPEED_MASK 3 ++#define MII_CTRL_SPEED_10 0 ++#define MII_CTRL_SPEED_100 1 ++#define MII_CTRL_SPEED_1000 2 ++ ++static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg) +{ -+ void __iomem *base = ar71xx_gpio_base; -+ unsigned i; ++ switch (reg) { ++ case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: ++ case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: ++ case AG71XX_REG_MII_CFG: ++ break; + -+ for (i = 0; i < len; i++) { -+ u8 data; ++ default: ++ BUG(); ++ } ++} + -+ /* activate RE line */ -+ __raw_writel(RB750_NAND_NRE, base + GPIO_REG_CLEAR); -+ /* flush write */ -+ __raw_readl(base + GPIO_REG_CLEAR); -+ -+ /* read input lines */ -+ data = __raw_readl(base + GPIO_REG_IN) >> RB750_NAND_DATA_SHIFT; ++static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) ++{ ++ ag71xx_check_reg_offset(ag, reg); + -+ /* deactivate RE line */ -+ __raw_writel(RB750_NAND_NRE, base + GPIO_REG_SET); ++ __raw_writel(value, ag->mac_base + reg); ++ /* flush write */ ++ (void) __raw_readl(ag->mac_base + reg); ++} + -+ if (read_buf) -+ read_buf[i] = data; -+ else if (verify_buf && verify_buf[i] != data) -+ return -EFAULT; -+ } ++static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) ++{ ++ ag71xx_check_reg_offset(ag, reg); + -+ return 0; ++ return __raw_readl(ag->mac_base + reg); +} + -+static void rb750_nand_select_chip(struct mtd_info *mtd, int chip) ++static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) +{ -+ void __iomem *base = ar71xx_gpio_base; -+ u32 func; -+ -+ func = __raw_readl(base + GPIO_REG_FUNC); -+ if (chip >= 0) { -+ /* disable latch */ -+ rb750_latch_change(RB750_LVC573_LE, 0); ++ void __iomem *r; + -+ /* disable alternate functions */ -+ ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, -+ AR724X_GPIO_FUNC_SPI_EN); ++ ag71xx_check_reg_offset(ag, reg); + -+ /* set input mode for data lines */ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) & -+ ~RB750_NAND_INPUT_BITS, -+ base + GPIO_REG_OE); ++ r = ag->mac_base + reg; ++ __raw_writel(__raw_readl(r) | mask, r); ++ /* flush write */ ++ (void)__raw_readl(r); ++} + -+ /* deactivate RE and WE lines */ -+ __raw_writel(RB750_NAND_NRE | RB750_NAND_NWE, -+ base + GPIO_REG_SET); -+ /* flush write */ -+ (void) __raw_readl(base + GPIO_REG_SET); ++static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) ++{ ++ void __iomem *r; + -+ /* activate CE line */ -+ __raw_writel(RB750_NAND_NCE, base + GPIO_REG_CLEAR); -+ } else { -+ /* deactivate CE line */ -+ __raw_writel(RB750_NAND_NCE, base + GPIO_REG_SET); -+ /* flush write */ -+ (void) __raw_readl(base + GPIO_REG_SET); ++ ag71xx_check_reg_offset(ag, reg); + -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) | -+ RB750_NAND_IO0 | RB750_NAND_RDY, -+ base + GPIO_REG_OE); ++ r = ag->mac_base + reg; ++ __raw_writel(__raw_readl(r) & ~mask, r); ++ /* flush write */ ++ (void) __raw_readl(r); ++} + -+ /* restore alternate functions */ -+ ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN, -+ AR724X_GPIO_FUNC_JTAG_DISABLE); ++static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) ++{ ++ ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints); ++} + -+ /* enable latch */ -+ rb750_latch_change(0, RB750_LVC573_LE); -+ } ++static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints) ++{ ++ ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints); +} + -+static int rb750_nand_dev_ready(struct mtd_info *mtd) ++static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value) +{ -+ void __iomem *base = ar71xx_gpio_base; ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + -+ return !!(__raw_readl(base + GPIO_REG_IN) & RB750_NAND_RDY); ++ if (pdata->is_ar724x) ++ return; ++ ++ __raw_writel(value, ag->mii_ctrl); ++ ++ /* flush write */ ++ __raw_readl(ag->mii_ctrl); +} + -+static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) ++static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag) +{ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ void __iomem *base = ar71xx_gpio_base; -+ u32 t; ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + -+ t = __raw_readl(base + GPIO_REG_OUT); ++ if (pdata->is_ar724x) ++ return 0xffffffff; + -+ t &= ~(RB750_NAND_CLE | RB750_NAND_ALE); -+ t |= (ctrl & NAND_CLE) ? RB750_NAND_CLE : 0; -+ t |= (ctrl & NAND_ALE) ? RB750_NAND_ALE : 0; ++ return __raw_readl(ag->mii_ctrl); ++} + -+ __raw_writel(t, base + GPIO_REG_OUT); -+ /* flush write */ -+ __raw_readl(base + GPIO_REG_OUT); -+ } ++static inline void ag71xx_mii_ctrl_set_if(struct ag71xx *ag, ++ unsigned int mii_if) ++{ ++ u32 t; + -+ if (cmd != NAND_CMD_NONE) { -+ u8 t = cmd; -+ rb750_nand_write(&t, 1); -+ } ++ t = ag71xx_mii_ctrl_rr(ag); ++ t &= ~(MII_CTRL_IF_MASK); ++ t |= (mii_if & MII_CTRL_IF_MASK); ++ ag71xx_mii_ctrl_wr(ag, t); +} + -+static u8 rb750_nand_read_byte(struct mtd_info *mtd) ++static inline void ag71xx_mii_ctrl_set_speed(struct ag71xx *ag, ++ unsigned int speed) +{ -+ u8 data = 0; -+ rb750_nand_read_verify(&data, 1, NULL); -+ return data; ++ u32 t; ++ ++ t = ag71xx_mii_ctrl_rr(ag); ++ t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT); ++ t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT; ++ ag71xx_mii_ctrl_wr(ag, t); +} + -+static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) ++#ifdef CONFIG_AG71XX_AR8216_SUPPORT ++void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); ++int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, ++ int pktlen); ++static inline int ag71xx_has_ar8216(struct ag71xx *ag) +{ -+ rb750_nand_read_verify(buf, len, NULL); ++ return ag71xx_get_pdata(ag)->has_ar8216; +} -+ -+static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) ++#else ++static inline void ag71xx_add_ar8216_header(struct ag71xx *ag, ++ struct sk_buff *skb) +{ -+ rb750_nand_write(buf, len); +} + -+static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len) ++static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag, ++ struct sk_buff *skb, ++ int pktlen) +{ -+ return rb750_nand_read_verify(NULL, len, buf); ++ return 0; +} -+ -+static void __init rb750_nand_gpio_init(void) ++static inline int ag71xx_has_ar8216(struct ag71xx *ag) +{ -+ void __iomem *base = ar71xx_gpio_base; -+ u32 out; -+ -+ out = __raw_readl(base + GPIO_REG_OUT); ++ return 0; ++} ++#endif + -+ /* setup output levels */ -+ __raw_writel(RB750_NAND_NCE | RB750_NAND_NRE | RB750_NAND_NWE, -+ base + GPIO_REG_SET); ++#ifdef CONFIG_AG71XX_DEBUG_FS ++int ag71xx_debugfs_root_init(void); ++void ag71xx_debugfs_root_exit(void); ++int ag71xx_debugfs_init(struct ag71xx *ag); ++void ag71xx_debugfs_exit(struct ag71xx *ag); ++void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status); ++void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx); ++#else ++static inline int ag71xx_debugfs_root_init(void) { return 0; } ++static inline void ag71xx_debugfs_root_exit(void) {} ++static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; } ++static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {} ++static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, ++ u32 status) {} ++static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, ++ int rx, int tx) {} ++#endif /* CONFIG_AG71XX_DEBUG_FS */ + -+ __raw_writel(RB750_NAND_ALE | RB750_NAND_CLE, -+ base + GPIO_REG_CLEAR); ++void ag71xx_ar7240_start(struct ag71xx *ag); ++void ag71xx_ar7240_stop(struct ag71xx *ag); ++int ag71xx_ar7240_init(struct ag71xx *ag); ++void ag71xx_ar7240_cleanup(struct ag71xx *ag); + -+ /* setup input lines */ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) & ~(RB750_NAND_INPUT_BITS), -+ base + GPIO_REG_OE); ++int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg); ++void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val); + -+ /* setup output lines */ -+ __raw_writel(__raw_readl(base + GPIO_REG_OE) | RB750_NAND_OUTPUT_BITS, -+ base + GPIO_REG_OE); ++u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, ++ unsigned reg_addr); ++int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, ++ unsigned reg_addr, u16 reg_val); + -+ rb750_latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0); -+} ++#endif /* _AG71XX_H */ +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar7240.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ar7240.c +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar7240.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ar7240.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,913 @@ ++/* ++ * Driver for the built-in ethernet switch of the Atheros AR7240 SoC ++ * Copyright (c) 2010 Gabor Juhos ++ * Copyright (c) 2010 Felix Fietkau ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ + -+static int __init rb750_nand_probe(struct platform_device *pdev) -+{ -+ struct rb750_nand_info *info; -+ int ret; ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "ag71xx.h" + -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); ++#define BITM(_count) (BIT(_count) - 1) ++#define BITS(_shift, _count) (BITM(_count) << _shift) + -+ rb750_nand_gpio_init(); ++#define AR7240_REG_MASK_CTRL 0x00 ++#define AR7240_MASK_CTRL_REVISION_M BITM(8) ++#define AR7240_MASK_CTRL_VERSION_M BITM(8) ++#define AR7240_MASK_CTRL_VERSION_S 8 ++#define AR7240_MASK_CTRL_SOFT_RESET BIT(31) + -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) -+ return -ENOMEM; ++#define AR7240_REG_MAC_ADDR0 0x20 ++#define AR7240_REG_MAC_ADDR1 0x24 + -+ info->chip.priv = &info; -+ info->mtd.priv = &info->chip; -+ info->mtd.owner = THIS_MODULE; ++#define AR7240_REG_FLOOD_MASK 0x2c ++#define AR7240_FLOOD_MASK_BROAD_TO_CPU BIT(26) + -+ info->chip.select_chip = rb750_nand_select_chip; -+ info->chip.cmd_ctrl = rb750_nand_cmd_ctrl; -+ info->chip.dev_ready = rb750_nand_dev_ready; -+ info->chip.read_byte = rb750_nand_read_byte; -+ info->chip.write_buf = rb750_nand_write_buf; -+ info->chip.read_buf = rb750_nand_read_buf; -+ info->chip.verify_buf = rb750_nand_verify_buf; ++#define AR7240_REG_GLOBAL_CTRL 0x30 ++#define AR7240_GLOBAL_CTRL_MTU_M BITM(12) + -+ info->chip.chip_delay = 25; -+ info->chip.ecc.mode = NAND_ECC_SOFT; -+ info->chip.options |= NAND_NO_AUTOINCR; ++#define AR7240_REG_VTU 0x0040 ++#define AR7240_VTU_OP BITM(3) ++#define AR7240_VTU_OP_NOOP 0x0 ++#define AR7240_VTU_OP_FLUSH 0x1 ++#define AR7240_VTU_OP_LOAD 0x2 ++#define AR7240_VTU_OP_PURGE 0x3 ++#define AR7240_VTU_OP_REMOVE_PORT 0x4 ++#define AR7240_VTU_ACTIVE BIT(3) ++#define AR7240_VTU_FULL BIT(4) ++#define AR7240_VTU_PORT BITS(8, 4) ++#define AR7240_VTU_PORT_S 8 ++#define AR7240_VTU_VID BITS(16, 12) ++#define AR7240_VTU_VID_S 16 ++#define AR7240_VTU_PRIO BITS(28, 3) ++#define AR7240_VTU_PRIO_S 28 ++#define AR7240_VTU_PRIO_EN BIT(31) + -+ platform_set_drvdata(pdev, info); ++#define AR7240_REG_VTU_DATA 0x0044 ++#define AR7240_VTUDATA_MEMBER BITS(0, 10) ++#define AR7240_VTUDATA_VALID BIT(11) + -+ ret = nand_scan_ident(&info->mtd, 1); -+ if (ret) { -+ ret = -ENXIO; -+ goto err_free_info; -+ } ++#define AR7240_REG_ATU 0x50 ++#define AR7240_ATU_FLUSH_ALL 0x1 + -+ if (info->mtd.writesize == 512) -+ info->chip.ecc.layout = &rb750_nand_ecclayout; ++#define AR7240_REG_AT_CTRL 0x5c ++#define AR7240_AT_CTRL_AGE_TIME BITS(0, 15) ++#define AR7240_AT_CTRL_AGE_EN BIT(17) ++#define AR7240_AT_CTRL_LEARN_CHANGE BIT(18) ++#define AR7240_AT_CTRL_ARP_EN BIT(20) + -+ ret = nand_scan_tail(&info->mtd); -+ if (ret) { -+ return -ENXIO; -+ goto err_set_drvdata; -+ } ++#define AR7240_REG_TAG_PRIORITY 0x70 + -+#ifdef CONFIG_MTD_PARTITIONS -+ ret = add_mtd_partitions(&info->mtd, rb750_nand_partitions, -+ ARRAY_SIZE(rb750_nand_partitions)); -+#else -+ ret = add_mtd_device(&info->mtd); -+#endif -+ if (ret) -+ goto err_release_nand; ++#define AR7240_REG_SERVICE_TAG 0x74 ++#define AR7240_SERVICE_TAG_M BITM(16) + -+ return 0; ++#define AR7240_REG_CPU_PORT 0x78 ++#define AR7240_MIRROR_PORT_S 4 ++#define AR7240_CPU_PORT_EN BIT(8) + -+err_release_nand: -+ nand_release(&info->mtd); -+err_set_drvdata: -+ platform_set_drvdata(pdev, NULL); -+err_free_info: -+ kfree(info); -+ return ret; -+} ++#define AR7240_REG_MIB_FUNCTION0 0x80 ++#define AR7240_MIB_TIMER_M BITM(16) ++#define AR7240_MIB_AT_HALF_EN BIT(16) ++#define AR7240_MIB_BUSY BIT(17) ++#define AR7240_MIB_FUNC_S 24 ++#define AR7240_MIB_FUNC_NO_OP 0x0 ++#define AR7240_MIB_FUNC_FLUSH 0x1 ++#define AR7240_MIB_FUNC_CAPTURE 0x3 + -+static int __devexit rb750_nand_remove(struct platform_device *pdev) -+{ -+ struct rb750_nand_info *info = platform_get_drvdata(pdev); ++#define AR7240_REG_MDIO_CTRL 0x98 ++#define AR7240_MDIO_CTRL_DATA_M BITM(16) ++#define AR7240_MDIO_CTRL_REG_ADDR_S 16 ++#define AR7240_MDIO_CTRL_PHY_ADDR_S 21 ++#define AR7240_MDIO_CTRL_CMD_WRITE 0 ++#define AR7240_MDIO_CTRL_CMD_READ BIT(27) ++#define AR7240_MDIO_CTRL_MASTER_EN BIT(30) ++#define AR7240_MDIO_CTRL_BUSY BIT(31) + -+ nand_release(&info->mtd); -+ platform_set_drvdata(pdev, NULL); -+ kfree(info); ++#define AR7240_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100) + -+ return 0; -+} ++#define AR7240_REG_PORT_STATUS(_port) (AR7240_REG_PORT_BASE((_port)) + 0x00) ++#define AR7240_PORT_STATUS_SPEED_M BITM(2) ++#define AR7240_PORT_STATUS_SPEED_10 0 ++#define AR7240_PORT_STATUS_SPEED_100 1 ++#define AR7240_PORT_STATUS_SPEED_1000 2 ++#define AR7240_PORT_STATUS_TXMAC BIT(2) ++#define AR7240_PORT_STATUS_RXMAC BIT(3) ++#define AR7240_PORT_STATUS_TXFLOW BIT(4) ++#define AR7240_PORT_STATUS_RXFLOW BIT(5) ++#define AR7240_PORT_STATUS_DUPLEX BIT(6) ++#define AR7240_PORT_STATUS_LINK_UP BIT(8) ++#define AR7240_PORT_STATUS_LINK_AUTO BIT(9) ++#define AR7240_PORT_STATUS_LINK_PAUSE BIT(10) + -+static struct platform_driver rb750_nand_driver = { -+ .probe = rb750_nand_probe, -+ .remove = __devexit_p(rb750_nand_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; ++#define AR7240_REG_PORT_CTRL(_port) (AR7240_REG_PORT_BASE((_port)) + 0x04) ++#define AR7240_PORT_CTRL_STATE_M BITM(3) ++#define AR7240_PORT_CTRL_STATE_DISABLED 0 ++#define AR7240_PORT_CTRL_STATE_BLOCK 1 ++#define AR7240_PORT_CTRL_STATE_LISTEN 2 ++#define AR7240_PORT_CTRL_STATE_LEARN 3 ++#define AR7240_PORT_CTRL_STATE_FORWARD 4 ++#define AR7240_PORT_CTRL_LEARN_LOCK BIT(7) ++#define AR7240_PORT_CTRL_VLAN_MODE_S 8 ++#define AR7240_PORT_CTRL_VLAN_MODE_KEEP 0 ++#define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1 ++#define AR7240_PORT_CTRL_VLAN_MODE_ADD 2 ++#define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3 ++#define AR7240_PORT_CTRL_IGMP_SNOOP BIT(10) ++#define AR7240_PORT_CTRL_HEADER BIT(11) ++#define AR7240_PORT_CTRL_MAC_LOOP BIT(12) ++#define AR7240_PORT_CTRL_SINGLE_VLAN BIT(13) ++#define AR7240_PORT_CTRL_LEARN BIT(14) ++#define AR7240_PORT_CTRL_DOUBLE_TAG BIT(15) ++#define AR7240_PORT_CTRL_MIRROR_TX BIT(16) ++#define AR7240_PORT_CTRL_MIRROR_RX BIT(17) + -+static int __init rb750_nand_init(void) -+{ -+ return platform_driver_register(&rb750_nand_driver); -+} ++#define AR7240_REG_PORT_VLAN(_port) (AR7240_REG_PORT_BASE((_port)) + 0x08) + -+static void __exit rb750_nand_exit(void) -+{ -+ platform_driver_unregister(&rb750_nand_driver); -+} ++#define AR7240_PORT_VLAN_DEFAULT_ID_S 0 ++#define AR7240_PORT_VLAN_DEST_PORTS_S 16 ++#define AR7240_PORT_VLAN_MODE_S 30 ++#define AR7240_PORT_VLAN_MODE_PORT_ONLY 0 ++#define AR7240_PORT_VLAN_MODE_PORT_FALLBACK 1 ++#define AR7240_PORT_VLAN_MODE_VLAN_ONLY 2 ++#define AR7240_PORT_VLAN_MODE_SECURE 3 + -+module_init(rb750_nand_init); -+module_exit(rb750_nand_exit); + -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c linux-2.6.39/drivers/mtd/wrt160nl_part.c ---- linux-2.6.39.orig/drivers/mtd/wrt160nl_part.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/mtd/wrt160nl_part.c 2011-08-06 09:32:37.138017083 +0200 -@@ -0,0 +1,190 @@ -+/* -+ * Copyright (C) 2009 Christian Daniel -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * 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. -+ * -+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ * TRX flash partition table. -+ * Based on ar7 map by Felix Fietkau -+ * -+ */ ++#define AR7240_REG_STATS_BASE(_port) (0x20000 + (_port) * 0x100) + -+#include -+#include -+#include ++#define AR7240_STATS_RXBROAD 0x00 ++#define AR7240_STATS_RXPAUSE 0x04 ++#define AR7240_STATS_RXMULTI 0x08 ++#define AR7240_STATS_RXFCSERR 0x0c ++#define AR7240_STATS_RXALIGNERR 0x10 ++#define AR7240_STATS_RXRUNT 0x14 ++#define AR7240_STATS_RXFRAGMENT 0x18 ++#define AR7240_STATS_RX64BYTE 0x1c ++#define AR7240_STATS_RX128BYTE 0x20 ++#define AR7240_STATS_RX256BYTE 0x24 ++#define AR7240_STATS_RX512BYTE 0x28 ++#define AR7240_STATS_RX1024BYTE 0x2c ++#define AR7240_STATS_RX1518BYTE 0x30 ++#define AR7240_STATS_RXMAXBYTE 0x34 ++#define AR7240_STATS_RXTOOLONG 0x38 ++#define AR7240_STATS_RXGOODBYTE 0x3c ++#define AR7240_STATS_RXBADBYTE 0x44 ++#define AR7240_STATS_RXOVERFLOW 0x4c ++#define AR7240_STATS_FILTERED 0x50 ++#define AR7240_STATS_TXBROAD 0x54 ++#define AR7240_STATS_TXPAUSE 0x58 ++#define AR7240_STATS_TXMULTI 0x5c ++#define AR7240_STATS_TXUNDERRUN 0x60 ++#define AR7240_STATS_TX64BYTE 0x64 ++#define AR7240_STATS_TX128BYTE 0x68 ++#define AR7240_STATS_TX256BYTE 0x6c ++#define AR7240_STATS_TX512BYTE 0x70 ++#define AR7240_STATS_TX1024BYTE 0x74 ++#define AR7240_STATS_TX1518BYTE 0x78 ++#define AR7240_STATS_TXMAXBYTE 0x7c ++#define AR7240_STATS_TXOVERSIZE 0x80 ++#define AR7240_STATS_TXBYTE 0x84 ++#define AR7240_STATS_TXCOLLISION 0x8c ++#define AR7240_STATS_TXABORTCOL 0x90 ++#define AR7240_STATS_TXMULTICOL 0x94 ++#define AR7240_STATS_TXSINGLECOL 0x98 ++#define AR7240_STATS_TXEXCDEFER 0x9c ++#define AR7240_STATS_TXDEFER 0xa0 ++#define AR7240_STATS_TXLATECOL 0xa4 + -+#include -+#include ++#define AR7240_PORT_CPU 0 ++#define AR7240_NUM_PORTS 6 ++#define AR7240_NUM_PHYS 5 + -+struct cybertan_header { -+ char magic[4]; -+ u8 res1[4]; -+ char fw_date[3]; -+ char fw_ver[3]; -+ char id[4]; -+ char hw_ver; -+ char unused; -+ u8 flags[2]; -+ u8 res2[10]; -+}; ++#define AR7240_PHY_ID1 0x004d ++#define AR7240_PHY_ID2 0xd041 + -+#define TRX_PARTS 6 -+#define TRX_MAGIC 0x30524448 -+#define TRX_MAX_OFFSET 3 ++#define AR7240_PORT_MASK(_port) BIT((_port)) ++#define AR7240_PORT_MASK_ALL BITM(AR7240_NUM_PORTS) ++#define AR7240_PORT_MASK_BUT(_port) (AR7240_PORT_MASK_ALL & ~BIT((_port))) + -+struct trx_header { -+ uint32_t magic; /* "HDR0" */ -+ uint32_t len; /* Length of file including header */ -+ uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ -+ uint32_t flag_version; /* 0:15 flags, 16:31 version */ -+ uint32_t offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ -+}; ++#define AR7240_MAX_VLANS 16 + -+#define IH_MAGIC 0x27051956 /* Image Magic Number */ -+#define IH_NMLEN 32 /* Image Name Length */ ++#define sw_to_ar7240(_dev) container_of(_dev, struct ar7240sw, swdev) + -+struct uimage_header { -+ uint32_t ih_magic; /* Image Header Magic Number */ -+ uint32_t ih_hcrc; /* Image Header CRC Checksum */ -+ uint32_t ih_time; /* Image Creation Timestamp */ -+ uint32_t ih_size; /* Image Data Size */ -+ uint32_t ih_load; /* Data» Load Address */ -+ uint32_t ih_ep; /* Entry Point Address */ -+ uint32_t ih_dcrc; /* Image Data CRC Checksum */ -+ uint8_t ih_os; /* Operating System */ -+ uint8_t ih_arch; /* CPU architecture */ -+ uint8_t ih_type; /* Image Type */ -+ uint8_t ih_comp; /* Compression Type */ -+ uint8_t ih_name[IH_NMLEN]; /* Image Name */ ++struct ar7240sw { ++ struct mii_bus *mii_bus; ++ struct switch_dev swdev; ++ bool vlan; ++ u16 vlan_id[AR7240_MAX_VLANS]; ++ u8 vlan_table[AR7240_MAX_VLANS]; ++ u8 vlan_tagged; ++ u16 pvid[AR7240_NUM_PORTS]; +}; + -+struct wrt160nl_header { -+ struct cybertan_header cybertan; -+ struct trx_header trx; -+ struct uimage_header uimage; -+} __attribute__ ((packed)); -+ -+static struct mtd_partition trx_parts[TRX_PARTS]; ++struct ar7240sw_hw_stat { ++ char string[ETH_GSTRING_LEN]; ++ int sizeof_stat; ++ int reg; ++}; + -+#define WRT160NL_UBOOT_LEN 0x40000 -+#define WRT160NL_ART_LEN 0x10000 -+#define WRT160NL_NVRAM_LEN 0x10000 ++static DEFINE_MUTEX(reg_mutex); + -+static int wrt160nl_parse_partitions(struct mtd_info *master, -+ struct mtd_partition **pparts, -+ unsigned long origin) ++static inline void ar7240sw_init(struct ar7240sw *as, struct mii_bus *mii) +{ -+ struct wrt160nl_header *header; -+ struct trx_header *theader; -+ struct uimage_header *uheader; -+ size_t retlen; -+ unsigned int kernel_len; -+ unsigned int uboot_len = max(master->erasesize, WRT160NL_UBOOT_LEN); -+ unsigned int nvram_len = max(master->erasesize, WRT160NL_NVRAM_LEN); -+ unsigned int art_len = max(master->erasesize, WRT160NL_ART_LEN); -+ int ret; -+ -+ header = vmalloc(sizeof(*header)); -+ if (!header) { -+ return -ENOMEM; -+ goto out; -+ } -+ -+ ret = master->read(master, uboot_len, sizeof(*header), -+ &retlen, (void *) header); -+ if (ret) -+ goto free_hdr; ++ as->mii_bus = mii; ++} + -+ if (retlen != sizeof(*header)) { -+ ret = -EIO; -+ goto free_hdr; -+ } ++static inline u16 mk_phy_addr(u32 reg) ++{ ++ return 0x17 & ((reg >> 4) | 0x10); ++} + -+ if (strncmp(header->cybertan.magic, "NL16", 4) != 0) { -+ printk(KERN_NOTICE "%s: no WRT160NL signature found\n", -+ master->name); -+ goto free_hdr; -+ } ++static inline u16 mk_phy_reg(u32 reg) ++{ ++ return (reg << 1) & 0x1e; ++} + -+ theader = &header->trx; -+ if (le32_to_cpu(theader->magic) != TRX_MAGIC) { -+ printk(KERN_NOTICE "%s: no TRX header found\n", master->name); -+ goto free_hdr; -+ } ++static inline u16 mk_high_addr(u32 reg) ++{ ++ return (reg >> 7) & 0x1ff; ++} + -+ uheader = &header->uimage; -+ if (uheader->ih_magic != IH_MAGIC) { -+ printk(KERN_NOTICE "%s: no uImage found\n", master->name); -+ goto free_hdr; -+ } ++static u32 __ar7240sw_reg_read(struct mii_bus *mii, u32 reg) ++{ ++ unsigned long flags; ++ u16 phy_addr; ++ u16 phy_reg; ++ u32 hi, lo; + -+ kernel_len = le32_to_cpu(theader->offsets[1]) + -+ sizeof(struct cybertan_header); ++ reg = (reg & 0xfffffffc) >> 2; ++ phy_addr = mk_phy_addr(reg); ++ phy_reg = mk_phy_reg(reg); + -+ trx_parts[0].name = "u-boot"; -+ trx_parts[0].offset = 0; -+ trx_parts[0].size = uboot_len; -+ trx_parts[0].mask_flags = MTD_WRITEABLE; ++ local_irq_save(flags); ++ ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); ++ lo = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg); ++ hi = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg + 1); ++ local_irq_restore(flags); + -+ trx_parts[1].name = "kernel"; -+ trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size; -+ trx_parts[1].size = kernel_len; -+ trx_parts[1].mask_flags = 0; ++ return (hi << 16) | lo; ++} + -+ trx_parts[2].name = "rootfs"; -+ trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size; -+ trx_parts[2].size = master->size - uboot_len - nvram_len - art_len - -+ trx_parts[1].size; -+ trx_parts[2].mask_flags = 0; ++static void __ar7240sw_reg_write(struct mii_bus *mii, u32 reg, u32 val) ++{ ++ unsigned long flags; ++ u16 phy_addr; ++ u16 phy_reg; + -+ trx_parts[3].name = "nvram"; -+ trx_parts[3].offset = master->size - nvram_len - art_len; -+ trx_parts[3].size = nvram_len; -+ trx_parts[3].mask_flags = MTD_WRITEABLE; ++ reg = (reg & 0xfffffffc) >> 2; ++ phy_addr = mk_phy_addr(reg); ++ phy_reg = mk_phy_reg(reg); + -+ trx_parts[4].name = "art"; -+ trx_parts[4].offset = master->size - art_len; -+ trx_parts[4].size = art_len; -+ trx_parts[4].mask_flags = MTD_WRITEABLE; ++ local_irq_save(flags); ++ ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); ++ ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg + 1, (val >> 16)); ++ ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg, (val & 0xffff)); ++ local_irq_restore(flags); ++} + -+ trx_parts[5].name = "firmware"; -+ trx_parts[5].offset = uboot_len; -+ trx_parts[5].size = master->size - uboot_len - nvram_len - art_len; -+ trx_parts[5].mask_flags = 0; ++static u32 ar7240sw_reg_read(struct mii_bus *mii, u32 reg_addr) ++{ ++ u32 ret; + -+ *pparts = trx_parts; -+ ret = TRX_PARTS; ++ mutex_lock(®_mutex); ++ ret = __ar7240sw_reg_read(mii, reg_addr); ++ mutex_unlock(®_mutex); + -+free_hdr: -+ vfree(header); -+out: + return ret; +} + -+static struct mtd_part_parser wrt160nl_parser = { -+ .owner = THIS_MODULE, -+ .parse_fn = wrt160nl_parse_partitions, -+ .name = "wrt160nl", -+}; -+ -+static int __init wrt160nl_parser_init(void) ++static void ar7240sw_reg_write(struct mii_bus *mii, u32 reg_addr, u32 reg_val) +{ -+ return register_mtd_parser(&wrt160nl_parser); ++ mutex_lock(®_mutex); ++ __ar7240sw_reg_write(mii, reg_addr, reg_val); ++ mutex_unlock(®_mutex); +} + -+module_init(wrt160nl_parser_init); ++static u32 ar7240sw_reg_rmw(struct mii_bus *mii, u32 reg, u32 mask, u32 val) ++{ ++ u32 t; + -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Christian Daniel "); -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar7240.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ar7240.c ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar7240.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ar7240.c 2011-08-06 09:32:37.298018216 +0200 -@@ -0,0 +1,913 @@ -+/* -+ * Driver for the built-in ethernet switch of the Atheros AR7240 SoC -+ * Copyright (c) 2010 Gabor Juhos -+ * Copyright (c) 2010 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ ++ mutex_lock(®_mutex); ++ t = __ar7240sw_reg_read(mii, reg); ++ t &= ~mask; ++ t |= val; ++ __ar7240sw_reg_write(mii, reg, t); ++ mutex_unlock(®_mutex); + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "ag71xx.h" ++ return t; ++} + -+#define BITM(_count) (BIT(_count) - 1) -+#define BITS(_shift, _count) (BITM(_count) << _shift) ++static void ar7240sw_reg_set(struct mii_bus *mii, u32 reg, u32 val) ++{ ++ u32 t; + -+#define AR7240_REG_MASK_CTRL 0x00 -+#define AR7240_MASK_CTRL_REVISION_M BITM(8) -+#define AR7240_MASK_CTRL_VERSION_M BITM(8) -+#define AR7240_MASK_CTRL_VERSION_S 8 -+#define AR7240_MASK_CTRL_SOFT_RESET BIT(31) ++ mutex_lock(®_mutex); ++ t = __ar7240sw_reg_read(mii, reg); ++ t |= val; ++ __ar7240sw_reg_write(mii, reg, t); ++ mutex_unlock(®_mutex); ++} + -+#define AR7240_REG_MAC_ADDR0 0x20 -+#define AR7240_REG_MAC_ADDR1 0x24 ++static int __ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, ++ unsigned timeout) ++{ ++ int i; + -+#define AR7240_REG_FLOOD_MASK 0x2c -+#define AR7240_FLOOD_MASK_BROAD_TO_CPU BIT(26) ++ for (i = 0; i < timeout; i++) { ++ u32 t; + -+#define AR7240_REG_GLOBAL_CTRL 0x30 -+#define AR7240_GLOBAL_CTRL_MTU_M BITM(12) ++ t = __ar7240sw_reg_read(mii, reg); ++ if ((t & mask) == val) ++ return 0; + -+#define AR7240_REG_VTU 0x0040 -+#define AR7240_VTU_OP BITM(3) -+#define AR7240_VTU_OP_NOOP 0x0 -+#define AR7240_VTU_OP_FLUSH 0x1 -+#define AR7240_VTU_OP_LOAD 0x2 -+#define AR7240_VTU_OP_PURGE 0x3 -+#define AR7240_VTU_OP_REMOVE_PORT 0x4 -+#define AR7240_VTU_ACTIVE BIT(3) -+#define AR7240_VTU_FULL BIT(4) -+#define AR7240_VTU_PORT BITS(8, 4) -+#define AR7240_VTU_PORT_S 8 -+#define AR7240_VTU_VID BITS(16, 12) -+#define AR7240_VTU_VID_S 16 -+#define AR7240_VTU_PRIO BITS(28, 3) -+#define AR7240_VTU_PRIO_S 28 -+#define AR7240_VTU_PRIO_EN BIT(31) -+ -+#define AR7240_REG_VTU_DATA 0x0044 -+#define AR7240_VTUDATA_MEMBER BITS(0, 10) -+#define AR7240_VTUDATA_VALID BIT(11) ++ msleep(1); ++ } + -+#define AR7240_REG_ATU 0x50 -+#define AR7240_ATU_FLUSH_ALL 0x1 ++ return -ETIMEDOUT; ++} + -+#define AR7240_REG_AT_CTRL 0x5c -+#define AR7240_AT_CTRL_AGE_TIME BITS(0, 15) -+#define AR7240_AT_CTRL_AGE_EN BIT(17) -+#define AR7240_AT_CTRL_LEARN_CHANGE BIT(18) -+#define AR7240_AT_CTRL_ARP_EN BIT(20) ++static int ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, ++ unsigned timeout) ++{ ++ int ret; + -+#define AR7240_REG_TAG_PRIORITY 0x70 ++ mutex_lock(®_mutex); ++ ret = __ar7240sw_reg_wait(mii, reg, mask, val, timeout); ++ mutex_unlock(®_mutex); ++ return ret; ++} + -+#define AR7240_REG_SERVICE_TAG 0x74 -+#define AR7240_SERVICE_TAG_M BITM(16) ++u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, ++ unsigned reg_addr) ++{ ++ u32 t, val = 0xffff; ++ int err; + -+#define AR7240_REG_CPU_PORT 0x78 -+#define AR7240_MIRROR_PORT_S 4 -+#define AR7240_CPU_PORT_EN BIT(8) ++ if (phy_addr >= AR7240_NUM_PHYS) ++ return 0xffff; + -+#define AR7240_REG_MIB_FUNCTION0 0x80 -+#define AR7240_MIB_TIMER_M BITM(16) -+#define AR7240_MIB_AT_HALF_EN BIT(16) -+#define AR7240_MIB_BUSY BIT(17) -+#define AR7240_MIB_FUNC_S 24 -+#define AR7240_MIB_FUNC_NO_OP 0x0 -+#define AR7240_MIB_FUNC_FLUSH 0x1 -+#define AR7240_MIB_FUNC_CAPTURE 0x3 ++ mutex_lock(®_mutex); ++ t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | ++ (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | ++ AR7240_MDIO_CTRL_MASTER_EN | ++ AR7240_MDIO_CTRL_BUSY | ++ AR7240_MDIO_CTRL_CMD_READ; + -+#define AR7240_REG_MDIO_CTRL 0x98 -+#define AR7240_MDIO_CTRL_DATA_M BITM(16) -+#define AR7240_MDIO_CTRL_REG_ADDR_S 16 -+#define AR7240_MDIO_CTRL_PHY_ADDR_S 21 -+#define AR7240_MDIO_CTRL_CMD_WRITE 0 -+#define AR7240_MDIO_CTRL_CMD_READ BIT(27) -+#define AR7240_MDIO_CTRL_MASTER_EN BIT(30) -+#define AR7240_MDIO_CTRL_BUSY BIT(31) ++ __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); ++ err = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, ++ AR7240_MDIO_CTRL_BUSY, 0, 5); ++ if (!err) ++ val = __ar7240sw_reg_read(mii, AR7240_REG_MDIO_CTRL); ++ mutex_unlock(®_mutex); + -+#define AR7240_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100) ++ return val & AR7240_MDIO_CTRL_DATA_M; ++} + -+#define AR7240_REG_PORT_STATUS(_port) (AR7240_REG_PORT_BASE((_port)) + 0x00) -+#define AR7240_PORT_STATUS_SPEED_M BITM(2) -+#define AR7240_PORT_STATUS_SPEED_10 0 -+#define AR7240_PORT_STATUS_SPEED_100 1 -+#define AR7240_PORT_STATUS_SPEED_1000 2 -+#define AR7240_PORT_STATUS_TXMAC BIT(2) -+#define AR7240_PORT_STATUS_RXMAC BIT(3) -+#define AR7240_PORT_STATUS_TXFLOW BIT(4) -+#define AR7240_PORT_STATUS_RXFLOW BIT(5) -+#define AR7240_PORT_STATUS_DUPLEX BIT(6) -+#define AR7240_PORT_STATUS_LINK_UP BIT(8) -+#define AR7240_PORT_STATUS_LINK_AUTO BIT(9) -+#define AR7240_PORT_STATUS_LINK_PAUSE BIT(10) ++int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, ++ unsigned reg_addr, u16 reg_val) ++{ ++ u32 t; ++ int ret; + -+#define AR7240_REG_PORT_CTRL(_port) (AR7240_REG_PORT_BASE((_port)) + 0x04) -+#define AR7240_PORT_CTRL_STATE_M BITM(3) -+#define AR7240_PORT_CTRL_STATE_DISABLED 0 -+#define AR7240_PORT_CTRL_STATE_BLOCK 1 -+#define AR7240_PORT_CTRL_STATE_LISTEN 2 -+#define AR7240_PORT_CTRL_STATE_LEARN 3 -+#define AR7240_PORT_CTRL_STATE_FORWARD 4 -+#define AR7240_PORT_CTRL_LEARN_LOCK BIT(7) -+#define AR7240_PORT_CTRL_VLAN_MODE_S 8 -+#define AR7240_PORT_CTRL_VLAN_MODE_KEEP 0 -+#define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1 -+#define AR7240_PORT_CTRL_VLAN_MODE_ADD 2 -+#define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3 -+#define AR7240_PORT_CTRL_IGMP_SNOOP BIT(10) -+#define AR7240_PORT_CTRL_HEADER BIT(11) -+#define AR7240_PORT_CTRL_MAC_LOOP BIT(12) -+#define AR7240_PORT_CTRL_SINGLE_VLAN BIT(13) -+#define AR7240_PORT_CTRL_LEARN BIT(14) -+#define AR7240_PORT_CTRL_DOUBLE_TAG BIT(15) -+#define AR7240_PORT_CTRL_MIRROR_TX BIT(16) -+#define AR7240_PORT_CTRL_MIRROR_RX BIT(17) ++ if (phy_addr >= AR7240_NUM_PHYS) ++ return -EINVAL; + -+#define AR7240_REG_PORT_VLAN(_port) (AR7240_REG_PORT_BASE((_port)) + 0x08) ++ mutex_lock(®_mutex); ++ t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | ++ (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | ++ AR7240_MDIO_CTRL_MASTER_EN | ++ AR7240_MDIO_CTRL_BUSY | ++ AR7240_MDIO_CTRL_CMD_WRITE | ++ reg_val; + -+#define AR7240_PORT_VLAN_DEFAULT_ID_S 0 -+#define AR7240_PORT_VLAN_DEST_PORTS_S 16 -+#define AR7240_PORT_VLAN_MODE_S 30 -+#define AR7240_PORT_VLAN_MODE_PORT_ONLY 0 -+#define AR7240_PORT_VLAN_MODE_PORT_FALLBACK 1 -+#define AR7240_PORT_VLAN_MODE_VLAN_ONLY 2 -+#define AR7240_PORT_VLAN_MODE_SECURE 3 ++ __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); ++ ret = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, ++ AR7240_MDIO_CTRL_BUSY, 0, 5); ++ mutex_unlock(®_mutex); + ++ return ret; ++} + -+#define AR7240_REG_STATS_BASE(_port) (0x20000 + (_port) * 0x100) ++static int ar7240sw_capture_stats(struct ar7240sw *as) ++{ ++ struct mii_bus *mii = as->mii_bus; ++ int ret; + -+#define AR7240_STATS_RXBROAD 0x00 -+#define AR7240_STATS_RXPAUSE 0x04 -+#define AR7240_STATS_RXMULTI 0x08 -+#define AR7240_STATS_RXFCSERR 0x0c -+#define AR7240_STATS_RXALIGNERR 0x10 -+#define AR7240_STATS_RXRUNT 0x14 -+#define AR7240_STATS_RXFRAGMENT 0x18 -+#define AR7240_STATS_RX64BYTE 0x1c -+#define AR7240_STATS_RX128BYTE 0x20 -+#define AR7240_STATS_RX256BYTE 0x24 -+#define AR7240_STATS_RX512BYTE 0x28 -+#define AR7240_STATS_RX1024BYTE 0x2c -+#define AR7240_STATS_RX1518BYTE 0x30 -+#define AR7240_STATS_RXMAXBYTE 0x34 -+#define AR7240_STATS_RXTOOLONG 0x38 -+#define AR7240_STATS_RXGOODBYTE 0x3c -+#define AR7240_STATS_RXBADBYTE 0x44 -+#define AR7240_STATS_RXOVERFLOW 0x4c -+#define AR7240_STATS_FILTERED 0x50 -+#define AR7240_STATS_TXBROAD 0x54 -+#define AR7240_STATS_TXPAUSE 0x58 -+#define AR7240_STATS_TXMULTI 0x5c -+#define AR7240_STATS_TXUNDERRUN 0x60 -+#define AR7240_STATS_TX64BYTE 0x64 -+#define AR7240_STATS_TX128BYTE 0x68 -+#define AR7240_STATS_TX256BYTE 0x6c -+#define AR7240_STATS_TX512BYTE 0x70 -+#define AR7240_STATS_TX1024BYTE 0x74 -+#define AR7240_STATS_TX1518BYTE 0x78 -+#define AR7240_STATS_TXMAXBYTE 0x7c -+#define AR7240_STATS_TXOVERSIZE 0x80 -+#define AR7240_STATS_TXBYTE 0x84 -+#define AR7240_STATS_TXCOLLISION 0x8c -+#define AR7240_STATS_TXABORTCOL 0x90 -+#define AR7240_STATS_TXMULTICOL 0x94 -+#define AR7240_STATS_TXSINGLECOL 0x98 -+#define AR7240_STATS_TXEXCDEFER 0x9c -+#define AR7240_STATS_TXDEFER 0xa0 -+#define AR7240_STATS_TXLATECOL 0xa4 ++ /* Capture the hardware statistics for all ports */ ++ ar7240sw_reg_write(mii, AR7240_REG_MIB_FUNCTION0, ++ (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S)); + -+#define AR7240_PORT_CPU 0 -+#define AR7240_NUM_PORTS 6 -+#define AR7240_NUM_PHYS 5 ++ /* Wait for the capturing to complete. */ ++ ret = ar7240sw_reg_wait(mii, AR7240_REG_MIB_FUNCTION0, ++ AR7240_MIB_BUSY, 0, 10); ++ return ret; ++} + -+#define AR7240_PHY_ID1 0x004d -+#define AR7240_PHY_ID2 0xd041 ++static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port) ++{ ++ ar7240sw_reg_write(as->mii_bus, AR7240_REG_PORT_CTRL(port), ++ AR7240_PORT_CTRL_STATE_DISABLED); ++} + -+#define AR7240_PORT_MASK(_port) BIT((_port)) -+#define AR7240_PORT_MASK_ALL BITM(AR7240_NUM_PORTS) -+#define AR7240_PORT_MASK_BUT(_port) (AR7240_PORT_MASK_ALL & ~BIT((_port))) ++static void ar7240sw_setup(struct ar7240sw *as) ++{ ++ struct mii_bus *mii = as->mii_bus; + -+#define AR7240_MAX_VLANS 16 ++ /* Enable CPU port, and disable mirror port */ ++ ar7240sw_reg_write(mii, AR7240_REG_CPU_PORT, ++ AR7240_CPU_PORT_EN | ++ (15 << AR7240_MIRROR_PORT_S)); + -+#define sw_to_ar7240(_dev) container_of(_dev, struct ar7240sw, swdev) ++ /* Setup TAG priority mapping */ ++ ar7240sw_reg_write(mii, AR7240_REG_TAG_PRIORITY, 0xfa50); + -+struct ar7240sw { -+ struct mii_bus *mii_bus; -+ struct switch_dev swdev; -+ bool vlan; -+ u16 vlan_id[AR7240_MAX_VLANS]; -+ u8 vlan_table[AR7240_MAX_VLANS]; -+ u8 vlan_tagged; -+ u16 pvid[AR7240_NUM_PORTS]; -+}; ++ /* Enable ARP frame acknowledge, aging, MAC replacing */ ++ ar7240sw_reg_write(mii, AR7240_REG_AT_CTRL, ++ 0x2b /* 5 min age time */ | ++ AR7240_AT_CTRL_AGE_EN | ++ AR7240_AT_CTRL_ARP_EN | ++ AR7240_AT_CTRL_LEARN_CHANGE); + -+struct ar7240sw_hw_stat { -+ char string[ETH_GSTRING_LEN]; -+ int sizeof_stat; -+ int reg; -+}; ++ /* Enable Broadcast frames transmitted to the CPU */ ++ ar7240sw_reg_set(mii, AR7240_REG_FLOOD_MASK, ++ AR7240_FLOOD_MASK_BROAD_TO_CPU); + -+static DEFINE_MUTEX(reg_mutex); ++ /* setup MTU */ ++ ar7240sw_reg_rmw(mii, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M, ++ 1536); + -+static inline void ar7240sw_init(struct ar7240sw *as, struct mii_bus *mii) -+{ -+ as->mii_bus = mii; ++ /* setup Service TAG */ ++ ar7240sw_reg_rmw(mii, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M, 0); +} + -+static inline u16 mk_phy_addr(u32 reg) ++static int ar7240sw_reset(struct ar7240sw *as) +{ -+ return 0x17 & ((reg >> 4) | 0x10); -+} -+ -+static inline u16 mk_phy_reg(u32 reg) -+{ -+ return (reg << 1) & 0x1e; -+} -+ -+static inline u16 mk_high_addr(u32 reg) -+{ -+ return (reg >> 7) & 0x1ff; -+} -+ -+static u32 __ar7240sw_reg_read(struct mii_bus *mii, u32 reg) -+{ -+ unsigned long flags; -+ u16 phy_addr; -+ u16 phy_reg; -+ u32 hi, lo; -+ -+ reg = (reg & 0xfffffffc) >> 2; -+ phy_addr = mk_phy_addr(reg); -+ phy_reg = mk_phy_reg(reg); -+ -+ local_irq_save(flags); -+ ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); -+ lo = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg); -+ hi = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg + 1); -+ local_irq_restore(flags); -+ -+ return (hi << 16) | lo; -+} -+ -+static void __ar7240sw_reg_write(struct mii_bus *mii, u32 reg, u32 val) -+{ -+ unsigned long flags; -+ u16 phy_addr; -+ u16 phy_reg; -+ -+ reg = (reg & 0xfffffffc) >> 2; -+ phy_addr = mk_phy_addr(reg); -+ phy_reg = mk_phy_reg(reg); -+ -+ local_irq_save(flags); -+ ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); -+ ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg + 1, (val >> 16)); -+ ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg, (val & 0xffff)); -+ local_irq_restore(flags); -+} -+ -+static u32 ar7240sw_reg_read(struct mii_bus *mii, u32 reg_addr) -+{ -+ u32 ret; -+ -+ mutex_lock(®_mutex); -+ ret = __ar7240sw_reg_read(mii, reg_addr); -+ mutex_unlock(®_mutex); -+ -+ return ret; -+} -+ -+static void ar7240sw_reg_write(struct mii_bus *mii, u32 reg_addr, u32 reg_val) -+{ -+ mutex_lock(®_mutex); -+ __ar7240sw_reg_write(mii, reg_addr, reg_val); -+ mutex_unlock(®_mutex); -+} -+ -+static u32 ar7240sw_reg_rmw(struct mii_bus *mii, u32 reg, u32 mask, u32 val) -+{ -+ u32 t; -+ -+ mutex_lock(®_mutex); -+ t = __ar7240sw_reg_read(mii, reg); -+ t &= ~mask; -+ t |= val; -+ __ar7240sw_reg_write(mii, reg, t); -+ mutex_unlock(®_mutex); -+ -+ return t; -+} -+ -+static void ar7240sw_reg_set(struct mii_bus *mii, u32 reg, u32 val) -+{ -+ u32 t; -+ -+ mutex_lock(®_mutex); -+ t = __ar7240sw_reg_read(mii, reg); -+ t |= val; -+ __ar7240sw_reg_write(mii, reg, t); -+ mutex_unlock(®_mutex); -+} -+ -+static int __ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, -+ unsigned timeout) -+{ -+ int i; -+ -+ for (i = 0; i < timeout; i++) { -+ u32 t; -+ -+ t = __ar7240sw_reg_read(mii, reg); -+ if ((t & mask) == val) -+ return 0; -+ -+ msleep(1); -+ } -+ -+ return -ETIMEDOUT; -+} -+ -+static int ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, -+ unsigned timeout) -+{ -+ int ret; -+ -+ mutex_lock(®_mutex); -+ ret = __ar7240sw_reg_wait(mii, reg, mask, val, timeout); -+ mutex_unlock(®_mutex); -+ return ret; -+} -+ -+u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, -+ unsigned reg_addr) -+{ -+ u32 t, val = 0xffff; -+ int err; -+ -+ if (phy_addr >= AR7240_NUM_PHYS) -+ return 0xffff; -+ -+ mutex_lock(®_mutex); -+ t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | -+ (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | -+ AR7240_MDIO_CTRL_MASTER_EN | -+ AR7240_MDIO_CTRL_BUSY | -+ AR7240_MDIO_CTRL_CMD_READ; -+ -+ __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); -+ err = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, -+ AR7240_MDIO_CTRL_BUSY, 0, 5); -+ if (!err) -+ val = __ar7240sw_reg_read(mii, AR7240_REG_MDIO_CTRL); -+ mutex_unlock(®_mutex); -+ -+ return val & AR7240_MDIO_CTRL_DATA_M; -+} -+ -+int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, -+ unsigned reg_addr, u16 reg_val) -+{ -+ u32 t; -+ int ret; -+ -+ if (phy_addr >= AR7240_NUM_PHYS) -+ return -EINVAL; -+ -+ mutex_lock(®_mutex); -+ t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | -+ (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | -+ AR7240_MDIO_CTRL_MASTER_EN | -+ AR7240_MDIO_CTRL_BUSY | -+ AR7240_MDIO_CTRL_CMD_WRITE | -+ reg_val; -+ -+ __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); -+ ret = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, -+ AR7240_MDIO_CTRL_BUSY, 0, 5); -+ mutex_unlock(®_mutex); -+ -+ return ret; -+} -+ -+static int ar7240sw_capture_stats(struct ar7240sw *as) -+{ -+ struct mii_bus *mii = as->mii_bus; -+ int ret; -+ -+ /* Capture the hardware statistics for all ports */ -+ ar7240sw_reg_write(mii, AR7240_REG_MIB_FUNCTION0, -+ (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S)); -+ -+ /* Wait for the capturing to complete. */ -+ ret = ar7240sw_reg_wait(mii, AR7240_REG_MIB_FUNCTION0, -+ AR7240_MIB_BUSY, 0, 10); -+ return ret; -+} -+ -+static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port) -+{ -+ ar7240sw_reg_write(as->mii_bus, AR7240_REG_PORT_CTRL(port), -+ AR7240_PORT_CTRL_STATE_DISABLED); -+} -+ -+static void ar7240sw_setup(struct ar7240sw *as) -+{ -+ struct mii_bus *mii = as->mii_bus; -+ -+ /* Enable CPU port, and disable mirror port */ -+ ar7240sw_reg_write(mii, AR7240_REG_CPU_PORT, -+ AR7240_CPU_PORT_EN | -+ (15 << AR7240_MIRROR_PORT_S)); -+ -+ /* Setup TAG priority mapping */ -+ ar7240sw_reg_write(mii, AR7240_REG_TAG_PRIORITY, 0xfa50); -+ -+ /* Enable ARP frame acknowledge, aging, MAC replacing */ -+ ar7240sw_reg_write(mii, AR7240_REG_AT_CTRL, -+ 0x2b /* 5 min age time */ | -+ AR7240_AT_CTRL_AGE_EN | -+ AR7240_AT_CTRL_ARP_EN | -+ AR7240_AT_CTRL_LEARN_CHANGE); -+ -+ /* Enable Broadcast frames transmitted to the CPU */ -+ ar7240sw_reg_set(mii, AR7240_REG_FLOOD_MASK, -+ AR7240_FLOOD_MASK_BROAD_TO_CPU); -+ -+ /* setup MTU */ -+ ar7240sw_reg_rmw(mii, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M, -+ 1536); -+ -+ /* setup Service TAG */ -+ ar7240sw_reg_rmw(mii, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M, 0); -+} -+ -+static int ar7240sw_reset(struct ar7240sw *as) -+{ -+ struct mii_bus *mii = as->mii_bus; -+ int ret; -+ int i; ++ struct mii_bus *mii = as->mii_bus; ++ int ret; ++ int i; + + /* Set all ports to disabled state. */ + for (i = 0; i < AR7240_NUM_PORTS; i++) @@ -18678,7 +16803,7 @@ diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar7240.c linux-2.6.39/driv +} diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar8216.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ar8216.c --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar8216.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ar8216.c 2011-04-27 12:19:22.257663952 +0200 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ar8216.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,44 @@ +/* + * Atheros AR71xx built-in ethernet mac driver @@ -18726,7 +16851,7 @@ diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ar8216.c linux-2.6.39/driv +} diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_debugfs.c linux-2.6.39/drivers/net/ag71xx/ag71xx_debugfs.c --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_debugfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_debugfs.c 2011-08-06 09:32:37.298018216 +0200 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_debugfs.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,280 @@ +/* + * Atheros AR71xx built-in ethernet mac driver @@ -19010,7 +17135,7 @@ diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_debugfs.c linux-2.6.39/dri +} diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ethtool.c linux-2.6.39/drivers/net/ag71xx/ag71xx_ethtool.c --- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ethtool.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ethtool.c 2011-08-06 09:32:37.308017908 +0200 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_ethtool.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,124 @@ +/* + * Atheros AR71xx built-in ethernet mac driver @@ -19136,10 +17261,10 @@ diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_ethtool.c linux-2.6.39/dri + .set_ringparam = ag71xx_ethtool_set_ringparam, + .get_link = ethtool_op_get_link, +}; -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h linux-2.6.39/drivers/net/ag71xx/ag71xx.h ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx.h 2011-08-22 07:40:12.160480642 +0200 -@@ -0,0 +1,518 @@ +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,1291 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * @@ -19153,4330 +17278,3155 @@ diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx.h linux-2.6.39/drivers/net + * by the Free Software Foundation. + */ + -+#ifndef __AG71XX_H -+#define __AG71XX_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include ++#include "ag71xx.h" + -+#include -+#include -+ -+#define AG71XX_DRV_NAME "ag71xx" -+#define AG71XX_DRV_VERSION "0.5.35" ++#define AG71XX_DEFAULT_MSG_ENABLE \ ++ (NETIF_MSG_DRV \ ++ | NETIF_MSG_PROBE \ ++ | NETIF_MSG_LINK \ ++ | NETIF_MSG_TIMER \ ++ | NETIF_MSG_IFDOWN \ ++ | NETIF_MSG_IFUP \ ++ | NETIF_MSG_RX_ERR \ ++ | NETIF_MSG_TX_ERR) + -+#define AG71XX_NAPI_WEIGHT 64 -+#define AG71XX_OOM_REFILL (1 + HZ/10) ++static int ag71xx_msg_level = -1; + -+#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE) -+#define AG71XX_INT_TX (AG71XX_INT_TX_PS) -+#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF) ++module_param_named(msg_level, ag71xx_msg_level, int, 0); ++MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)"); + -+#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX) -+#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL) ++static void ag71xx_dump_dma_regs(struct ag71xx *ag) ++{ ++ DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_TX_CTRL), ++ ag71xx_rr(ag, AG71XX_REG_TX_DESC), ++ ag71xx_rr(ag, AG71XX_REG_TX_STATUS)); + -+#define AG71XX_TX_MTU_LEN 1540 -+#define AG71XX_RX_PKT_RESERVE 64 -+#define AG71XX_RX_PKT_SIZE \ -+ (AG71XX_RX_PKT_RESERVE + ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) ++ DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_RX_CTRL), ++ ag71xx_rr(ag, AG71XX_REG_RX_DESC), ++ ag71xx_rr(ag, AG71XX_REG_RX_STATUS)); ++} + -+#define AG71XX_TX_RING_SIZE_DEFAULT 64 -+#define AG71XX_RX_RING_SIZE_DEFAULT 128 ++static void ag71xx_dump_regs(struct ag71xx *ag) ++{ ++ DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_MAC_CFG1), ++ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), ++ ag71xx_rr(ag, AG71XX_REG_MAC_IPG), ++ ag71xx_rr(ag, AG71XX_REG_MAC_HDX), ++ ag71xx_rr(ag, AG71XX_REG_MAC_MFL)); ++ DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), ++ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1), ++ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2)); ++ DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); ++ DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), ++ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); ++} + -+#define AG71XX_TX_RING_SIZE_MAX 256 -+#define AG71XX_RX_RING_SIZE_MAX 256 ++static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr) ++{ ++ DBG("%s: %s intr=%08x %s%s%s%s%s%s\n", ++ ag->dev->name, label, intr, ++ (intr & AG71XX_INT_TX_PS) ? "TXPS " : "", ++ (intr & AG71XX_INT_TX_UR) ? "TXUR " : "", ++ (intr & AG71XX_INT_TX_BE) ? "TXBE " : "", ++ (intr & AG71XX_INT_RX_PR) ? "RXPR " : "", ++ (intr & AG71XX_INT_RX_OF) ? "RXOF " : "", ++ (intr & AG71XX_INT_RX_BE) ? "RXBE " : ""); ++} + -+#ifdef CONFIG_AG71XX_DEBUG -+#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args) -+#else -+#define DBG(fmt, args...) do {} while (0) -+#endif ++static void ag71xx_ring_free(struct ag71xx_ring *ring) ++{ ++ kfree(ring->buf); + -+#define ag71xx_assert(_cond) \ -+do { \ -+ if (_cond) \ -+ break; \ -+ printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \ -+ BUG(); \ -+} while (0) ++ if (ring->descs_cpu) ++ dma_free_coherent(NULL, ring->size * ring->desc_size, ++ ring->descs_cpu, ring->descs_dma); ++} + -+struct ag71xx_desc { -+ u32 data; -+ u32 ctrl; -+#define DESC_EMPTY BIT(31) -+#define DESC_MORE BIT(24) -+#define DESC_PKTLEN_M 0xfff -+ u32 next; -+ u32 pad; -+} __attribute__((aligned(4))); ++static int ag71xx_ring_alloc(struct ag71xx_ring *ring) ++{ ++ int err; ++ int i; + -+struct ag71xx_buf { -+ struct sk_buff *skb; -+ struct ag71xx_desc *desc; -+ dma_addr_t dma_addr; -+ unsigned long timestamp; -+}; ++ ring->desc_size = sizeof(struct ag71xx_desc); ++ if (ring->desc_size % cache_line_size()) { ++ DBG("ag71xx: ring %p, desc size %u rounded to %u\n", ++ ring, ring->desc_size, ++ roundup(ring->desc_size, cache_line_size())); ++ ring->desc_size = roundup(ring->desc_size, cache_line_size()); ++ } + -+struct ag71xx_ring { -+ struct ag71xx_buf *buf; -+ u8 *descs_cpu; -+ dma_addr_t descs_dma; -+ unsigned int desc_size; -+ unsigned int curr; -+ unsigned int dirty; -+ unsigned int size; -+}; ++ ring->descs_cpu = dma_alloc_coherent(NULL, ring->size * ring->desc_size, ++ &ring->descs_dma, GFP_ATOMIC); ++ if (!ring->descs_cpu) { ++ err = -ENOMEM; ++ goto err; ++ } + -+struct ag71xx_mdio { -+ struct mii_bus *mii_bus; -+ int mii_irq[PHY_MAX_ADDR]; -+ void __iomem *mdio_base; -+ struct ag71xx_mdio_platform_data *pdata; -+}; + -+struct ag71xx_int_stats { -+ unsigned long rx_pr; -+ unsigned long rx_be; -+ unsigned long rx_of; -+ unsigned long tx_ps; -+ unsigned long tx_be; -+ unsigned long tx_ur; -+ unsigned long total; -+}; ++ ring->buf = kzalloc(ring->size * sizeof(*ring->buf), GFP_KERNEL); ++ if (!ring->buf) { ++ err = -ENOMEM; ++ goto err; ++ } + -+struct ag71xx_napi_stats { -+ unsigned long napi_calls; -+ unsigned long rx_count; -+ unsigned long rx_packets; -+ unsigned long rx_packets_max; -+ unsigned long tx_count; -+ unsigned long tx_packets; -+ unsigned long tx_packets_max; ++ for (i = 0; i < ring->size; i++) { ++ int idx = i * ring->desc_size; ++ ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[idx]; ++ DBG("ag71xx: ring %p, desc %d at %p\n", ++ ring, i, ring->buf[i].desc); ++ } + -+ unsigned long rx[AG71XX_NAPI_WEIGHT + 1]; -+ unsigned long tx[AG71XX_NAPI_WEIGHT + 1]; -+}; ++ return 0; + -+struct ag71xx_debug { -+ struct dentry *debugfs_dir; ++err: ++ return err; ++} + -+ struct ag71xx_int_stats int_stats; -+ struct ag71xx_napi_stats napi_stats; -+}; ++static void ag71xx_ring_tx_clean(struct ag71xx *ag) ++{ ++ struct ag71xx_ring *ring = &ag->tx_ring; ++ struct net_device *dev = ag->dev; + -+struct ag71xx { -+ void __iomem *mac_base; -+ void __iomem *mii_ctrl; ++ while (ring->curr != ring->dirty) { ++ u32 i = ring->dirty % ring->size; + -+ spinlock_t lock; -+ struct platform_device *pdev; -+ struct net_device *dev; -+ struct napi_struct napi; -+ u32 msg_enable; ++ if (!ag71xx_desc_empty(ring->buf[i].desc)) { ++ ring->buf[i].desc->ctrl = 0; ++ dev->stats.tx_errors++; ++ } + -+ struct ag71xx_desc *stop_desc; -+ dma_addr_t stop_desc_dma; ++ if (ring->buf[i].skb) ++ dev_kfree_skb_any(ring->buf[i].skb); + -+ struct ag71xx_ring rx_ring; -+ struct ag71xx_ring tx_ring; ++ ring->buf[i].skb = NULL; + -+ struct mii_bus *mii_bus; -+ struct phy_device *phy_dev; -+ void *phy_priv; ++ ring->dirty++; ++ } + -+ unsigned int link; -+ unsigned int speed; -+ int duplex; ++ /* flush descriptors */ ++ wmb(); + -+ struct work_struct restart_work; -+ struct delayed_work link_work; -+ struct timer_list oom_timer; ++} + -+#ifdef CONFIG_AG71XX_DEBUG_FS -+ struct ag71xx_debug debug; -+#endif -+}; ++static void ag71xx_ring_tx_init(struct ag71xx *ag) ++{ ++ struct ag71xx_ring *ring = &ag->tx_ring; ++ int i; + -+extern struct ethtool_ops ag71xx_ethtool_ops; -+void ag71xx_link_adjust(struct ag71xx *ag); ++ for (i = 0; i < ring->size; i++) { ++ ring->buf[i].desc->next = (u32) (ring->descs_dma + ++ ring->desc_size * ((i + 1) % ring->size)); + -+int ag71xx_mdio_driver_init(void) __init; -+void ag71xx_mdio_driver_exit(void); ++ ring->buf[i].desc->ctrl = DESC_EMPTY; ++ ring->buf[i].skb = NULL; ++ } + -+int ag71xx_phy_connect(struct ag71xx *ag); -+void ag71xx_phy_disconnect(struct ag71xx *ag); -+void ag71xx_phy_start(struct ag71xx *ag); -+void ag71xx_phy_stop(struct ag71xx *ag); ++ /* flush descriptors */ ++ wmb(); + -+static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag) -+{ -+ return ag->pdev->dev.platform_data; ++ ring->curr = 0; ++ ring->dirty = 0; +} + -+static inline int ag71xx_desc_empty(struct ag71xx_desc *desc) ++static void ag71xx_ring_rx_clean(struct ag71xx *ag) +{ -+ return (desc->ctrl & DESC_EMPTY) != 0; ++ struct ag71xx_ring *ring = &ag->rx_ring; ++ int i; ++ ++ if (!ring->buf) ++ return; ++ ++ for (i = 0; i < ring->size; i++) ++ if (ring->buf[i].skb) { ++ dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, ++ AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); ++ kfree_skb(ring->buf[i].skb); ++ } +} + -+static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc) ++static int ag71xx_rx_reserve(struct ag71xx *ag) +{ -+ return desc->ctrl & DESC_PKTLEN_M; ++ int reserve = 0; ++ ++ if (ag71xx_get_pdata(ag)->is_ar724x) { ++ if (!ag71xx_has_ar8216(ag)) ++ reserve = 2; ++ ++ if (ag->phy_dev) ++ reserve += 4 - (ag->phy_dev->pkt_align % 4); ++ ++ reserve %= 4; ++ } ++ ++ return reserve + AG71XX_RX_PKT_RESERVE; +} + -+/* Register offsets */ -+#define AG71XX_REG_MAC_CFG1 0x0000 -+#define AG71XX_REG_MAC_CFG2 0x0004 -+#define AG71XX_REG_MAC_IPG 0x0008 -+#define AG71XX_REG_MAC_HDX 0x000c -+#define AG71XX_REG_MAC_MFL 0x0010 -+#define AG71XX_REG_MII_CFG 0x0020 -+#define AG71XX_REG_MII_CMD 0x0024 -+#define AG71XX_REG_MII_ADDR 0x0028 -+#define AG71XX_REG_MII_CTRL 0x002c -+#define AG71XX_REG_MII_STATUS 0x0030 -+#define AG71XX_REG_MII_IND 0x0034 -+#define AG71XX_REG_MAC_IFCTL 0x0038 -+#define AG71XX_REG_MAC_ADDR1 0x0040 -+#define AG71XX_REG_MAC_ADDR2 0x0044 -+#define AG71XX_REG_FIFO_CFG0 0x0048 -+#define AG71XX_REG_FIFO_CFG1 0x004c -+#define AG71XX_REG_FIFO_CFG2 0x0050 -+#define AG71XX_REG_FIFO_CFG3 0x0054 -+#define AG71XX_REG_FIFO_CFG4 0x0058 -+#define AG71XX_REG_FIFO_CFG5 0x005c -+#define AG71XX_REG_FIFO_RAM0 0x0060 -+#define AG71XX_REG_FIFO_RAM1 0x0064 -+#define AG71XX_REG_FIFO_RAM2 0x0068 -+#define AG71XX_REG_FIFO_RAM3 0x006c -+#define AG71XX_REG_FIFO_RAM4 0x0070 -+#define AG71XX_REG_FIFO_RAM5 0x0074 -+#define AG71XX_REG_FIFO_RAM6 0x0078 -+#define AG71XX_REG_FIFO_RAM7 0x007c + -+#define AG71XX_REG_TX_CTRL 0x0180 -+#define AG71XX_REG_TX_DESC 0x0184 -+#define AG71XX_REG_TX_STATUS 0x0188 -+#define AG71XX_REG_RX_CTRL 0x018c -+#define AG71XX_REG_RX_DESC 0x0190 -+#define AG71XX_REG_RX_STATUS 0x0194 -+#define AG71XX_REG_INT_ENABLE 0x0198 -+#define AG71XX_REG_INT_STATUS 0x019c ++static int ag71xx_ring_rx_init(struct ag71xx *ag) ++{ ++ struct ag71xx_ring *ring = &ag->rx_ring; ++ unsigned int reserve = ag71xx_rx_reserve(ag); ++ unsigned int i; ++ int ret; + -+#define AG71XX_REG_FIFO_DEPTH 0x01a8 -+#define AG71XX_REG_RX_SM 0x01b0 -+#define AG71XX_REG_TX_SM 0x01b4 ++ ret = 0; ++ for (i = 0; i < ring->size; i++) { ++ ring->buf[i].desc->next = (u32) (ring->descs_dma + ++ ring->desc_size * ((i + 1) % ring->size)); + -+#define MAC_CFG1_TXE BIT(0) /* Tx Enable */ -+#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */ -+#define MAC_CFG1_RXE BIT(2) /* Rx Enable */ -+#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */ -+#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */ -+#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */ -+#define MAC_CFG1_LB BIT(8) /* Loopback mode */ -+#define MAC_CFG1_SR BIT(31) /* Soft Reset */ ++ DBG("ag71xx: RX desc at %p, next is %08x\n", ++ ring->buf[i].desc, ++ ring->buf[i].desc->next); ++ } + -+#define MAC_CFG2_FDX BIT(0) -+#define MAC_CFG2_CRC_EN BIT(1) -+#define MAC_CFG2_PAD_CRC_EN BIT(2) -+#define MAC_CFG2_LEN_CHECK BIT(4) -+#define MAC_CFG2_HUGE_FRAME_EN BIT(5) -+#define MAC_CFG2_IF_1000 BIT(9) -+#define MAC_CFG2_IF_10_100 BIT(8) ++ for (i = 0; i < ring->size; i++) { ++ struct sk_buff *skb; ++ dma_addr_t dma_addr; + -+#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */ -+#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */ -+#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */ -+#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */ -+#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */ -+#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \ -+ | FIFO_CFG0_TXS | FIFO_CFG0_TXF) ++ skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); ++ if (!skb) { ++ ret = -ENOMEM; ++ break; ++ } + -+#define FIFO_CFG0_ENABLE_SHIFT 8 ++ skb->dev = ag->dev; ++ skb_reserve(skb, reserve); + -+#define FIFO_CFG4_DE BIT(0) /* Drop Event */ -+#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */ -+#define FIFO_CFG4_FC BIT(2) /* False Carrier */ -+#define FIFO_CFG4_CE BIT(3) /* Code Error */ -+#define FIFO_CFG4_CR BIT(4) /* CRC error */ -+#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */ -+#define FIFO_CFG4_LO BIT(6) /* Length out of range */ -+#define FIFO_CFG4_OK BIT(7) /* Packet is OK */ -+#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */ -+#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */ -+#define FIFO_CFG4_DR BIT(10) /* Dribble */ -+#define FIFO_CFG4_LE BIT(11) /* Long Event */ -+#define FIFO_CFG4_CF BIT(12) /* Control Frame */ -+#define FIFO_CFG4_PF BIT(13) /* Pause Frame */ -+#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */ -+#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */ -+#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */ -+#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */ ++ dma_addr = dma_map_single(&ag->dev->dev, skb->data, ++ AG71XX_RX_PKT_SIZE, ++ DMA_FROM_DEVICE); ++ ring->buf[i].skb = skb; ++ ring->buf[i].dma_addr = dma_addr; ++ ring->buf[i].desc->data = (u32) dma_addr; ++ ring->buf[i].desc->ctrl = DESC_EMPTY; ++ } + -+#define FIFO_CFG5_DE BIT(0) /* Drop Event */ -+#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */ -+#define FIFO_CFG5_FC BIT(2) /* False Carrier */ -+#define FIFO_CFG5_CE BIT(3) /* Code Error */ -+#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */ -+#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */ -+#define FIFO_CFG5_OK BIT(6) /* Packet is OK */ -+#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */ -+#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */ -+#define FIFO_CFG5_DR BIT(9) /* Dribble */ -+#define FIFO_CFG5_CF BIT(10) /* Control Frame */ -+#define FIFO_CFG5_PF BIT(11) /* Pause Frame */ -+#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */ -+#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */ -+#define FIFO_CFG5_LE BIT(14) /* Long Event */ -+#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */ -+#define FIFO_CFG5_16 BIT(16) /* unknown */ -+#define FIFO_CFG5_17 BIT(17) /* unknown */ -+#define FIFO_CFG5_SF BIT(18) /* Short Frame */ -+#define FIFO_CFG5_BM BIT(19) /* Byte Mode */ ++ /* flush descriptors */ ++ wmb(); + -+#define AG71XX_INT_TX_PS BIT(0) -+#define AG71XX_INT_TX_UR BIT(1) -+#define AG71XX_INT_TX_BE BIT(3) -+#define AG71XX_INT_RX_PR BIT(4) -+#define AG71XX_INT_RX_OF BIT(6) -+#define AG71XX_INT_RX_BE BIT(7) ++ ring->curr = 0; ++ ring->dirty = 0; + -+#define MAC_IFCTL_SPEED BIT(16) ++ return ret; ++} + -+#define MII_CFG_CLK_DIV_4 0 -+#define MII_CFG_CLK_DIV_6 2 -+#define MII_CFG_CLK_DIV_8 3 -+#define MII_CFG_CLK_DIV_10 4 -+#define MII_CFG_CLK_DIV_14 5 -+#define MII_CFG_CLK_DIV_20 6 -+#define MII_CFG_CLK_DIV_28 7 -+#define MII_CFG_RESET BIT(31) ++static int ag71xx_ring_rx_refill(struct ag71xx *ag) ++{ ++ struct ag71xx_ring *ring = &ag->rx_ring; ++ unsigned int reserve = ag71xx_rx_reserve(ag); ++ unsigned int count; + -+#define MII_CMD_WRITE 0x0 -+#define MII_CMD_READ 0x1 -+#define MII_ADDR_SHIFT 8 -+#define MII_IND_BUSY BIT(0) -+#define MII_IND_INVALID BIT(2) ++ count = 0; ++ for (; ring->curr - ring->dirty > 0; ring->dirty++) { ++ unsigned int i; + -+#define TX_CTRL_TXE BIT(0) /* Tx Enable */ ++ i = ring->dirty % ring->size; + -+#define TX_STATUS_PS BIT(0) /* Packet Sent */ -+#define TX_STATUS_UR BIT(1) /* Tx Underrun */ -+#define TX_STATUS_BE BIT(3) /* Bus Error */ ++ if (ring->buf[i].skb == NULL) { ++ dma_addr_t dma_addr; ++ struct sk_buff *skb; + -+#define RX_CTRL_RXE BIT(0) /* Rx Enable */ ++ skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); ++ if (skb == NULL) ++ break; + -+#define RX_STATUS_PR BIT(0) /* Packet Received */ -+#define RX_STATUS_OF BIT(2) /* Rx Overflow */ -+#define RX_STATUS_BE BIT(3) /* Bus Error */ ++ skb_reserve(skb, reserve); ++ skb->dev = ag->dev; + -+#define MII_CTRL_IF_MASK 3 -+#define MII_CTRL_SPEED_SHIFT 4 -+#define MII_CTRL_SPEED_MASK 3 -+#define MII_CTRL_SPEED_10 0 -+#define MII_CTRL_SPEED_100 1 -+#define MII_CTRL_SPEED_1000 2 ++ dma_addr = dma_map_single(&ag->dev->dev, skb->data, ++ AG71XX_RX_PKT_SIZE, ++ DMA_FROM_DEVICE); + -+static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg) -+{ -+ switch (reg) { -+ case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: -+ case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: -+ case AG71XX_REG_MII_CFG: -+ break; ++ ring->buf[i].skb = skb; ++ ring->buf[i].dma_addr = dma_addr; ++ ring->buf[i].desc->data = (u32) dma_addr; ++ } + -+ default: -+ BUG(); ++ ring->buf[i].desc->ctrl = DESC_EMPTY; ++ count++; + } -+} -+ -+static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) -+{ -+ ag71xx_check_reg_offset(ag, reg); + -+ __raw_writel(value, ag->mac_base + reg); -+ /* flush write */ -+ (void) __raw_readl(ag->mac_base + reg); -+} ++ /* flush descriptors */ ++ wmb(); + -+static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) -+{ -+ ag71xx_check_reg_offset(ag, reg); ++ DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count); + -+ return __raw_readl(ag->mac_base + reg); ++ return count; +} + -+static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) ++static int ag71xx_rings_init(struct ag71xx *ag) +{ -+ void __iomem *r; -+ -+ ag71xx_check_reg_offset(ag, reg); ++ int ret; + -+ r = ag->mac_base + reg; -+ __raw_writel(__raw_readl(r) | mask, r); -+ /* flush write */ -+ (void)__raw_readl(r); -+} ++ ret = ag71xx_ring_alloc(&ag->tx_ring); ++ if (ret) ++ return ret; + -+static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) -+{ -+ void __iomem *r; ++ ag71xx_ring_tx_init(ag); + -+ ag71xx_check_reg_offset(ag, reg); ++ ret = ag71xx_ring_alloc(&ag->rx_ring); ++ if (ret) ++ return ret; + -+ r = ag->mac_base + reg; -+ __raw_writel(__raw_readl(r) & ~mask, r); -+ /* flush write */ -+ (void) __raw_readl(r); ++ ret = ag71xx_ring_rx_init(ag); ++ return ret; +} + -+static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) ++static void ag71xx_rings_cleanup(struct ag71xx *ag) +{ -+ ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints); ++ ag71xx_ring_rx_clean(ag); ++ ag71xx_ring_free(&ag->rx_ring); ++ ++ ag71xx_ring_tx_clean(ag); ++ ag71xx_ring_free(&ag->tx_ring); +} + -+static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints) ++static unsigned char *ag71xx_speed_str(struct ag71xx *ag) +{ -+ ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints); ++ switch (ag->speed) { ++ case SPEED_1000: ++ return "1000"; ++ case SPEED_100: ++ return "100"; ++ case SPEED_10: ++ return "10"; ++ } ++ ++ return "?"; +} + -+static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value) ++static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) +{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ u32 t; + -+ if (pdata->is_ar724x) -+ return; ++ t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16) ++ | (((u32) mac[3]) << 8) | ((u32) mac[2]); + -+ __raw_writel(value, ag->mii_ctrl); ++ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t); + -+ /* flush write */ -+ __raw_readl(ag->mii_ctrl); ++ t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16); ++ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); +} + -+static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag) ++static void ag71xx_dma_reset(struct ag71xx *ag) +{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ u32 val; ++ int i; + -+ if (pdata->is_ar724x) -+ return 0xffffffff; ++ ag71xx_dump_dma_regs(ag); + -+ return __raw_readl(ag->mii_ctrl); -+} ++ /* stop RX and TX */ ++ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); ++ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); + -+static inline void ag71xx_mii_ctrl_set_if(struct ag71xx *ag, -+ unsigned int mii_if) -+{ -+ u32 t; ++ /* ++ * give the hardware some time to really stop all rx/tx activity ++ * clearing the descriptors too early causes random memory corruption ++ */ ++ mdelay(1); + -+ t = ag71xx_mii_ctrl_rr(ag); -+ t &= ~(MII_CTRL_IF_MASK); -+ t |= (mii_if & MII_CTRL_IF_MASK); -+ ag71xx_mii_ctrl_wr(ag, t); -+} ++ /* clear descriptor addresses */ ++ ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->stop_desc_dma); ++ ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->stop_desc_dma); + -+static inline void ag71xx_mii_ctrl_set_speed(struct ag71xx *ag, -+ unsigned int speed) -+{ -+ u32 t; ++ /* clear pending RX/TX interrupts */ ++ for (i = 0; i < 256; i++) { ++ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); ++ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); ++ } + -+ t = ag71xx_mii_ctrl_rr(ag); -+ t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT); -+ t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT; -+ ag71xx_mii_ctrl_wr(ag, t); -+} ++ /* clear pending errors */ ++ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); ++ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); + -+#ifdef CONFIG_AG71XX_AR8216_SUPPORT -+void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); -+int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, -+ int pktlen); -+static inline int ag71xx_has_ar8216(struct ag71xx *ag) -+{ -+ return ag71xx_get_pdata(ag)->has_ar8216; -+} -+#else -+static inline void ag71xx_add_ar8216_header(struct ag71xx *ag, -+ struct sk_buff *skb) -+{ ++ val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); ++ if (val) ++ printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n", ++ ag->dev->name, val); ++ ++ val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); ++ ++ /* mask out reserved bits */ ++ val &= ~0xff000000; ++ ++ if (val) ++ printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n", ++ ag->dev->name, val); ++ ++ ag71xx_dump_dma_regs(ag); +} + -+static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag, -+ struct sk_buff *skb, -+ int pktlen) ++#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \ ++ MAC_CFG1_SRX | MAC_CFG1_STX) ++ ++#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT) ++ ++#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \ ++ FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \ ++ FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \ ++ FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \ ++ FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \ ++ FIFO_CFG4_VT) ++ ++#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \ ++ FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \ ++ FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \ ++ FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \ ++ FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \ ++ FIFO_CFG5_17 | FIFO_CFG5_SF) ++ ++static void ag71xx_hw_stop(struct ag71xx *ag) +{ -+ return 0; ++ /* disable all interrupts and stop the rx/tx engine */ ++ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0); ++ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); ++ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); +} -+static inline int ag71xx_has_ar8216(struct ag71xx *ag) ++ ++static void ag71xx_hw_setup(struct ag71xx *ag) +{ -+ return 0; -+} -+#endif ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + -+#ifdef CONFIG_AG71XX_DEBUG_FS -+int ag71xx_debugfs_root_init(void); -+void ag71xx_debugfs_root_exit(void); -+int ag71xx_debugfs_init(struct ag71xx *ag); -+void ag71xx_debugfs_exit(struct ag71xx *ag); -+void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status); -+void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx); -+#else -+static inline int ag71xx_debugfs_root_init(void) { return 0; } -+static inline void ag71xx_debugfs_root_exit(void) {} -+static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; } -+static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {} -+static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, -+ u32 status) {} -+static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, -+ int rx, int tx) {} -+#endif /* CONFIG_AG71XX_DEBUG_FS */ ++ /* setup MAC configuration registers */ ++ ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT); + -+void ag71xx_ar7240_start(struct ag71xx *ag); -+void ag71xx_ar7240_stop(struct ag71xx *ag); -+int ag71xx_ar7240_init(struct ag71xx *ag); -+void ag71xx_ar7240_cleanup(struct ag71xx *ag); ++ ag71xx_sb(ag, AG71XX_REG_MAC_CFG2, ++ MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK); + -+int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg); -+void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val); ++ /* setup max frame length */ ++ ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN); + -+u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, -+ unsigned reg_addr); -+int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, -+ unsigned reg_addr, u16 reg_val); ++ /* setup MII interface type */ ++ ag71xx_mii_ctrl_set_if(ag, pdata->mii_if); + -+#endif /* _AG71XX_H */ -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_main.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_main.c 2011-08-22 07:40:12.160480642 +0200 -@@ -0,0 +1,1291 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ ++ /* setup FIFO configuration registers */ ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT); ++ if (pdata->is_ar724x) { ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, pdata->fifo_cfg1); ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, pdata->fifo_cfg2); ++ } else { ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); ++ } ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT); ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT); ++} + -+#include "ag71xx.h" ++static void ag71xx_hw_init(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ u32 reset_mask = pdata->reset_bit; + -+#define AG71XX_DEFAULT_MSG_ENABLE \ -+ (NETIF_MSG_DRV \ -+ | NETIF_MSG_PROBE \ -+ | NETIF_MSG_LINK \ -+ | NETIF_MSG_TIMER \ -+ | NETIF_MSG_IFDOWN \ -+ | NETIF_MSG_IFUP \ -+ | NETIF_MSG_RX_ERR \ -+ | NETIF_MSG_TX_ERR) ++ ag71xx_hw_stop(ag); + -+static int ag71xx_msg_level = -1; ++ if (pdata->is_ar724x) { ++ u32 reset_phy = reset_mask; + -+module_param_named(msg_level, ag71xx_msg_level, int, 0); -+MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)"); ++ reset_phy &= RESET_MODULE_GE0_PHY | RESET_MODULE_GE1_PHY; ++ reset_mask &= ~(RESET_MODULE_GE0_PHY | RESET_MODULE_GE1_PHY); + -+static void ag71xx_dump_dma_regs(struct ag71xx *ag) ++ ar71xx_device_stop(reset_phy); ++ mdelay(50); ++ ar71xx_device_start(reset_phy); ++ mdelay(200); ++ } ++ ++ ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); ++ udelay(20); ++ ++ ar71xx_device_stop(reset_mask); ++ mdelay(100); ++ ar71xx_device_start(reset_mask); ++ mdelay(200); ++ ++ ag71xx_hw_setup(ag); ++ ++ ag71xx_dma_reset(ag); ++} ++ ++static void ag71xx_fast_reset(struct ag71xx *ag) +{ -+ DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_TX_CTRL), -+ ag71xx_rr(ag, AG71XX_REG_TX_DESC), -+ ag71xx_rr(ag, AG71XX_REG_TX_STATUS)); ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ struct net_device *dev = ag->dev; ++ u32 reset_mask = pdata->reset_bit; ++ u32 rx_ds, tx_ds; ++ u32 mii_reg; + -+ DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_RX_CTRL), -+ ag71xx_rr(ag, AG71XX_REG_RX_DESC), -+ ag71xx_rr(ag, AG71XX_REG_RX_STATUS)); ++ reset_mask &= RESET_MODULE_GE0_MAC | RESET_MODULE_GE1_MAC; ++ ++ mii_reg = ag71xx_rr(ag, AG71XX_REG_MII_CFG); ++ rx_ds = ag71xx_rr(ag, AG71XX_REG_RX_DESC); ++ tx_ds = ag71xx_rr(ag, AG71XX_REG_TX_DESC); ++ ++ ar71xx_device_stop(reset_mask); ++ udelay(10); ++ ar71xx_device_start(reset_mask); ++ udelay(10); ++ ++ ag71xx_dma_reset(ag); ++ ag71xx_hw_setup(ag); ++ ++ ag71xx_wr(ag, AG71XX_REG_RX_DESC, rx_ds); ++ ag71xx_wr(ag, AG71XX_REG_TX_DESC, tx_ds); ++ ag71xx_wr(ag, AG71XX_REG_MII_CFG, mii_reg); ++ ++ ag71xx_hw_set_macaddr(ag, dev->dev_addr); +} + -+static void ag71xx_dump_regs(struct ag71xx *ag) ++static void ag71xx_hw_start(struct ag71xx *ag) +{ -+ DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG1), -+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), -+ ag71xx_rr(ag, AG71XX_REG_MAC_IPG), -+ ag71xx_rr(ag, AG71XX_REG_MAC_HDX), -+ ag71xx_rr(ag, AG71XX_REG_MAC_MFL)); -+ DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), -+ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1), -+ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2)); -+ DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n", ++ /* start RX engine */ ++ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); ++ ++ /* enable interrupts */ ++ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT); ++} ++ ++void ag71xx_link_adjust(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ u32 cfg2; ++ u32 ifctl; ++ u32 fifo5; ++ u32 mii_speed; ++ ++ if (!ag->link) { ++ ag71xx_hw_stop(ag); ++ netif_carrier_off(ag->dev); ++ if (netif_msg_link(ag)) ++ printk(KERN_INFO "%s: link down\n", ag->dev->name); ++ return; ++ } ++ ++ if (pdata->is_ar724x) ++ ag71xx_fast_reset(ag); ++ ++ cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); ++ cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); ++ cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; ++ ++ ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); ++ ifctl &= ~(MAC_IFCTL_SPEED); ++ ++ fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); ++ fifo5 &= ~FIFO_CFG5_BM; ++ ++ switch (ag->speed) { ++ case SPEED_1000: ++ mii_speed = MII_CTRL_SPEED_1000; ++ cfg2 |= MAC_CFG2_IF_1000; ++ fifo5 |= FIFO_CFG5_BM; ++ break; ++ case SPEED_100: ++ mii_speed = MII_CTRL_SPEED_100; ++ cfg2 |= MAC_CFG2_IF_10_100; ++ ifctl |= MAC_IFCTL_SPEED; ++ break; ++ case SPEED_10: ++ mii_speed = MII_CTRL_SPEED_10; ++ cfg2 |= MAC_CFG2_IF_10_100; ++ break; ++ default: ++ BUG(); ++ return; ++ } ++ ++ if (pdata->is_ar91xx) ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); ++ else if (pdata->is_ar724x) ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3); ++ else ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff); ++ ++ if (pdata->set_pll) ++ pdata->set_pll(ag->speed); ++ ++ ag71xx_mii_ctrl_set_speed(ag, mii_speed); ++ ++ ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); ++ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); ++ ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); ++ ag71xx_hw_start(ag); ++ ++ netif_carrier_on(ag->dev); ++ if (netif_msg_link(ag)) ++ printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n", ++ ag->dev->name, ++ ag71xx_speed_str(ag), ++ (DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); ++ ++ DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); -+ DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n", ++ ++ DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); -+} + -+static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr) -+{ -+ DBG("%s: %s intr=%08x %s%s%s%s%s%s\n", -+ ag->dev->name, label, intr, -+ (intr & AG71XX_INT_TX_PS) ? "TXPS " : "", -+ (intr & AG71XX_INT_TX_UR) ? "TXUR " : "", -+ (intr & AG71XX_INT_TX_BE) ? "TXBE " : "", -+ (intr & AG71XX_INT_RX_PR) ? "RXPR " : "", -+ (intr & AG71XX_INT_RX_OF) ? "RXOF " : "", -+ (intr & AG71XX_INT_RX_BE) ? "RXBE " : ""); ++ DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", ++ ag->dev->name, ++ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), ++ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), ++ ag71xx_mii_ctrl_rr(ag)); +} + -+static void ag71xx_ring_free(struct ag71xx_ring *ring) ++static int ag71xx_open(struct net_device *dev) +{ -+ kfree(ring->buf); -+ -+ if (ring->descs_cpu) -+ dma_free_coherent(NULL, ring->size * ring->desc_size, -+ ring->descs_cpu, ring->descs_dma); -+} ++ struct ag71xx *ag = netdev_priv(dev); ++ int ret; + -+static int ag71xx_ring_alloc(struct ag71xx_ring *ring) -+{ -+ int err; -+ int i; ++ ret = ag71xx_rings_init(ag); ++ if (ret) ++ goto err; + -+ ring->desc_size = sizeof(struct ag71xx_desc); -+ if (ring->desc_size % cache_line_size()) { -+ DBG("ag71xx: ring %p, desc size %u rounded to %u\n", -+ ring, ring->desc_size, -+ roundup(ring->desc_size, cache_line_size())); -+ ring->desc_size = roundup(ring->desc_size, cache_line_size()); -+ } ++ napi_enable(&ag->napi); + -+ ring->descs_cpu = dma_alloc_coherent(NULL, ring->size * ring->desc_size, -+ &ring->descs_dma, GFP_ATOMIC); -+ if (!ring->descs_cpu) { -+ err = -ENOMEM; -+ goto err; -+ } ++ netif_carrier_off(dev); ++ ag71xx_phy_start(ag); + ++ ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma); ++ ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma); + -+ ring->buf = kzalloc(ring->size * sizeof(*ring->buf), GFP_KERNEL); -+ if (!ring->buf) { -+ err = -ENOMEM; -+ goto err; -+ } ++ ag71xx_hw_set_macaddr(ag, dev->dev_addr); + -+ for (i = 0; i < ring->size; i++) { -+ int idx = i * ring->desc_size; -+ ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[idx]; -+ DBG("ag71xx: ring %p, desc %d at %p\n", -+ ring, i, ring->buf[i].desc); -+ } ++ netif_start_queue(dev); + + return 0; + +err: -+ return err; ++ ag71xx_rings_cleanup(ag); ++ return ret; +} + -+static void ag71xx_ring_tx_clean(struct ag71xx *ag) ++static int ag71xx_stop(struct net_device *dev) +{ -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ struct net_device *dev = ag->dev; ++ struct ag71xx *ag = netdev_priv(dev); ++ unsigned long flags; + -+ while (ring->curr != ring->dirty) { -+ u32 i = ring->dirty % ring->size; ++ netif_carrier_off(dev); ++ ag71xx_phy_stop(ag); + -+ if (!ag71xx_desc_empty(ring->buf[i].desc)) { -+ ring->buf[i].desc->ctrl = 0; -+ dev->stats.tx_errors++; -+ } ++ spin_lock_irqsave(&ag->lock, flags); + -+ if (ring->buf[i].skb) -+ dev_kfree_skb_any(ring->buf[i].skb); ++ netif_stop_queue(dev); + -+ ring->buf[i].skb = NULL; ++ ag71xx_hw_stop(ag); ++ ag71xx_dma_reset(ag); + -+ ring->dirty++; -+ } ++ napi_disable(&ag->napi); ++ del_timer_sync(&ag->oom_timer); + -+ /* flush descriptors */ -+ wmb(); ++ spin_unlock_irqrestore(&ag->lock, flags); + ++ ag71xx_rings_cleanup(ag); ++ ++ return 0; +} + -+static void ag71xx_ring_tx_init(struct ag71xx *ag) ++static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb, ++ struct net_device *dev) +{ ++ struct ag71xx *ag = netdev_priv(dev); + struct ag71xx_ring *ring = &ag->tx_ring; -+ int i; ++ struct ag71xx_desc *desc; ++ dma_addr_t dma_addr; ++ int i; + -+ for (i = 0; i < ring->size; i++) { -+ ring->buf[i].desc->next = (u32) (ring->descs_dma + -+ ring->desc_size * ((i + 1) % ring->size)); ++ i = ring->curr % ring->size; ++ desc = ring->buf[i].desc; + -+ ring->buf[i].desc->ctrl = DESC_EMPTY; -+ ring->buf[i].skb = NULL; ++ if (!ag71xx_desc_empty(desc)) ++ goto err_drop; ++ ++ if (ag71xx_has_ar8216(ag)) ++ ag71xx_add_ar8216_header(ag, skb); ++ ++ if (skb->len <= 0) { ++ DBG("%s: packet len is too small\n", ag->dev->name); ++ goto err_drop; + } + -+ /* flush descriptors */ -+ wmb(); ++ dma_addr = dma_map_single(&dev->dev, skb->data, skb->len, ++ DMA_TO_DEVICE); + -+ ring->curr = 0; -+ ring->dirty = 0; -+} ++ ring->buf[i].skb = skb; ++ ring->buf[i].timestamp = jiffies; + -+static void ag71xx_ring_rx_clean(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ int i; ++ /* setup descriptor fields */ ++ desc->data = (u32) dma_addr; ++ desc->ctrl = (skb->len & DESC_PKTLEN_M); + -+ if (!ring->buf) -+ return; ++ /* flush descriptor */ ++ wmb(); + -+ for (i = 0; i < ring->size; i++) -+ if (ring->buf[i].skb) { -+ dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, -+ AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); -+ kfree_skb(ring->buf[i].skb); -+ } -+} ++ ring->curr++; ++ if (ring->curr == (ring->dirty + ring->size)) { ++ DBG("%s: tx queue full\n", ag->dev->name); ++ netif_stop_queue(dev); ++ } + -+static int ag71xx_rx_reserve(struct ag71xx *ag) -+{ -+ int reserve = 0; ++ DBG("%s: packet injected into TX queue\n", ag->dev->name); + -+ if (ag71xx_get_pdata(ag)->is_ar724x) { -+ if (!ag71xx_has_ar8216(ag)) -+ reserve = 2; ++ /* enable TX engine */ ++ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); + -+ if (ag->phy_dev) -+ reserve += 4 - (ag->phy_dev->pkt_align % 4); ++ return NETDEV_TX_OK; + -+ reserve %= 4; -+ } ++err_drop: ++ dev->stats.tx_dropped++; + -+ return reserve + AG71XX_RX_PKT_RESERVE; ++ dev_kfree_skb(skb); ++ return NETDEV_TX_OK; +} + -+ -+static int ag71xx_ring_rx_init(struct ag71xx *ag) ++static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ unsigned int reserve = ag71xx_rx_reserve(ag); -+ unsigned int i; ++ struct ag71xx *ag = netdev_priv(dev); + int ret; + -+ ret = 0; -+ for (i = 0; i < ring->size; i++) { -+ ring->buf[i].desc->next = (u32) (ring->descs_dma + -+ ring->desc_size * ((i + 1) % ring->size)); ++ switch (cmd) { ++ case SIOCETHTOOL: ++ if (ag->phy_dev == NULL) ++ break; + -+ DBG("ag71xx: RX desc at %p, next is %08x\n", -+ ring->buf[i].desc, -+ ring->buf[i].desc->next); -+ } ++ spin_lock_irq(&ag->lock); ++ ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data); ++ spin_unlock_irq(&ag->lock); ++ return ret; + -+ for (i = 0; i < ring->size; i++) { -+ struct sk_buff *skb; -+ dma_addr_t dma_addr; ++ case SIOCSIFHWADDR: ++ if (copy_from_user ++ (dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr))) ++ return -EFAULT; ++ return 0; + -+ skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); -+ if (!skb) { -+ ret = -ENOMEM; ++ case SIOCGIFHWADDR: ++ if (copy_to_user ++ (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr))) ++ return -EFAULT; ++ return 0; ++ ++ case SIOCGMIIPHY: ++ case SIOCGMIIREG: ++ case SIOCSMIIREG: ++ if (ag->phy_dev == NULL) + break; -+ } + -+ skb->dev = ag->dev; -+ skb_reserve(skb, reserve); ++ return phy_mii_ioctl(ag->phy_dev, ifr, cmd); + -+ dma_addr = dma_map_single(&ag->dev->dev, skb->data, -+ AG71XX_RX_PKT_SIZE, -+ DMA_FROM_DEVICE); -+ ring->buf[i].skb = skb; -+ ring->buf[i].dma_addr = dma_addr; -+ ring->buf[i].desc->data = (u32) dma_addr; -+ ring->buf[i].desc->ctrl = DESC_EMPTY; ++ default: ++ break; + } + -+ /* flush descriptors */ -+ wmb(); ++ return -EOPNOTSUPP; ++} + -+ ring->curr = 0; -+ ring->dirty = 0; ++static void ag71xx_oom_timer_handler(unsigned long data) ++{ ++ struct net_device *dev = (struct net_device *) data; ++ struct ag71xx *ag = netdev_priv(dev); + -+ return ret; ++ napi_schedule(&ag->napi); +} + -+static int ag71xx_ring_rx_refill(struct ag71xx *ag) ++static void ag71xx_tx_timeout(struct net_device *dev) +{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ unsigned int reserve = ag71xx_rx_reserve(ag); -+ unsigned int count; ++ struct ag71xx *ag = netdev_priv(dev); + -+ count = 0; -+ for (; ring->curr - ring->dirty > 0; ring->dirty++) { -+ unsigned int i; ++ if (netif_msg_tx_err(ag)) ++ printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name); + -+ i = ring->dirty % ring->size; ++ schedule_work(&ag->restart_work); ++} + -+ if (ring->buf[i].skb == NULL) { -+ dma_addr_t dma_addr; -+ struct sk_buff *skb; ++static void ag71xx_restart_work_func(struct work_struct *work) ++{ ++ struct ag71xx *ag = container_of(work, struct ag71xx, restart_work); + -+ skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); -+ if (skb == NULL) -+ break; ++ if (ag71xx_get_pdata(ag)->is_ar724x) { ++ ag->link = 0; ++ ag71xx_link_adjust(ag); ++ return; ++ } + -+ skb_reserve(skb, reserve); -+ skb->dev = ag->dev; ++ ag71xx_stop(ag->dev); ++ ag71xx_open(ag->dev); ++} + -+ dma_addr = dma_map_single(&ag->dev->dev, skb->data, -+ AG71XX_RX_PKT_SIZE, -+ DMA_FROM_DEVICE); ++static bool ag71xx_check_dma_stuck(struct ag71xx *ag, unsigned long timestamp) ++{ ++ u32 rx_sm, tx_sm, rx_fd; + -+ ring->buf[i].skb = skb; -+ ring->buf[i].dma_addr = dma_addr; -+ ring->buf[i].desc->data = (u32) dma_addr; -+ } ++ if (likely(time_before(jiffies, timestamp + HZ/10))) ++ return false; + -+ ring->buf[i].desc->ctrl = DESC_EMPTY; -+ count++; -+ } ++ if (!netif_carrier_ok(ag->dev)) ++ return false; + -+ /* flush descriptors */ -+ wmb(); ++ rx_sm = ag71xx_rr(ag, AG71XX_REG_RX_SM); ++ if ((rx_sm & 0x7) == 0x3 && ((rx_sm >> 4) & 0x7) == 0x6) ++ return true; + -+ DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count); ++ tx_sm = ag71xx_rr(ag, AG71XX_REG_TX_SM); ++ rx_fd = ag71xx_rr(ag, AG71XX_REG_FIFO_DEPTH); ++ if (((tx_sm >> 4) & 0x7) == 0 && ((rx_sm & 0x7) == 0) && ++ ((rx_sm >> 4) & 0x7) == 0 && rx_fd == 0) ++ return true; + -+ return count; ++ return false; +} + -+static int ag71xx_rings_init(struct ag71xx *ag) ++static int ag71xx_tx_packets(struct ag71xx *ag) +{ -+ int ret; ++ struct ag71xx_ring *ring = &ag->tx_ring; ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ int sent; + -+ ret = ag71xx_ring_alloc(&ag->tx_ring); -+ if (ret) -+ return ret; ++ DBG("%s: processing TX ring\n", ag->dev->name); + -+ ag71xx_ring_tx_init(ag); ++ sent = 0; ++ while (ring->dirty != ring->curr) { ++ unsigned int i = ring->dirty % ring->size; ++ struct ag71xx_desc *desc = ring->buf[i].desc; ++ struct sk_buff *skb = ring->buf[i].skb; + -+ ret = ag71xx_ring_alloc(&ag->rx_ring); -+ if (ret) -+ return ret; ++ if (!ag71xx_desc_empty(desc)) { ++ if (pdata->is_ar7240 && ++ ag71xx_check_dma_stuck(ag, ring->buf[i].timestamp)) ++ schedule_work(&ag->restart_work); ++ break; ++ } + -+ ret = ag71xx_ring_rx_init(ag); -+ return ret; -+} ++ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); + -+static void ag71xx_rings_cleanup(struct ag71xx *ag) -+{ -+ ag71xx_ring_rx_clean(ag); -+ ag71xx_ring_free(&ag->rx_ring); ++ ag->dev->stats.tx_bytes += skb->len; ++ ag->dev->stats.tx_packets++; + -+ ag71xx_ring_tx_clean(ag); -+ ag71xx_ring_free(&ag->tx_ring); -+} ++ dev_kfree_skb_any(skb); ++ ring->buf[i].skb = NULL; + -+static unsigned char *ag71xx_speed_str(struct ag71xx *ag) -+{ -+ switch (ag->speed) { -+ case SPEED_1000: -+ return "1000"; -+ case SPEED_100: -+ return "100"; -+ case SPEED_10: -+ return "10"; ++ ring->dirty++; ++ sent++; + } + -+ return "?"; -+} ++ DBG("%s: %d packets sent out\n", ag->dev->name, sent); + -+static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) -+{ -+ u32 t; -+ -+ t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16) -+ | (((u32) mac[3]) << 8) | ((u32) mac[2]); -+ -+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t); ++ if ((ring->curr - ring->dirty) < (ring->size * 3) / 4) ++ netif_wake_queue(ag->dev); + -+ t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16); -+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); ++ return sent; +} + -+static void ag71xx_dma_reset(struct ag71xx *ag) ++static int ag71xx_rx_packets(struct ag71xx *ag, int limit) +{ -+ u32 val; -+ int i; ++ struct net_device *dev = ag->dev; ++ struct ag71xx_ring *ring = &ag->rx_ring; ++ int done = 0; + -+ ag71xx_dump_dma_regs(ag); ++ DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n", ++ dev->name, limit, ring->curr, ring->dirty); + -+ /* stop RX and TX */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); -+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); ++ while (done < limit) { ++ unsigned int i = ring->curr % ring->size; ++ struct ag71xx_desc *desc = ring->buf[i].desc; ++ struct sk_buff *skb; ++ int pktlen; ++ int err = 0; + -+ /* -+ * give the hardware some time to really stop all rx/tx activity -+ * clearing the descriptors too early causes random memory corruption -+ */ -+ mdelay(1); ++ if (ag71xx_desc_empty(desc)) ++ break; + -+ /* clear descriptor addresses */ -+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->stop_desc_dma); -+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->stop_desc_dma); ++ if ((ring->dirty + ring->size) == ring->curr) { ++ ag71xx_assert(0); ++ break; ++ } + -+ /* clear pending RX/TX interrupts */ -+ for (i = 0; i < 256; i++) { + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); -+ } -+ -+ /* clear pending errors */ -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); + -+ val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); -+ if (val) -+ printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n", -+ ag->dev->name, val); ++ skb = ring->buf[i].skb; ++ pktlen = ag71xx_desc_pktlen(desc); ++ pktlen -= ETH_FCS_LEN; + -+ val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); ++ dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, ++ AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); + -+ /* mask out reserved bits */ -+ val &= ~0xff000000; ++ dev->last_rx = jiffies; ++ dev->stats.rx_packets++; ++ dev->stats.rx_bytes += pktlen; + -+ if (val) -+ printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n", -+ ag->dev->name, val); ++ skb_put(skb, pktlen); ++ if (ag71xx_has_ar8216(ag)) ++ err = ag71xx_remove_ar8216_header(ag, skb, pktlen); + -+ ag71xx_dump_dma_regs(ag); -+} ++ if (err) { ++ dev->stats.rx_dropped++; ++ kfree_skb(skb); ++ } else { ++ skb->dev = dev; ++ skb->ip_summed = CHECKSUM_NONE; ++ if (ag->phy_dev) { ++ ag->phy_dev->netif_receive_skb(skb); ++ } else { ++ skb->protocol = eth_type_trans(skb, dev); ++ netif_receive_skb(skb); ++ } ++ } + -+#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \ -+ MAC_CFG1_SRX | MAC_CFG1_STX) ++ ring->buf[i].skb = NULL; ++ done++; + -+#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT) ++ ring->curr++; ++ } + -+#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \ -+ FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \ -+ FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \ -+ FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \ -+ FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \ -+ FIFO_CFG4_VT) ++ ag71xx_ring_rx_refill(ag); + -+#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \ -+ FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \ -+ FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \ -+ FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \ -+ FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \ -+ FIFO_CFG5_17 | FIFO_CFG5_SF) ++ DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n", ++ dev->name, ring->curr, ring->dirty, done); + -+static void ag71xx_hw_stop(struct ag71xx *ag) -+{ -+ /* disable all interrupts and stop the rx/tx engine */ -+ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0); -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); -+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); ++ return done; +} + -+static void ag71xx_hw_setup(struct ag71xx *ag) ++static int ag71xx_poll(struct napi_struct *napi, int limit) +{ ++ struct ag71xx *ag = container_of(napi, struct ag71xx, napi); + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ struct net_device *dev = ag->dev; ++ struct ag71xx_ring *rx_ring; ++ unsigned long flags; ++ u32 status; ++ int tx_done; ++ int rx_done; + -+ /* setup MAC configuration registers */ -+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT); ++ pdata->ddr_flush(); ++ tx_done = ag71xx_tx_packets(ag); + -+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG2, -+ MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK); ++ DBG("%s: processing RX ring\n", dev->name); ++ rx_done = ag71xx_rx_packets(ag, limit); + -+ /* setup max frame length */ -+ ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN); ++ ag71xx_debugfs_update_napi_stats(ag, rx_done, tx_done); + -+ /* setup MII interface type */ -+ ag71xx_mii_ctrl_set_if(ag, pdata->mii_if); ++ rx_ring = &ag->rx_ring; ++ if (rx_ring->buf[rx_ring->dirty % rx_ring->size].skb == NULL) ++ goto oom; + -+ /* setup FIFO configuration registers */ -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT); -+ if (pdata->is_ar724x) { -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, pdata->fifo_cfg1); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, pdata->fifo_cfg2); -+ } else { -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); ++ status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); ++ if (unlikely(status & RX_STATUS_OF)) { ++ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF); ++ dev->stats.rx_fifo_errors++; ++ ++ /* restart RX */ ++ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); + } -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT); -+} + -+static void ag71xx_hw_init(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ u32 reset_mask = pdata->reset_bit; ++ if (rx_done < limit) { ++ if (status & RX_STATUS_PR) ++ goto more; + -+ ag71xx_hw_stop(ag); ++ status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); ++ if (status & TX_STATUS_PS) ++ goto more; + -+ if (pdata->is_ar724x) { -+ u32 reset_phy = reset_mask; ++ DBG("%s: disable polling mode, rx=%d, tx=%d,limit=%d\n", ++ dev->name, rx_done, tx_done, limit); + -+ reset_phy &= RESET_MODULE_GE0_PHY | RESET_MODULE_GE1_PHY; -+ reset_mask &= ~(RESET_MODULE_GE0_PHY | RESET_MODULE_GE1_PHY); ++ napi_complete(napi); + -+ ar71xx_device_stop(reset_phy); -+ mdelay(50); -+ ar71xx_device_start(reset_phy); -+ mdelay(200); ++ /* enable interrupts */ ++ spin_lock_irqsave(&ag->lock, flags); ++ ag71xx_int_enable(ag, AG71XX_INT_POLL); ++ spin_unlock_irqrestore(&ag->lock, flags); ++ return rx_done; + } + -+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); -+ udelay(20); -+ -+ ar71xx_device_stop(reset_mask); -+ mdelay(100); -+ ar71xx_device_start(reset_mask); -+ mdelay(200); ++more: ++ DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n", ++ dev->name, rx_done, tx_done, limit); ++ return rx_done; + -+ ag71xx_hw_setup(ag); ++oom: ++ if (netif_msg_rx_err(ag)) ++ printk(KERN_DEBUG "%s: out of memory\n", dev->name); + -+ ag71xx_dma_reset(ag); ++ mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL); ++ napi_complete(napi); ++ return 0; +} + -+static void ag71xx_fast_reset(struct ag71xx *ag) ++static irqreturn_t ag71xx_interrupt(int irq, void *dev_id) +{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct net_device *dev = ag->dev; -+ u32 reset_mask = pdata->reset_bit; -+ u32 rx_ds, tx_ds; -+ u32 mii_reg; ++ struct net_device *dev = dev_id; ++ struct ag71xx *ag = netdev_priv(dev); ++ u32 status; + -+ reset_mask &= RESET_MODULE_GE0_MAC | RESET_MODULE_GE1_MAC; ++ status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS); ++ ag71xx_dump_intr(ag, "raw", status); + -+ mii_reg = ag71xx_rr(ag, AG71XX_REG_MII_CFG); -+ rx_ds = ag71xx_rr(ag, AG71XX_REG_RX_DESC); -+ tx_ds = ag71xx_rr(ag, AG71XX_REG_TX_DESC); ++ if (unlikely(!status)) ++ return IRQ_NONE; + -+ ar71xx_device_stop(reset_mask); -+ udelay(10); -+ ar71xx_device_start(reset_mask); -+ udelay(10); ++ if (unlikely(status & AG71XX_INT_ERR)) { ++ if (status & AG71XX_INT_TX_BE) { ++ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE); ++ dev_err(&dev->dev, "TX BUS error\n"); ++ } ++ if (status & AG71XX_INT_RX_BE) { ++ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE); ++ dev_err(&dev->dev, "RX BUS error\n"); ++ } ++ } + -+ ag71xx_dma_reset(ag); -+ ag71xx_hw_setup(ag); ++ if (likely(status & AG71XX_INT_POLL)) { ++ ag71xx_int_disable(ag, AG71XX_INT_POLL); ++ DBG("%s: enable polling mode\n", dev->name); ++ napi_schedule(&ag->napi); ++ } + -+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, rx_ds); -+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, tx_ds); -+ ag71xx_wr(ag, AG71XX_REG_MII_CFG, mii_reg); ++ ag71xx_debugfs_update_int_stats(ag, status); + -+ ag71xx_hw_set_macaddr(ag, dev->dev_addr); ++ return IRQ_HANDLED; +} + -+static void ag71xx_hw_start(struct ag71xx *ag) ++static void ag71xx_set_multicast_list(struct net_device *dev) +{ -+ /* start RX engine */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); ++ /* TODO */ ++} + -+ /* enable interrupts */ -+ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT); ++#ifdef CONFIG_NET_POLL_CONTROLLER ++/* ++ * Polling 'interrupt' - used by things like netconsole to send skbs ++ * without having to re-enable interrupts. It's not called while ++ * the interrupt routine is executing. ++ */ ++static void ag71xx_netpoll(struct net_device *dev) ++{ ++ disable_irq(dev->irq); ++ ag71xx_interrupt(dev->irq, dev); ++ enable_irq(dev->irq); +} ++#endif + -+void ag71xx_link_adjust(struct ag71xx *ag) ++static const struct net_device_ops ag71xx_netdev_ops = { ++ .ndo_open = ag71xx_open, ++ .ndo_stop = ag71xx_stop, ++ .ndo_start_xmit = ag71xx_hard_start_xmit, ++ .ndo_set_multicast_list = ag71xx_set_multicast_list, ++ .ndo_do_ioctl = ag71xx_do_ioctl, ++ .ndo_tx_timeout = ag71xx_tx_timeout, ++ .ndo_change_mtu = eth_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++#ifdef CONFIG_NET_POLL_CONTROLLER ++ .ndo_poll_controller = ag71xx_netpoll, ++#endif ++}; ++ ++static int __devinit ag71xx_probe(struct platform_device *pdev) +{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ u32 cfg2; -+ u32 ifctl; -+ u32 fifo5; -+ u32 mii_speed; ++ struct net_device *dev; ++ struct resource *res; ++ struct ag71xx *ag; ++ struct ag71xx_platform_data *pdata; ++ int err; + -+ if (!ag->link) { -+ ag71xx_hw_stop(ag); -+ netif_carrier_off(ag->dev); -+ if (netif_msg_link(ag)) -+ printk(KERN_INFO "%s: link down\n", ag->dev->name); -+ return; ++ pdata = pdev->dev.platform_data; ++ if (!pdata) { ++ dev_err(&pdev->dev, "no platform data specified\n"); ++ err = -ENXIO; ++ goto err_out; + } + -+ if (pdata->is_ar724x) -+ ag71xx_fast_reset(ag); ++ if (pdata->mii_bus_dev == NULL) { ++ dev_err(&pdev->dev, "no MII bus device specified\n"); ++ err = -EINVAL; ++ goto err_out; ++ } + -+ cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); -+ cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); -+ cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; ++ dev = alloc_etherdev(sizeof(*ag)); ++ if (!dev) { ++ dev_err(&pdev->dev, "alloc_etherdev failed\n"); ++ err = -ENOMEM; ++ goto err_out; ++ } + -+ ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); -+ ifctl &= ~(MAC_IFCTL_SPEED); ++ SET_NETDEV_DEV(dev, &pdev->dev); + -+ fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); -+ fifo5 &= ~FIFO_CFG5_BM; ++ ag = netdev_priv(dev); ++ ag->pdev = pdev; ++ ag->dev = dev; ++ ag->msg_enable = netif_msg_init(ag71xx_msg_level, ++ AG71XX_DEFAULT_MSG_ENABLE); ++ spin_lock_init(&ag->lock); + -+ switch (ag->speed) { -+ case SPEED_1000: -+ mii_speed = MII_CTRL_SPEED_1000; -+ cfg2 |= MAC_CFG2_IF_1000; -+ fifo5 |= FIFO_CFG5_BM; -+ break; -+ case SPEED_100: -+ mii_speed = MII_CTRL_SPEED_100; -+ cfg2 |= MAC_CFG2_IF_10_100; -+ ifctl |= MAC_IFCTL_SPEED; -+ break; -+ case SPEED_10: -+ mii_speed = MII_CTRL_SPEED_10; -+ cfg2 |= MAC_CFG2_IF_10_100; -+ break; -+ default: -+ BUG(); -+ return; ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base"); ++ if (!res) { ++ dev_err(&pdev->dev, "no mac_base resource found\n"); ++ err = -ENXIO; ++ goto err_out; + } + -+ if (pdata->is_ar91xx) -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); -+ else if (pdata->is_ar724x) -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3); -+ else -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff); ++ ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1); ++ if (!ag->mac_base) { ++ dev_err(&pdev->dev, "unable to ioremap mac_base\n"); ++ err = -ENOMEM; ++ goto err_free_dev; ++ } + -+ if (pdata->set_pll) -+ pdata->set_pll(ag->speed); ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mii_ctrl"); ++ if (!res) { ++ dev_err(&pdev->dev, "no mii_ctrl resource found\n"); ++ err = -ENXIO; ++ goto err_unmap_base; ++ } + -+ ag71xx_mii_ctrl_set_speed(ag, mii_speed); ++ ag->mii_ctrl = ioremap_nocache(res->start, res->end - res->start + 1); ++ if (!ag->mii_ctrl) { ++ dev_err(&pdev->dev, "unable to ioremap mii_ctrl\n"); ++ err = -ENOMEM; ++ goto err_unmap_base; ++ } + -+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); -+ ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); -+ ag71xx_hw_start(ag); ++ dev->irq = platform_get_irq(pdev, 0); ++ err = request_irq(dev->irq, ag71xx_interrupt, ++ IRQF_DISABLED, ++ dev->name, dev); ++ if (err) { ++ dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq); ++ goto err_unmap_mii_ctrl; ++ } + -+ netif_carrier_on(ag->dev); -+ if (netif_msg_link(ag)) -+ printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n", -+ ag->dev->name, -+ ag71xx_speed_str(ag), -+ (DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); ++ dev->base_addr = (unsigned long)ag->mac_base; ++ dev->netdev_ops = &ag71xx_netdev_ops; ++ dev->ethtool_ops = &ag71xx_ethtool_ops; + -+ DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); ++ INIT_WORK(&ag->restart_work, ag71xx_restart_work_func); + -+ DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); ++ init_timer(&ag->oom_timer); ++ ag->oom_timer.data = (unsigned long) dev; ++ ag->oom_timer.function = ag71xx_oom_timer_handler; + -+ DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), -+ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), -+ ag71xx_mii_ctrl_rr(ag)); -+} ++ ag->tx_ring.size = AG71XX_TX_RING_SIZE_DEFAULT; ++ ag->rx_ring.size = AG71XX_RX_RING_SIZE_DEFAULT; + -+static int ag71xx_open(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ int ret; ++ ag->stop_desc = dma_alloc_coherent(NULL, ++ sizeof(struct ag71xx_desc), &ag->stop_desc_dma, GFP_KERNEL); + -+ ret = ag71xx_rings_init(ag); -+ if (ret) -+ goto err; ++ if (!ag->stop_desc) ++ goto err_free_irq; + -+ napi_enable(&ag->napi); ++ ag->stop_desc->data = 0; ++ ag->stop_desc->ctrl = 0; ++ ag->stop_desc->next = (u32) ag->stop_desc_dma; + -+ netif_carrier_off(dev); -+ ag71xx_phy_start(ag); ++ memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN); + -+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma); -+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma); ++ netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT); + -+ ag71xx_hw_set_macaddr(ag, dev->dev_addr); ++ err = register_netdev(dev); ++ if (err) { ++ dev_err(&pdev->dev, "unable to register net device\n"); ++ goto err_free_desc; ++ } + -+ netif_start_queue(dev); ++ printk(KERN_INFO "%s: Atheros AG71xx at 0x%08lx, irq %d\n", ++ dev->name, dev->base_addr, dev->irq); + -+ return 0; ++ ag71xx_dump_regs(ag); + -+err: -+ ag71xx_rings_cleanup(ag); -+ return ret; -+} ++ ag71xx_hw_init(ag); + -+static int ag71xx_stop(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ unsigned long flags; ++ ag71xx_dump_regs(ag); + -+ netif_carrier_off(dev); -+ ag71xx_phy_stop(ag); ++ err = ag71xx_phy_connect(ag); ++ if (err) ++ goto err_unregister_netdev; + -+ spin_lock_irqsave(&ag->lock, flags); ++ err = ag71xx_debugfs_init(ag); ++ if (err) ++ goto err_phy_disconnect; + -+ netif_stop_queue(dev); ++ platform_set_drvdata(pdev, dev); + -+ ag71xx_hw_stop(ag); -+ ag71xx_dma_reset(ag); ++ return 0; + -+ napi_disable(&ag->napi); -+ del_timer_sync(&ag->oom_timer); ++err_phy_disconnect: ++ ag71xx_phy_disconnect(ag); ++err_unregister_netdev: ++ unregister_netdev(dev); ++err_free_desc: ++ dma_free_coherent(NULL, sizeof(struct ag71xx_desc), ag->stop_desc, ++ ag->stop_desc_dma); ++err_free_irq: ++ free_irq(dev->irq, dev); ++err_unmap_mii_ctrl: ++ iounmap(ag->mii_ctrl); ++err_unmap_base: ++ iounmap(ag->mac_base); ++err_free_dev: ++ kfree(dev); ++err_out: ++ platform_set_drvdata(pdev, NULL); ++ return err; ++} + -+ spin_unlock_irqrestore(&ag->lock, flags); ++static int __devexit ag71xx_remove(struct platform_device *pdev) ++{ ++ struct net_device *dev = platform_get_drvdata(pdev); + -+ ag71xx_rings_cleanup(ag); ++ if (dev) { ++ struct ag71xx *ag = netdev_priv(dev); ++ ++ ag71xx_debugfs_exit(ag); ++ ag71xx_phy_disconnect(ag); ++ unregister_netdev(dev); ++ free_irq(dev->irq, dev); ++ iounmap(ag->mii_ctrl); ++ iounmap(ag->mac_base); ++ kfree(dev); ++ platform_set_drvdata(pdev, NULL); ++ } + + return 0; +} + -+static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb, -+ struct net_device *dev) ++static struct platform_driver ag71xx_driver = { ++ .probe = ag71xx_probe, ++ .remove = __exit_p(ag71xx_remove), ++ .driver = { ++ .name = AG71XX_DRV_NAME, ++ } ++}; ++ ++static int __init ag71xx_module_init(void) +{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ struct ag71xx_desc *desc; -+ dma_addr_t dma_addr; -+ int i; ++ int ret; + -+ i = ring->curr % ring->size; -+ desc = ring->buf[i].desc; ++ ret = ag71xx_debugfs_root_init(); ++ if (ret) ++ goto err_out; + -+ if (!ag71xx_desc_empty(desc)) -+ goto err_drop; ++ ret = ag71xx_mdio_driver_init(); ++ if (ret) ++ goto err_debugfs_exit; + -+ if (ag71xx_has_ar8216(ag)) -+ ag71xx_add_ar8216_header(ag, skb); ++ ret = platform_driver_register(&ag71xx_driver); ++ if (ret) ++ goto err_mdio_exit; + -+ if (skb->len <= 0) { -+ DBG("%s: packet len is too small\n", ag->dev->name); -+ goto err_drop; -+ } ++ return 0; + -+ dma_addr = dma_map_single(&dev->dev, skb->data, skb->len, -+ DMA_TO_DEVICE); ++err_mdio_exit: ++ ag71xx_mdio_driver_exit(); ++err_debugfs_exit: ++ ag71xx_debugfs_root_exit(); ++err_out: ++ return ret; ++} + -+ ring->buf[i].skb = skb; -+ ring->buf[i].timestamp = jiffies; ++static void __exit ag71xx_module_exit(void) ++{ ++ platform_driver_unregister(&ag71xx_driver); ++ ag71xx_mdio_driver_exit(); ++ ag71xx_debugfs_root_exit(); ++} + -+ /* setup descriptor fields */ -+ desc->data = (u32) dma_addr; -+ desc->ctrl = (skb->len & DESC_PKTLEN_M); ++module_init(ag71xx_module_init); ++module_exit(ag71xx_module_exit); + -+ /* flush descriptor */ -+ wmb(); ++MODULE_VERSION(AG71XX_DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_AUTHOR("Imre Kaloz "); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" AG71XX_DRV_NAME); +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,248 @@ ++/* ++ * Atheros AR71xx built-in ethernet mac driver ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Based on Atheros' AG7100 driver ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ ring->curr++; -+ if (ring->curr == (ring->dirty + ring->size)) { -+ DBG("%s: tx queue full\n", ag->dev->name); -+ netif_stop_queue(dev); -+ } ++#include "ag71xx.h" + -+ DBG("%s: packet injected into TX queue\n", ag->dev->name); ++#define AG71XX_MDIO_RETRY 1000 ++#define AG71XX_MDIO_DELAY 5 + -+ /* enable TX engine */ -+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); ++static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg, ++ u32 value) ++{ ++ void __iomem *r; + -+ return NETDEV_TX_OK; ++ r = am->mdio_base + reg; ++ __raw_writel(value, r); + -+err_drop: -+ dev->stats.tx_dropped++; ++ /* flush write */ ++ (void) __raw_readl(r); ++} + -+ dev_kfree_skb(skb); -+ return NETDEV_TX_OK; ++static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg) ++{ ++ return __raw_readl(am->mdio_base + reg); +} + -+static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ++static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am) ++{ ++ DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n", ++ am->mii_bus->name, ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG), ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD), ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR)); ++ DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n", ++ am->mii_bus->name, ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL), ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS), ++ ag71xx_mdio_rr(am, AG71XX_REG_MII_IND)); ++} ++ ++int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg) +{ -+ struct ag71xx *ag = netdev_priv(dev); + int ret; ++ int i; + -+ switch (cmd) { -+ case SIOCETHTOOL: -+ if (ag->phy_dev == NULL) -+ break; ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, ++ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ); + -+ spin_lock_irq(&ag->lock); -+ ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data); -+ spin_unlock_irq(&ag->lock); -+ return ret; ++ i = AG71XX_MDIO_RETRY; ++ while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { ++ if (i-- == 0) { ++ printk(KERN_ERR "%s: mii_read timed out\n", ++ am->mii_bus->name); ++ ret = 0xffff; ++ goto out; ++ } ++ udelay(AG71XX_MDIO_DELAY); ++ } + -+ case SIOCSIFHWADDR: -+ if (copy_from_user -+ (dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr))) -+ return -EFAULT; -+ return 0; ++ ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff; ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); + -+ case SIOCGIFHWADDR: -+ if (copy_to_user -+ (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr))) -+ return -EFAULT; -+ return 0; ++ DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret); + -+ case SIOCGMIIPHY: -+ case SIOCGMIIREG: -+ case SIOCSMIIREG: -+ if (ag->phy_dev == NULL) -+ break; ++out: ++ return ret; ++} + -+ return phy_mii_ioctl(ag->phy_dev, ifr, cmd); ++void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val) ++{ ++ int i; + -+ default: -+ break; -+ } ++ DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val); + -+ return -EOPNOTSUPP; ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, ++ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val); ++ ++ i = AG71XX_MDIO_RETRY; ++ while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { ++ if (i-- == 0) { ++ printk(KERN_ERR "%s: mii_write timed out\n", ++ am->mii_bus->name); ++ break; ++ } ++ udelay(AG71XX_MDIO_DELAY); ++ } +} + -+static void ag71xx_oom_timer_handler(unsigned long data) ++static int ag71xx_mdio_reset(struct mii_bus *bus) +{ -+ struct net_device *dev = (struct net_device *) data; -+ struct ag71xx *ag = netdev_priv(dev); ++ struct ag71xx_mdio *am = bus->priv; ++ u32 t; + -+ napi_schedule(&ag->napi); -+} ++ if (am->pdata->is_ar7240) ++ t = MII_CFG_CLK_DIV_6; ++ else ++ t = MII_CFG_CLK_DIV_28; + -+static void ag71xx_tx_timeout(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET); ++ udelay(100); + -+ if (netif_msg_tx_err(ag)) -+ printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name); ++ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t); ++ udelay(100); + -+ schedule_work(&ag->restart_work); ++ return 0; +} + -+static void ag71xx_restart_work_func(struct work_struct *work) ++static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg) +{ -+ struct ag71xx *ag = container_of(work, struct ag71xx, restart_work); -+ -+ if (ag71xx_get_pdata(ag)->is_ar724x) { -+ ag->link = 0; -+ ag71xx_link_adjust(ag); -+ return; -+ } ++ struct ag71xx_mdio *am = bus->priv; + -+ ag71xx_stop(ag->dev); -+ ag71xx_open(ag->dev); ++ if (am->pdata->is_ar7240) ++ return ar7240sw_phy_read(bus, addr, reg); ++ else ++ return ag71xx_mdio_mii_read(am, addr, reg); +} + -+static bool ag71xx_check_dma_stuck(struct ag71xx *ag, unsigned long timestamp) ++static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) +{ -+ u32 rx_sm, tx_sm, rx_fd; ++ struct ag71xx_mdio *am = bus->priv; + -+ if (likely(time_before(jiffies, timestamp + HZ/10))) -+ return false; ++ if (am->pdata->is_ar7240) ++ ar7240sw_phy_write(bus, addr, reg, val); ++ else ++ ag71xx_mdio_mii_write(am, addr, reg, val); ++ return 0; ++} + -+ if (!netif_carrier_ok(ag->dev)) -+ return false; -+ -+ rx_sm = ag71xx_rr(ag, AG71XX_REG_RX_SM); -+ if ((rx_sm & 0x7) == 0x3 && ((rx_sm >> 4) & 0x7) == 0x6) -+ return true; ++static int __devinit ag71xx_mdio_probe(struct platform_device *pdev) ++{ ++ struct ag71xx_mdio_platform_data *pdata; ++ struct ag71xx_mdio *am; ++ struct resource *res; ++ int i; ++ int err; + -+ tx_sm = ag71xx_rr(ag, AG71XX_REG_TX_SM); -+ rx_fd = ag71xx_rr(ag, AG71XX_REG_FIFO_DEPTH); -+ if (((tx_sm >> 4) & 0x7) == 0 && ((rx_sm & 0x7) == 0) && -+ ((rx_sm >> 4) & 0x7) == 0 && rx_fd == 0) -+ return true; ++ pdata = pdev->dev.platform_data; ++ if (!pdata) { ++ dev_err(&pdev->dev, "no platform data specified\n"); ++ return -EINVAL; ++ } + -+ return false; -+} ++ am = kzalloc(sizeof(*am), GFP_KERNEL); ++ if (!am) { ++ err = -ENOMEM; ++ goto err_out; ++ } + -+static int ag71xx_tx_packets(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ int sent; ++ am->pdata = pdata; + -+ DBG("%s: processing TX ring\n", ag->dev->name); ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "no iomem resource found\n"); ++ err = -ENXIO; ++ goto err_out; ++ } + -+ sent = 0; -+ while (ring->dirty != ring->curr) { -+ unsigned int i = ring->dirty % ring->size; -+ struct ag71xx_desc *desc = ring->buf[i].desc; -+ struct sk_buff *skb = ring->buf[i].skb; ++ am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1); ++ if (!am->mdio_base) { ++ dev_err(&pdev->dev, "unable to ioremap registers\n"); ++ err = -ENOMEM; ++ goto err_free_mdio; ++ } + -+ if (!ag71xx_desc_empty(desc)) { -+ if (pdata->is_ar7240 && -+ ag71xx_check_dma_stuck(ag, ring->buf[i].timestamp)) -+ schedule_work(&ag->restart_work); -+ break; -+ } ++ am->mii_bus = mdiobus_alloc(); ++ if (am->mii_bus == NULL) { ++ err = -ENOMEM; ++ goto err_iounmap; ++ } + -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); ++ am->mii_bus->name = "ag71xx_mdio"; ++ am->mii_bus->read = ag71xx_mdio_read; ++ am->mii_bus->write = ag71xx_mdio_write; ++ am->mii_bus->reset = ag71xx_mdio_reset; ++ am->mii_bus->irq = am->mii_irq; ++ am->mii_bus->priv = am; ++ am->mii_bus->parent = &pdev->dev; ++ snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev)); ++ am->mii_bus->phy_mask = pdata->phy_mask; + -+ ag->dev->stats.tx_bytes += skb->len; -+ ag->dev->stats.tx_packets++; ++ for (i = 0; i < PHY_MAX_ADDR; i++) ++ am->mii_irq[i] = PHY_POLL; + -+ dev_kfree_skb_any(skb); -+ ring->buf[i].skb = NULL; ++ ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0); + -+ ring->dirty++; -+ sent++; -+ } ++ err = mdiobus_register(am->mii_bus); ++ if (err) ++ goto err_free_bus; + -+ DBG("%s: %d packets sent out\n", ag->dev->name, sent); ++ ag71xx_mdio_dump_regs(am); + -+ if ((ring->curr - ring->dirty) < (ring->size * 3) / 4) -+ netif_wake_queue(ag->dev); ++ platform_set_drvdata(pdev, am); ++ return 0; + -+ return sent; ++err_free_bus: ++ mdiobus_free(am->mii_bus); ++err_iounmap: ++ iounmap(am->mdio_base); ++err_free_mdio: ++ kfree(am); ++err_out: ++ return err; +} + -+static int ag71xx_rx_packets(struct ag71xx *ag, int limit) ++static int __devexit ag71xx_mdio_remove(struct platform_device *pdev) +{ -+ struct net_device *dev = ag->dev; -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ int done = 0; -+ -+ DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n", -+ dev->name, limit, ring->curr, ring->dirty); ++ struct ag71xx_mdio *am = platform_get_drvdata(pdev); + -+ while (done < limit) { -+ unsigned int i = ring->curr % ring->size; -+ struct ag71xx_desc *desc = ring->buf[i].desc; -+ struct sk_buff *skb; -+ int pktlen; -+ int err = 0; ++ if (am) { ++ mdiobus_unregister(am->mii_bus); ++ mdiobus_free(am->mii_bus); ++ iounmap(am->mdio_base); ++ kfree(am); ++ platform_set_drvdata(pdev, NULL); ++ } + -+ if (ag71xx_desc_empty(desc)) -+ break; ++ return 0; ++} + -+ if ((ring->dirty + ring->size) == ring->curr) { -+ ag71xx_assert(0); -+ break; -+ } ++static struct platform_driver ag71xx_mdio_driver = { ++ .probe = ag71xx_mdio_probe, ++ .remove = __exit_p(ag71xx_mdio_remove), ++ .driver = { ++ .name = "ag71xx-mdio", ++ } ++}; + -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); ++int __init ag71xx_mdio_driver_init(void) ++{ ++ return platform_driver_register(&ag71xx_mdio_driver); ++} + -+ skb = ring->buf[i].skb; -+ pktlen = ag71xx_desc_pktlen(desc); -+ pktlen -= ETH_FCS_LEN; ++void ag71xx_mdio_driver_exit(void) ++{ ++ platform_driver_unregister(&ag71xx_mdio_driver); ++} +diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c +--- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,228 @@ ++/* ++ * Atheros AR71xx built-in ethernet mac driver ++ * ++ * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Based on Atheros' AG7100 driver ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ + -+ dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, -+ AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); ++#include "ag71xx.h" + -+ dev->last_rx = jiffies; -+ dev->stats.rx_packets++; -+ dev->stats.rx_bytes += pktlen; ++static void ag71xx_phy_link_adjust(struct net_device *dev) ++{ ++ struct ag71xx *ag = netdev_priv(dev); ++ struct phy_device *phydev = ag->phy_dev; ++ unsigned long flags; ++ int status_change = 0; + -+ skb_put(skb, pktlen); -+ if (ag71xx_has_ar8216(ag)) -+ err = ag71xx_remove_ar8216_header(ag, skb, pktlen); ++ spin_lock_irqsave(&ag->lock, flags); + -+ if (err) { -+ dev->stats.rx_dropped++; -+ kfree_skb(skb); -+ } else { -+ skb->dev = dev; -+ skb->ip_summed = CHECKSUM_NONE; -+ if (ag->phy_dev) { -+ ag->phy_dev->netif_receive_skb(skb); -+ } else { -+ skb->protocol = eth_type_trans(skb, dev); -+ netif_receive_skb(skb); -+ } ++ if (phydev->link) { ++ if (ag->duplex != phydev->duplex ++ || ag->speed != phydev->speed) { ++ status_change = 1; + } -+ -+ ring->buf[i].skb = NULL; -+ done++; -+ -+ ring->curr++; + } + -+ ag71xx_ring_rx_refill(ag); ++ if (phydev->link != ag->link) ++ status_change = 1; + -+ DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n", -+ dev->name, ring->curr, ring->dirty, done); ++ ag->link = phydev->link; ++ ag->duplex = phydev->duplex; ++ ag->speed = phydev->speed; + -+ return done; ++ if (status_change) ++ ag71xx_link_adjust(ag); ++ ++ spin_unlock_irqrestore(&ag->lock, flags); +} + -+static int ag71xx_poll(struct napi_struct *napi, int limit) ++void ag71xx_phy_start(struct ag71xx *ag) +{ -+ struct ag71xx *ag = container_of(napi, struct ag71xx, napi); + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct net_device *dev = ag->dev; -+ struct ag71xx_ring *rx_ring; -+ unsigned long flags; -+ u32 status; -+ int tx_done; -+ int rx_done; -+ -+ pdata->ddr_flush(); -+ tx_done = ag71xx_tx_packets(ag); + -+ DBG("%s: processing RX ring\n", dev->name); -+ rx_done = ag71xx_rx_packets(ag, limit); ++ if (ag->phy_dev) { ++ phy_start(ag->phy_dev); ++ } else if (pdata->has_ar7240_switch) { ++ ag71xx_ar7240_start(ag); ++ } else { ++ ag->link = 1; ++ ag71xx_link_adjust(ag); ++ } ++} + -+ ag71xx_debugfs_update_napi_stats(ag, rx_done, tx_done); ++void ag71xx_phy_stop(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + -+ rx_ring = &ag->rx_ring; -+ if (rx_ring->buf[rx_ring->dirty % rx_ring->size].skb == NULL) -+ goto oom; ++ if (ag->phy_dev) { ++ phy_stop(ag->phy_dev); ++ } else { ++ if (pdata->has_ar7240_switch) ++ ag71xx_ar7240_stop(ag); ++ ag->link = 0; ++ ag71xx_link_adjust(ag); ++ } ++} + -+ status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); -+ if (unlikely(status & RX_STATUS_OF)) { -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF); -+ dev->stats.rx_fifo_errors++; ++static int ag71xx_phy_connect_fixed(struct ag71xx *ag) ++{ ++ struct net_device *dev = ag->dev; ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ int ret = 0; + -+ /* restart RX */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); ++ /* use fixed settings */ ++ switch (pdata->speed) { ++ case SPEED_10: ++ case SPEED_100: ++ case SPEED_1000: ++ break; ++ default: ++ printk(KERN_ERR "%s: invalid speed specified\n", dev->name); ++ ret = -EINVAL; ++ break; + } + -+ if (rx_done < limit) { -+ if (status & RX_STATUS_PR) -+ goto more; -+ -+ status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); -+ if (status & TX_STATUS_PS) -+ goto more; ++ printk(KERN_DEBUG "%s: using fixed link parameters\n", dev->name); + -+ DBG("%s: disable polling mode, rx=%d, tx=%d,limit=%d\n", -+ dev->name, rx_done, tx_done, limit); ++ ag->duplex = pdata->duplex; ++ ag->speed = pdata->speed; + -+ napi_complete(napi); ++ return ret; ++} + -+ /* enable interrupts */ -+ spin_lock_irqsave(&ag->lock, flags); -+ ag71xx_int_enable(ag, AG71XX_INT_POLL); -+ spin_unlock_irqrestore(&ag->lock, flags); -+ return rx_done; -+ } ++static int ag71xx_phy_connect_multi(struct ag71xx *ag) ++{ ++ struct net_device *dev = ag->dev; ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); ++ struct phy_device *phydev = NULL; ++ int phy_addr; ++ int ret = 0; + -+more: -+ DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n", -+ dev->name, rx_done, tx_done, limit); -+ return rx_done; ++ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { ++ if (!(pdata->phy_mask & (1 << phy_addr))) ++ continue; + -+oom: -+ if (netif_msg_rx_err(ag)) -+ printk(KERN_DEBUG "%s: out of memory\n", dev->name); ++ if (ag->mii_bus->phy_map[phy_addr] == NULL) ++ continue; + -+ mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL); -+ napi_complete(napi); -+ return 0; -+} ++ DBG("%s: PHY found at %s, uid=%08x\n", ++ dev->name, ++ dev_name(&ag->mii_bus->phy_map[phy_addr]->dev), ++ ag->mii_bus->phy_map[phy_addr]->phy_id); + -+static irqreturn_t ag71xx_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *dev = dev_id; -+ struct ag71xx *ag = netdev_priv(dev); -+ u32 status; ++ if (phydev == NULL) ++ phydev = ag->mii_bus->phy_map[phy_addr]; ++ } + -+ status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS); -+ ag71xx_dump_intr(ag, "raw", status); ++ if (!phydev) { ++ printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n", ++ dev->name, pdata->phy_mask); ++ return -ENODEV; ++ } + -+ if (unlikely(!status)) -+ return IRQ_NONE; ++ ag->phy_dev = phy_connect(dev, dev_name(&phydev->dev), ++ &ag71xx_phy_link_adjust, 0, ++ pdata->phy_if_mode); + -+ if (unlikely(status & AG71XX_INT_ERR)) { -+ if (status & AG71XX_INT_TX_BE) { -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE); -+ dev_err(&dev->dev, "TX BUS error\n"); -+ } -+ if (status & AG71XX_INT_RX_BE) { -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE); -+ dev_err(&dev->dev, "RX BUS error\n"); -+ } ++ if (IS_ERR(ag->phy_dev)) { ++ printk(KERN_ERR "%s: could not connect to PHY at %s\n", ++ dev->name, dev_name(&phydev->dev)); ++ return PTR_ERR(ag->phy_dev); + } + -+ if (likely(status & AG71XX_INT_POLL)) { -+ ag71xx_int_disable(ag, AG71XX_INT_POLL); -+ DBG("%s: enable polling mode\n", dev->name); -+ napi_schedule(&ag->napi); -+ } ++ /* mask with MAC supported features */ ++ if (pdata->has_gbit) ++ phydev->supported &= PHY_GBIT_FEATURES; ++ else ++ phydev->supported &= PHY_BASIC_FEATURES; + -+ ag71xx_debugfs_update_int_stats(ag, status); ++ phydev->advertising = phydev->supported; + -+ return IRQ_HANDLED; -+} ++ printk(KERN_DEBUG "%s: connected to PHY at %s [uid=%08x, driver=%s]\n", ++ dev->name, dev_name(&phydev->dev), ++ phydev->phy_id, phydev->drv->name); + -+static void ag71xx_set_multicast_list(struct net_device *dev) -+{ -+ /* TODO */ ++ ag->link = 0; ++ ag->speed = 0; ++ ag->duplex = -1; ++ ++ return ret; +} + -+#ifdef CONFIG_NET_POLL_CONTROLLER -+/* -+ * Polling 'interrupt' - used by things like netconsole to send skbs -+ * without having to re-enable interrupts. It's not called while -+ * the interrupt routine is executing. -+ */ -+static void ag71xx_netpoll(struct net_device *dev) ++static int dev_is_class(struct device *dev, void *class) +{ -+ disable_irq(dev->irq); -+ ag71xx_interrupt(dev->irq, dev); -+ enable_irq(dev->irq); -+} -+#endif ++ if (dev->class != NULL && !strcmp(dev->class->name, class)) ++ return 1; + -+static const struct net_device_ops ag71xx_netdev_ops = { -+ .ndo_open = ag71xx_open, -+ .ndo_stop = ag71xx_stop, -+ .ndo_start_xmit = ag71xx_hard_start_xmit, -+ .ndo_set_multicast_list = ag71xx_set_multicast_list, -+ .ndo_do_ioctl = ag71xx_do_ioctl, -+ .ndo_tx_timeout = ag71xx_tx_timeout, -+ .ndo_change_mtu = eth_change_mtu, -+ .ndo_set_mac_address = eth_mac_addr, -+ .ndo_validate_addr = eth_validate_addr, -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ .ndo_poll_controller = ag71xx_netpoll, -+#endif -+}; ++ return 0; ++} + -+static int __devinit ag71xx_probe(struct platform_device *pdev) ++static struct device *dev_find_class(struct device *parent, char *class) +{ -+ struct net_device *dev; -+ struct resource *res; -+ struct ag71xx *ag; -+ struct ag71xx_platform_data *pdata; -+ int err; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) { -+ dev_err(&pdev->dev, "no platform data specified\n"); -+ err = -ENXIO; -+ goto err_out; ++ if (dev_is_class(parent, class)) { ++ get_device(parent); ++ return parent; + } + -+ if (pdata->mii_bus_dev == NULL) { -+ dev_err(&pdev->dev, "no MII bus device specified\n"); -+ err = -EINVAL; -+ goto err_out; -+ } ++ return device_find_child(parent, class, dev_is_class); ++} + -+ dev = alloc_etherdev(sizeof(*ag)); -+ if (!dev) { -+ dev_err(&pdev->dev, "alloc_etherdev failed\n"); -+ err = -ENOMEM; -+ goto err_out; -+ } ++static struct mii_bus *dev_to_mii_bus(struct device *dev) ++{ ++ struct device *d; + -+ SET_NETDEV_DEV(dev, &pdev->dev); ++ d = dev_find_class(dev, "mdio_bus"); ++ if (d != NULL) { ++ struct mii_bus *bus; + -+ ag = netdev_priv(dev); -+ ag->pdev = pdev; -+ ag->dev = dev; -+ ag->msg_enable = netif_msg_init(ag71xx_msg_level, -+ AG71XX_DEFAULT_MSG_ENABLE); -+ spin_lock_init(&ag->lock); ++ bus = to_mii_bus(d); ++ put_device(d); + -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base"); -+ if (!res) { -+ dev_err(&pdev->dev, "no mac_base resource found\n"); -+ err = -ENXIO; -+ goto err_out; ++ return bus; + } + -+ ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!ag->mac_base) { -+ dev_err(&pdev->dev, "unable to ioremap mac_base\n"); -+ err = -ENOMEM; -+ goto err_free_dev; -+ } ++ return NULL; ++} + -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mii_ctrl"); -+ if (!res) { -+ dev_err(&pdev->dev, "no mii_ctrl resource found\n"); -+ err = -ENXIO; -+ goto err_unmap_base; -+ } ++int __devinit ag71xx_phy_connect(struct ag71xx *ag) ++{ ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + -+ ag->mii_ctrl = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!ag->mii_ctrl) { -+ dev_err(&pdev->dev, "unable to ioremap mii_ctrl\n"); -+ err = -ENOMEM; -+ goto err_unmap_base; ++ ag->mii_bus = dev_to_mii_bus(pdata->mii_bus_dev); ++ if (ag->mii_bus == NULL) { ++ printk(KERN_ERR "%s: unable to find MII bus on device '%s'\n", ++ ag->dev->name, dev_name(pdata->mii_bus_dev)); ++ return -ENODEV; + } + -+ dev->irq = platform_get_irq(pdev, 0); -+ err = request_irq(dev->irq, ag71xx_interrupt, -+ IRQF_DISABLED, -+ dev->name, dev); -+ if (err) { -+ dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq); -+ goto err_unmap_mii_ctrl; ++ /* Reset the mdio bus explicitly */ ++ if (ag->mii_bus->reset) { ++ mutex_lock(&ag->mii_bus->mdio_lock); ++ ag->mii_bus->reset(ag->mii_bus); ++ mutex_unlock(&ag->mii_bus->mdio_lock); + } + -+ dev->base_addr = (unsigned long)ag->mac_base; -+ dev->netdev_ops = &ag71xx_netdev_ops; -+ dev->ethtool_ops = &ag71xx_ethtool_ops; ++ if (pdata->has_ar7240_switch) ++ return ag71xx_ar7240_init(ag); + -+ INIT_WORK(&ag->restart_work, ag71xx_restart_work_func); ++ if (pdata->phy_mask) ++ return ag71xx_phy_connect_multi(ag); + -+ init_timer(&ag->oom_timer); -+ ag->oom_timer.data = (unsigned long) dev; -+ ag->oom_timer.function = ag71xx_oom_timer_handler; -+ -+ ag->tx_ring.size = AG71XX_TX_RING_SIZE_DEFAULT; -+ ag->rx_ring.size = AG71XX_RX_RING_SIZE_DEFAULT; -+ -+ ag->stop_desc = dma_alloc_coherent(NULL, -+ sizeof(struct ag71xx_desc), &ag->stop_desc_dma, GFP_KERNEL); -+ -+ if (!ag->stop_desc) -+ goto err_free_irq; -+ -+ ag->stop_desc->data = 0; -+ ag->stop_desc->ctrl = 0; -+ ag->stop_desc->next = (u32) ag->stop_desc_dma; -+ -+ memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN); -+ -+ netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT); -+ -+ err = register_netdev(dev); -+ if (err) { -+ dev_err(&pdev->dev, "unable to register net device\n"); -+ goto err_free_desc; -+ } -+ -+ printk(KERN_INFO "%s: Atheros AG71xx at 0x%08lx, irq %d\n", -+ dev->name, dev->base_addr, dev->irq); -+ -+ ag71xx_dump_regs(ag); -+ -+ ag71xx_hw_init(ag); -+ -+ ag71xx_dump_regs(ag); -+ -+ err = ag71xx_phy_connect(ag); -+ if (err) -+ goto err_unregister_netdev; -+ -+ err = ag71xx_debugfs_init(ag); -+ if (err) -+ goto err_phy_disconnect; -+ -+ platform_set_drvdata(pdev, dev); -+ -+ return 0; -+ -+err_phy_disconnect: -+ ag71xx_phy_disconnect(ag); -+err_unregister_netdev: -+ unregister_netdev(dev); -+err_free_desc: -+ dma_free_coherent(NULL, sizeof(struct ag71xx_desc), ag->stop_desc, -+ ag->stop_desc_dma); -+err_free_irq: -+ free_irq(dev->irq, dev); -+err_unmap_mii_ctrl: -+ iounmap(ag->mii_ctrl); -+err_unmap_base: -+ iounmap(ag->mac_base); -+err_free_dev: -+ kfree(dev); -+err_out: -+ platform_set_drvdata(pdev, NULL); -+ return err; -+} -+ -+static int __devexit ag71xx_remove(struct platform_device *pdev) -+{ -+ struct net_device *dev = platform_get_drvdata(pdev); -+ -+ if (dev) { -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ ag71xx_debugfs_exit(ag); -+ ag71xx_phy_disconnect(ag); -+ unregister_netdev(dev); -+ free_irq(dev->irq, dev); -+ iounmap(ag->mii_ctrl); -+ iounmap(ag->mac_base); -+ kfree(dev); -+ platform_set_drvdata(pdev, NULL); -+ } -+ -+ return 0; ++ return ag71xx_phy_connect_fixed(ag); +} + -+static struct platform_driver ag71xx_driver = { -+ .probe = ag71xx_probe, -+ .remove = __exit_p(ag71xx_remove), -+ .driver = { -+ .name = AG71XX_DRV_NAME, -+ } -+}; -+ -+static int __init ag71xx_module_init(void) ++void ag71xx_phy_disconnect(struct ag71xx *ag) +{ -+ int ret; -+ -+ ret = ag71xx_debugfs_root_init(); -+ if (ret) -+ goto err_out; -+ -+ ret = ag71xx_mdio_driver_init(); -+ if (ret) -+ goto err_debugfs_exit; -+ -+ ret = platform_driver_register(&ag71xx_driver); -+ if (ret) -+ goto err_mdio_exit; -+ -+ return 0; -+ -+err_mdio_exit: -+ ag71xx_mdio_driver_exit(); -+err_debugfs_exit: -+ ag71xx_debugfs_root_exit(); -+err_out: -+ return ret; -+} ++ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + -+static void __exit ag71xx_module_exit(void) -+{ -+ platform_driver_unregister(&ag71xx_driver); -+ ag71xx_mdio_driver_exit(); -+ ag71xx_debugfs_root_exit(); ++ if (pdata->has_ar7240_switch) ++ ag71xx_ar7240_cleanup(ag); ++ else if (ag->phy_dev) ++ phy_disconnect(ag->phy_dev); +} +diff -Nur linux-2.6.39.orig/drivers/net/phy/Kconfig linux-2.6.39/drivers/net/phy/Kconfig +--- linux-2.6.39.orig/drivers/net/phy/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/phy/Kconfig 2011-08-24 18:17:24.000000000 +0200 +@@ -13,6 +13,12 @@ + + if PHYLIB + ++config SWCONFIG ++ tristate "Switch configuration API" ++ ---help--- ++ Switch configuration API using netlink. This allows ++ you to configure the VLAN features of certain switches. + -+module_init(ag71xx_module_init); -+module_exit(ag71xx_module_exit); -+ -+MODULE_VERSION(AG71XX_DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_AUTHOR("Imre Kaloz "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" AG71XX_DRV_NAME); -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_mdio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_mdio.c 2011-04-27 12:19:22.257663952 +0200 -@@ -0,0 +1,248 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos + comment "MII PHY device drivers" + + config MARVELL_PHY +diff -Nur linux-2.6.39.orig/drivers/net/phy/Makefile linux-2.6.39/drivers/net/phy/Makefile +--- linux-2.6.39.orig/drivers/net/phy/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/phy/Makefile 2011-08-24 18:17:24.000000000 +0200 +@@ -3,6 +3,7 @@ + libphy-objs := phy.o phy_device.o mdio_bus.o + + obj-$(CONFIG_PHYLIB) += libphy.o ++obj-$(CONFIG_SWCONFIG) += swconfig.o + obj-$(CONFIG_MARVELL_PHY) += marvell.o + obj-$(CONFIG_DAVICOM_PHY) += davicom.o + obj-$(CONFIG_CICADA_PHY) += cicada.o +diff -Nur linux-2.6.39.orig/drivers/net/phy/micrel.c linux-2.6.39/drivers/net/phy/micrel.c +--- linux-2.6.39.orig/drivers/net/phy/micrel.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/phy/micrel.c 2011-08-24 18:17:24.000000000 +0200 +@@ -1,251 +1,82 @@ + /* +- * drivers/net/phy/micrel.c ++ * Driver for Micrel/Kendin PHYs + * +- * Driver for Micrel PHYs ++ * Copyright (c) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * + * +- * Author: David J. Choi + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. -+ */ -+ -+#include "ag71xx.h" -+ -+#define AG71XX_MDIO_RETRY 1000 -+#define AG71XX_MDIO_DELAY 5 -+ -+static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg, -+ u32 value) -+{ -+ void __iomem *r; -+ -+ r = am->mdio_base + reg; -+ __raw_writel(value, r); -+ -+ /* flush write */ -+ (void) __raw_readl(r); -+} -+ -+static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg) -+{ -+ return __raw_readl(am->mdio_base + reg); -+} -+ -+static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am) -+{ -+ DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n", -+ am->mii_bus->name, -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR)); -+ DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n", -+ am->mii_bus->name, -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_IND)); -+} -+ -+int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg) -+{ -+ int ret; -+ int i; -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, -+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ); -+ -+ i = AG71XX_MDIO_RETRY; -+ while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { -+ if (i-- == 0) { -+ printk(KERN_ERR "%s: mii_read timed out\n", -+ am->mii_bus->name); -+ ret = 0xffff; -+ goto out; -+ } -+ udelay(AG71XX_MDIO_DELAY); -+ } -+ -+ ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff; -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); -+ -+ DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret); -+ -+out: -+ return ret; -+} -+ -+void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val) -+{ -+ int i; -+ -+ DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val); -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, -+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val); -+ -+ i = AG71XX_MDIO_RETRY; -+ while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { -+ if (i-- == 0) { -+ printk(KERN_ERR "%s: mii_write timed out\n", -+ am->mii_bus->name); -+ break; -+ } -+ udelay(AG71XX_MDIO_DELAY); -+ } -+} -+ -+static int ag71xx_mdio_reset(struct mii_bus *bus) -+{ -+ struct ag71xx_mdio *am = bus->priv; -+ u32 t; -+ -+ if (am->pdata->is_ar7240) -+ t = MII_CFG_CLK_DIV_6; -+ else -+ t = MII_CFG_CLK_DIV_28; -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET); -+ udelay(100); -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t); -+ udelay(100); -+ -+ return 0; -+} -+ -+static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg) -+{ -+ struct ag71xx_mdio *am = bus->priv; -+ -+ if (am->pdata->is_ar7240) -+ return ar7240sw_phy_read(bus, addr, reg); -+ else -+ return ag71xx_mdio_mii_read(am, addr, reg); -+} -+ -+static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) -+{ -+ struct ag71xx_mdio *am = bus->priv; -+ -+ if (am->pdata->is_ar7240) -+ ar7240sw_phy_write(bus, addr, reg, val); -+ else -+ ag71xx_mdio_mii_write(am, addr, reg, val); -+ return 0; -+} -+ -+static int __devinit ag71xx_mdio_probe(struct platform_device *pdev) -+{ -+ struct ag71xx_mdio_platform_data *pdata; -+ struct ag71xx_mdio *am; -+ struct resource *res; -+ int i; + * +- * Copyright (c) 2010 Micrel, 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. +- * +- * Support : ksz9021 1000/100/10 phy from Micrel +- * ks8001, ks8737, ks8721, ks8041, ks8051 100/10 phy + */ + +-#include +-#include ++#include ++#include + #include +-#include + +-/* general Interrupt control/status reg in vendor specific block. */ +-#define MII_KSZPHY_INTCS 0x1B +-#define KSZPHY_INTCS_JABBER (1 << 15) +-#define KSZPHY_INTCS_RECEIVE_ERR (1 << 14) +-#define KSZPHY_INTCS_PAGE_RECEIVE (1 << 13) +-#define KSZPHY_INTCS_PARELLEL (1 << 12) +-#define KSZPHY_INTCS_LINK_PARTNER_ACK (1 << 11) +-#define KSZPHY_INTCS_LINK_DOWN (1 << 10) +-#define KSZPHY_INTCS_REMOTE_FAULT (1 << 9) +-#define KSZPHY_INTCS_LINK_UP (1 << 8) +-#define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\ +- KSZPHY_INTCS_LINK_DOWN) +- +-/* general PHY control reg in vendor specific block. */ +-#define MII_KSZPHY_CTRL 0x1F +-/* bitmap of PHY register to set interrupt mode */ +-#define KSZPHY_CTRL_INT_ACTIVE_HIGH (1 << 9) +-#define KSZ9021_CTRL_INT_ACTIVE_HIGH (1 << 14) +-#define KS8737_CTRL_INT_ACTIVE_HIGH (1 << 14) +-#define KSZ8051_RMII_50MHZ_CLK (1 << 7) ++#define KSZ_REG_INT_CTRL 0x1b + +-static int kszphy_ack_interrupt(struct phy_device *phydev) +-{ +- /* bit[7..0] int status, which is a read and clear register. */ +- int rc; ++#define KSZ_INT_LU_EN (1 << 8) /* enable Link Up interrupt */ ++#define KSZ_INT_RF_EN (1 << 9) /* enable Remote Fault interrupt */ ++#define KSZ_INT_LD_EN (1 << 10) /* enable Link Down interrupt */ + +- rc = phy_read(phydev, MII_KSZPHY_INTCS); +- +- return (rc < 0) ? rc : 0; +-} ++#define KSZ_INT_INIT (KSZ_INT_LU_EN | KSZ_INT_LD_EN) + +-static int kszphy_set_interrupt(struct phy_device *phydev) ++static int ksz8041_ack_interrupt(struct phy_device *phydev) + { +- int temp; +- temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ? +- KSZPHY_INTCS_ALL : 0; +- return phy_write(phydev, MII_KSZPHY_INTCS, temp); +-} + int err; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) { -+ dev_err(&pdev->dev, "no platform data specified\n"); -+ return -EINVAL; -+ } -+ -+ am = kzalloc(sizeof(*am), GFP_KERNEL); -+ if (!am) { -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ am->pdata = pdata; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "no iomem resource found\n"); -+ err = -ENXIO; -+ goto err_out; -+ } -+ -+ am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!am->mdio_base) { -+ dev_err(&pdev->dev, "unable to ioremap registers\n"); -+ err = -ENOMEM; -+ goto err_free_mdio; -+ } -+ -+ am->mii_bus = mdiobus_alloc(); -+ if (am->mii_bus == NULL) { -+ err = -ENOMEM; -+ goto err_iounmap; -+ } -+ -+ am->mii_bus->name = "ag71xx_mdio"; -+ am->mii_bus->read = ag71xx_mdio_read; -+ am->mii_bus->write = ag71xx_mdio_write; -+ am->mii_bus->reset = ag71xx_mdio_reset; -+ am->mii_bus->irq = am->mii_irq; -+ am->mii_bus->priv = am; -+ am->mii_bus->parent = &pdev->dev; -+ snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev)); -+ am->mii_bus->phy_mask = pdata->phy_mask; -+ -+ for (i = 0; i < PHY_MAX_ADDR; i++) -+ am->mii_irq[i] = PHY_POLL; -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0); -+ -+ err = mdiobus_register(am->mii_bus); -+ if (err) -+ goto err_free_bus; -+ -+ ag71xx_mdio_dump_regs(am); -+ -+ platform_set_drvdata(pdev, am); -+ return 0; -+ -+err_free_bus: -+ mdiobus_free(am->mii_bus); -+err_iounmap: -+ iounmap(am->mdio_base); -+err_free_mdio: -+ kfree(am); -+err_out: + +-static int kszphy_config_intr(struct phy_device *phydev) +-{ +- int temp, rc; ++ err = phy_read(phydev, KSZ_REG_INT_CTRL); + +- /* set the interrupt pin active low */ +- temp = phy_read(phydev, MII_KSZPHY_CTRL); +- temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH; +- phy_write(phydev, MII_KSZPHY_CTRL, temp); +- rc = kszphy_set_interrupt(phydev); +- return rc < 0 ? rc : 0; ++ return (err < 0) ? err : 0; + } + +-static int ksz9021_config_intr(struct phy_device *phydev) ++static int ksz8041_config_intr(struct phy_device *phydev) + { +- int temp, rc; ++ int err; + +- /* set the interrupt pin active low */ +- temp = phy_read(phydev, MII_KSZPHY_CTRL); +- temp &= ~KSZ9021_CTRL_INT_ACTIVE_HIGH; +- phy_write(phydev, MII_KSZPHY_CTRL, temp); +- rc = kszphy_set_interrupt(phydev); +- return rc < 0 ? rc : 0; +-} +- +-static int ks8737_config_intr(struct phy_device *phydev) +-{ +- int temp, rc; ++ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) ++ err = phy_write(phydev, KSZ_REG_INT_CTRL, ++ KSZ_INT_INIT); ++ else ++ err = phy_write(phydev, KSZ_REG_INT_CTRL, 0); + +- /* set the interrupt pin active low */ +- temp = phy_read(phydev, MII_KSZPHY_CTRL); +- temp &= ~KS8737_CTRL_INT_ACTIVE_HIGH; +- phy_write(phydev, MII_KSZPHY_CTRL, temp); +- rc = kszphy_set_interrupt(phydev); +- return rc < 0 ? rc : 0; + return err; -+} -+ -+static int __devexit ag71xx_mdio_remove(struct platform_device *pdev) -+{ -+ struct ag71xx_mdio *am = platform_get_drvdata(pdev); -+ -+ if (am) { -+ mdiobus_unregister(am->mii_bus); -+ mdiobus_free(am->mii_bus); -+ iounmap(am->mdio_base); -+ kfree(am); -+ platform_set_drvdata(pdev, NULL); -+ } -+ -+ return 0; -+} -+ -+static struct platform_driver ag71xx_mdio_driver = { -+ .probe = ag71xx_mdio_probe, -+ .remove = __exit_p(ag71xx_mdio_remove), -+ .driver = { -+ .name = "ag71xx-mdio", -+ } -+}; -+ -+int __init ag71xx_mdio_driver_init(void) -+{ -+ return platform_driver_register(&ag71xx_mdio_driver); -+} -+ -+void ag71xx_mdio_driver_exit(void) -+{ -+ platform_driver_unregister(&ag71xx_mdio_driver); -+} -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c ---- linux-2.6.39.orig/drivers/net/ag71xx/ag71xx_phy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/ag71xx_phy.c 2011-08-06 09:32:37.298018216 +0200 -@@ -0,0 +1,228 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ag71xx.h" -+ -+static void ag71xx_phy_link_adjust(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct phy_device *phydev = ag->phy_dev; -+ unsigned long flags; -+ int status_change = 0; -+ -+ spin_lock_irqsave(&ag->lock, flags); -+ -+ if (phydev->link) { -+ if (ag->duplex != phydev->duplex -+ || ag->speed != phydev->speed) { -+ status_change = 1; -+ } -+ } -+ -+ if (phydev->link != ag->link) -+ status_change = 1; -+ -+ ag->link = phydev->link; -+ ag->duplex = phydev->duplex; -+ ag->speed = phydev->speed; -+ -+ if (status_change) -+ ag71xx_link_adjust(ag); -+ -+ spin_unlock_irqrestore(&ag->lock, flags); -+} -+ -+void ag71xx_phy_start(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ -+ if (ag->phy_dev) { -+ phy_start(ag->phy_dev); -+ } else if (pdata->has_ar7240_switch) { -+ ag71xx_ar7240_start(ag); -+ } else { -+ ag->link = 1; -+ ag71xx_link_adjust(ag); -+ } -+} -+ -+void ag71xx_phy_stop(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ -+ if (ag->phy_dev) { -+ phy_stop(ag->phy_dev); -+ } else { -+ if (pdata->has_ar7240_switch) -+ ag71xx_ar7240_stop(ag); -+ ag->link = 0; -+ ag71xx_link_adjust(ag); -+ } -+} -+ -+static int ag71xx_phy_connect_fixed(struct ag71xx *ag) -+{ -+ struct net_device *dev = ag->dev; -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ int ret = 0; -+ -+ /* use fixed settings */ -+ switch (pdata->speed) { -+ case SPEED_10: -+ case SPEED_100: -+ case SPEED_1000: -+ break; -+ default: -+ printk(KERN_ERR "%s: invalid speed specified\n", dev->name); -+ ret = -EINVAL; -+ break; -+ } -+ -+ printk(KERN_DEBUG "%s: using fixed link parameters\n", dev->name); -+ -+ ag->duplex = pdata->duplex; -+ ag->speed = pdata->speed; -+ -+ return ret; -+} -+ -+static int ag71xx_phy_connect_multi(struct ag71xx *ag) -+{ -+ struct net_device *dev = ag->dev; -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct phy_device *phydev = NULL; -+ int phy_addr; -+ int ret = 0; -+ -+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { -+ if (!(pdata->phy_mask & (1 << phy_addr))) -+ continue; -+ -+ if (ag->mii_bus->phy_map[phy_addr] == NULL) -+ continue; -+ -+ DBG("%s: PHY found at %s, uid=%08x\n", -+ dev->name, -+ dev_name(&ag->mii_bus->phy_map[phy_addr]->dev), -+ ag->mii_bus->phy_map[phy_addr]->phy_id); -+ -+ if (phydev == NULL) -+ phydev = ag->mii_bus->phy_map[phy_addr]; -+ } -+ -+ if (!phydev) { -+ printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n", -+ dev->name, pdata->phy_mask); -+ return -ENODEV; -+ } -+ -+ ag->phy_dev = phy_connect(dev, dev_name(&phydev->dev), -+ &ag71xx_phy_link_adjust, 0, -+ pdata->phy_if_mode); -+ -+ if (IS_ERR(ag->phy_dev)) { -+ printk(KERN_ERR "%s: could not connect to PHY at %s\n", -+ dev->name, dev_name(&phydev->dev)); -+ return PTR_ERR(ag->phy_dev); -+ } -+ -+ /* mask with MAC supported features */ -+ if (pdata->has_gbit) -+ phydev->supported &= PHY_GBIT_FEATURES; -+ else -+ phydev->supported &= PHY_BASIC_FEATURES; -+ -+ phydev->advertising = phydev->supported; -+ -+ printk(KERN_DEBUG "%s: connected to PHY at %s [uid=%08x, driver=%s]\n", -+ dev->name, dev_name(&phydev->dev), -+ phydev->phy_id, phydev->drv->name); -+ -+ ag->link = 0; -+ ag->speed = 0; -+ ag->duplex = -1; -+ -+ return ret; -+} -+ -+static int dev_is_class(struct device *dev, void *class) -+{ -+ if (dev->class != NULL && !strcmp(dev->class->name, class)) -+ return 1; -+ -+ return 0; -+} -+ -+static struct device *dev_find_class(struct device *parent, char *class) -+{ -+ if (dev_is_class(parent, class)) { -+ get_device(parent); -+ return parent; -+ } -+ -+ return device_find_child(parent, class, dev_is_class); -+} -+ -+static struct mii_bus *dev_to_mii_bus(struct device *dev) -+{ -+ struct device *d; -+ -+ d = dev_find_class(dev, "mdio_bus"); -+ if (d != NULL) { -+ struct mii_bus *bus; -+ -+ bus = to_mii_bus(d); -+ put_device(d); -+ -+ return bus; -+ } -+ -+ return NULL; -+} -+ -+int __devinit ag71xx_phy_connect(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ -+ ag->mii_bus = dev_to_mii_bus(pdata->mii_bus_dev); -+ if (ag->mii_bus == NULL) { -+ printk(KERN_ERR "%s: unable to find MII bus on device '%s'\n", -+ ag->dev->name, dev_name(pdata->mii_bus_dev)); -+ return -ENODEV; -+ } -+ -+ /* Reset the mdio bus explicitly */ -+ if (ag->mii_bus->reset) { -+ mutex_lock(&ag->mii_bus->mdio_lock); -+ ag->mii_bus->reset(ag->mii_bus); -+ mutex_unlock(&ag->mii_bus->mdio_lock); -+ } -+ -+ if (pdata->has_ar7240_switch) -+ return ag71xx_ar7240_init(ag); -+ -+ if (pdata->phy_mask) -+ return ag71xx_phy_connect_multi(ag); -+ -+ return ag71xx_phy_connect_fixed(ag); -+} -+ -+void ag71xx_phy_disconnect(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ -+ if (pdata->has_ar7240_switch) -+ ag71xx_ar7240_cleanup(ag); -+ else if (ag->phy_dev) -+ phy_disconnect(ag->phy_dev); -+} -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Kconfig linux-2.6.39/drivers/net/ag71xx/Kconfig ---- linux-2.6.39.orig/drivers/net/ag71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/Kconfig 2011-04-27 12:19:22.247664026 +0200 -@@ -0,0 +1,33 @@ -+config AG71XX -+ tristate "Atheros AR71xx built-in ethernet mac support" -+ depends on ATHEROS_AR71XX -+ select PHYLIB -+ help -+ If you wish to compile a kernel for AR71xx/91xx and enable -+ ethernet support, then you should always answer Y to this. -+ -+if AG71XX -+ -+config AG71XX_DEBUG -+ bool "Atheros AR71xx built-in ethernet driver debugging" -+ default n -+ help -+ Atheros AR71xx built-in ethernet driver debugging messages. -+ -+config AG71XX_DEBUG_FS -+ bool "Atheros AR71xx built-in ethernet driver debugfs support" -+ depends on DEBUG_FS -+ default n -+ help -+ Say Y, if you need access to various statistics provided by -+ the ag71xx driver. -+ -+config AG71XX_AR8216_SUPPORT -+ bool "special support for the Atheros AR8216 switch" -+ default n -+ default y if AR71XX_MACH_WNR2000 || AR71XX_MACH_MZK_W04NU -+ help -+ Say 'y' here if you want to enable special support for the -+ Atheros AR8216 switch found on some boards. -+ -+endif -diff -Nur linux-2.6.39.orig/drivers/net/ag71xx/Makefile linux-2.6.39/drivers/net/ag71xx/Makefile ---- linux-2.6.39.orig/drivers/net/ag71xx/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/ag71xx/Makefile 2011-04-27 12:19:22.257663952 +0200 -@@ -0,0 +1,15 @@ -+# -+# Makefile for the Atheros AR71xx built-in ethernet macs -+# -+ -+ag71xx-y += ag71xx_main.o -+ag71xx-y += ag71xx_ethtool.o -+ag71xx-y += ag71xx_phy.o -+ag71xx-y += ag71xx_mdio.o -+ag71xx-y += ag71xx_ar7240.o -+ -+ag71xx-$(CONFIG_AG71XX_DEBUG_FS) += ag71xx_debugfs.o -+ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o -+ -+obj-$(CONFIG_AG71XX) += ag71xx.o -+ -diff -Nur linux-2.6.39.orig/drivers/net/Kconfig linux-2.6.39/drivers/net/Kconfig ---- linux-2.6.39.orig/drivers/net/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/Kconfig 2011-08-22 16:21:54.787979739 +0200 -@@ -2071,6 +2071,8 @@ - - The safe and default value for this is N. - -+source drivers/net/ag71xx/Kconfig -+ - config DL2K - tristate "DL2000/TC902x-based Gigabit Ethernet support" - depends on PCI -diff -Nur linux-2.6.39.orig/drivers/net/Makefile linux-2.6.39/drivers/net/Makefile ---- linux-2.6.39.orig/drivers/net/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/Makefile 2011-08-22 16:21:54.797980120 +0200 -@@ -112,6 +112,7 @@ - # end link order section - # - -+obj-$(CONFIG_AG71XX) += ag71xx/ - obj-$(CONFIG_SUNDANCE) += sundance.o - obj-$(CONFIG_HAMACHI) += hamachi.o - obj-$(CONFIG_NET) += Space.o loopback.o -diff -Nur linux-2.6.39.orig/drivers/net/phy/Kconfig linux-2.6.39/drivers/net/phy/Kconfig ---- linux-2.6.39.orig/drivers/net/phy/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/phy/Kconfig 2011-08-22 22:19:34.339230055 +0200 -@@ -13,6 +13,12 @@ - - if PHYLIB - -+config SWCONFIG -+ tristate "Switch configuration API" -+ ---help--- -+ Switch configuration API using netlink. This allows -+ you to configure the VLAN features of certain switches. -+ - comment "MII PHY device drivers" - - config MARVELL_PHY -diff -Nur linux-2.6.39.orig/drivers/net/phy/Makefile linux-2.6.39/drivers/net/phy/Makefile ---- linux-2.6.39.orig/drivers/net/phy/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/phy/Makefile 2011-08-22 22:19:34.339230055 +0200 -@@ -3,6 +3,7 @@ - libphy-objs := phy.o phy_device.o mdio_bus.o - - obj-$(CONFIG_PHYLIB) += libphy.o -+obj-$(CONFIG_SWCONFIG) += swconfig.o - obj-$(CONFIG_MARVELL_PHY) += marvell.o - obj-$(CONFIG_DAVICOM_PHY) += davicom.o - obj-$(CONFIG_CICADA_PHY) += cicada.o -diff -Nur linux-2.6.39.orig/drivers/net/phy/micrel.c linux-2.6.39/drivers/net/phy/micrel.c ---- linux-2.6.39.orig/drivers/net/phy/micrel.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/phy/micrel.c 2011-04-27 12:19:22.257663952 +0200 -@@ -1,251 +1,82 @@ - /* -- * drivers/net/phy/micrel.c -+ * Driver for Micrel/Kendin PHYs - * -- * Driver for Micrel PHYs -+ * Copyright (c) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz - * -- * Author: David J. Choi -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. - * -- * Copyright (c) 2010 Micrel, 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. -- * -- * Support : ksz9021 1000/100/10 phy from Micrel -- * ks8001, ks8737, ks8721, ks8041, ks8051 100/10 phy - */ - --#include --#include -+#include -+#include - #include --#include - --/* general Interrupt control/status reg in vendor specific block. */ --#define MII_KSZPHY_INTCS 0x1B --#define KSZPHY_INTCS_JABBER (1 << 15) --#define KSZPHY_INTCS_RECEIVE_ERR (1 << 14) --#define KSZPHY_INTCS_PAGE_RECEIVE (1 << 13) --#define KSZPHY_INTCS_PARELLEL (1 << 12) --#define KSZPHY_INTCS_LINK_PARTNER_ACK (1 << 11) --#define KSZPHY_INTCS_LINK_DOWN (1 << 10) --#define KSZPHY_INTCS_REMOTE_FAULT (1 << 9) --#define KSZPHY_INTCS_LINK_UP (1 << 8) --#define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\ -- KSZPHY_INTCS_LINK_DOWN) -- --/* general PHY control reg in vendor specific block. */ --#define MII_KSZPHY_CTRL 0x1F --/* bitmap of PHY register to set interrupt mode */ --#define KSZPHY_CTRL_INT_ACTIVE_HIGH (1 << 9) --#define KSZ9021_CTRL_INT_ACTIVE_HIGH (1 << 14) --#define KS8737_CTRL_INT_ACTIVE_HIGH (1 << 14) --#define KSZ8051_RMII_50MHZ_CLK (1 << 7) -+#define KSZ_REG_INT_CTRL 0x1b - --static int kszphy_ack_interrupt(struct phy_device *phydev) --{ -- /* bit[7..0] int status, which is a read and clear register. */ -- int rc; -+#define KSZ_INT_LU_EN (1 << 8) /* enable Link Up interrupt */ -+#define KSZ_INT_RF_EN (1 << 9) /* enable Remote Fault interrupt */ -+#define KSZ_INT_LD_EN (1 << 10) /* enable Link Down interrupt */ - -- rc = phy_read(phydev, MII_KSZPHY_INTCS); -- -- return (rc < 0) ? rc : 0; --} -+#define KSZ_INT_INIT (KSZ_INT_LU_EN | KSZ_INT_LD_EN) - --static int kszphy_set_interrupt(struct phy_device *phydev) -+static int ksz8041_ack_interrupt(struct phy_device *phydev) - { -- int temp; -- temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ? -- KSZPHY_INTCS_ALL : 0; -- return phy_write(phydev, MII_KSZPHY_INTCS, temp); --} -+ int err; - --static int kszphy_config_intr(struct phy_device *phydev) --{ -- int temp, rc; -+ err = phy_read(phydev, KSZ_REG_INT_CTRL); - -- /* set the interrupt pin active low */ -- temp = phy_read(phydev, MII_KSZPHY_CTRL); -- temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH; -- phy_write(phydev, MII_KSZPHY_CTRL, temp); -- rc = kszphy_set_interrupt(phydev); -- return rc < 0 ? rc : 0; -+ return (err < 0) ? err : 0; - } - --static int ksz9021_config_intr(struct phy_device *phydev) -+static int ksz8041_config_intr(struct phy_device *phydev) - { -- int temp, rc; -+ int err; - -- /* set the interrupt pin active low */ -- temp = phy_read(phydev, MII_KSZPHY_CTRL); -- temp &= ~KSZ9021_CTRL_INT_ACTIVE_HIGH; -- phy_write(phydev, MII_KSZPHY_CTRL, temp); -- rc = kszphy_set_interrupt(phydev); -- return rc < 0 ? rc : 0; --} -- --static int ks8737_config_intr(struct phy_device *phydev) --{ -- int temp, rc; -+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) -+ err = phy_write(phydev, KSZ_REG_INT_CTRL, -+ KSZ_INT_INIT); -+ else -+ err = phy_write(phydev, KSZ_REG_INT_CTRL, 0); - -- /* set the interrupt pin active low */ -- temp = phy_read(phydev, MII_KSZPHY_CTRL); -- temp &= ~KS8737_CTRL_INT_ACTIVE_HIGH; -- phy_write(phydev, MII_KSZPHY_CTRL, temp); -- rc = kszphy_set_interrupt(phydev); -- return rc < 0 ? rc : 0; -+ return err; - } - --static int kszphy_config_init(struct phy_device *phydev) --{ -- return 0; --} -- --static int ks8051_config_init(struct phy_device *phydev) --{ -- int regval; -- -- if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { -- regval = phy_read(phydev, MII_KSZPHY_CTRL); -- regval |= KSZ8051_RMII_50MHZ_CLK; -- phy_write(phydev, MII_KSZPHY_CTRL, regval); -- } -- -- return 0; --} -- --static struct phy_driver ks8737_driver = { -- .phy_id = PHY_ID_KS8737, -- .phy_id_mask = 0x00fffff0, -- .name = "Micrel KS8737", -- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), -- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, -- .config_init = kszphy_config_init, -+static struct phy_driver ksz8041_phy_driver = { -+ .phy_id = 0x00221512, -+ .name = "Micrel KSZ8041", -+ .phy_id_mask = 0x001fffff, -+ .features = PHY_BASIC_FEATURES, -+ .flags = PHY_HAS_INTERRUPT, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, -- .ack_interrupt = kszphy_ack_interrupt, -- .config_intr = ks8737_config_intr, -- .driver = { .owner = THIS_MODULE,}, -+ .ack_interrupt = ksz8041_ack_interrupt, -+ .config_intr = ksz8041_config_intr, -+ .driver = { -+ .owner = THIS_MODULE, -+ }, - }; - --static struct phy_driver ks8041_driver = { -- .phy_id = PHY_ID_KS8041, -- .phy_id_mask = 0x00fffff0, -- .name = "Micrel KS8041", -- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause -- | SUPPORTED_Asym_Pause), -- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, -- .config_init = kszphy_config_init, -- .config_aneg = genphy_config_aneg, -- .read_status = genphy_read_status, -- .ack_interrupt = kszphy_ack_interrupt, -- .config_intr = kszphy_config_intr, -- .driver = { .owner = THIS_MODULE,}, --}; -- --static struct phy_driver ks8051_driver = { -- .phy_id = PHY_ID_KS8051, -- .phy_id_mask = 0x00fffff0, -- .name = "Micrel KS8051", -- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause -- | SUPPORTED_Asym_Pause), -- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, -- .config_init = ks8051_config_init, -- .config_aneg = genphy_config_aneg, -- .read_status = genphy_read_status, -- .ack_interrupt = kszphy_ack_interrupt, -- .config_intr = kszphy_config_intr, -- .driver = { .owner = THIS_MODULE,}, --}; -- --static struct phy_driver ks8001_driver = { -- .phy_id = PHY_ID_KS8001, -- .name = "Micrel KS8001 or KS8721", -- .phy_id_mask = 0x00fffff0, -- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), -- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, -- .config_init = kszphy_config_init, -- .config_aneg = genphy_config_aneg, -- .read_status = genphy_read_status, -- .ack_interrupt = kszphy_ack_interrupt, -- .config_intr = kszphy_config_intr, -- .driver = { .owner = THIS_MODULE,}, --}; -- --static struct phy_driver ksz9021_driver = { -- .phy_id = PHY_ID_KSZ9021, -- .phy_id_mask = 0x000fff10, -- .name = "Micrel KSZ9021 Gigabit PHY", -- .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause -- | SUPPORTED_Asym_Pause), -- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, -- .config_init = kszphy_config_init, -- .config_aneg = genphy_config_aneg, -- .read_status = genphy_read_status, -- .ack_interrupt = kszphy_ack_interrupt, -- .config_intr = ksz9021_config_intr, -- .driver = { .owner = THIS_MODULE, }, --}; -- --static int __init ksphy_init(void) -+static int __init micrel_phy_init(void) - { -- int ret; -- -- ret = phy_driver_register(&ks8001_driver); -- if (ret) -- goto err1; -- -- ret = phy_driver_register(&ksz9021_driver); -- if (ret) -- goto err2; -- -- ret = phy_driver_register(&ks8737_driver); -- if (ret) -- goto err3; -- ret = phy_driver_register(&ks8041_driver); -- if (ret) -- goto err4; -- ret = phy_driver_register(&ks8051_driver); -- if (ret) -- goto err5; -- -- return 0; -- --err5: -- phy_driver_unregister(&ks8041_driver); --err4: -- phy_driver_unregister(&ks8737_driver); --err3: -- phy_driver_unregister(&ksz9021_driver); --err2: -- phy_driver_unregister(&ks8001_driver); --err1: -- return ret; -+ return phy_driver_register(&ksz8041_phy_driver); - } - --static void __exit ksphy_exit(void) -+static void __exit micrel_phy_exit(void) - { -- phy_driver_unregister(&ks8001_driver); -- phy_driver_unregister(&ks8737_driver); -- phy_driver_unregister(&ksz9021_driver); -- phy_driver_unregister(&ks8041_driver); -- phy_driver_unregister(&ks8051_driver); -+ phy_driver_unregister(&ksz8041_phy_driver); - } - --module_init(ksphy_init); --module_exit(ksphy_exit); -- --MODULE_DESCRIPTION("Micrel PHY driver"); --MODULE_AUTHOR("David J. Choi"); --MODULE_LICENSE("GPL"); -- --static struct mdio_device_id __maybe_unused micrel_tbl[] = { -- { PHY_ID_KSZ9021, 0x000fff10 }, -- { PHY_ID_KS8001, 0x00fffff0 }, -- { PHY_ID_KS8737, 0x00fffff0 }, -- { PHY_ID_KS8041, 0x00fffff0 }, -- { PHY_ID_KS8051, 0x00fffff0 }, -- { } --}; -+#ifdef MODULE -+module_init(micrel_phy_init); -+module_exit(micrel_phy_exit); -+#else -+subsys_initcall(micrel_phy_init); -+#endif - --MODULE_DEVICE_TABLE(mdio, micrel_tbl); -+MODULE_DESCRIPTION("Micrel/Kendin PHY driver"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_AUTHOR("Imre Kaloz "); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.39.orig/drivers/net/phy/phy.c linux-2.6.39/drivers/net/phy/phy.c ---- linux-2.6.39.orig/drivers/net/phy/phy.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/phy/phy.c 2011-08-22 22:00:02.067980292 +0200 -@@ -297,6 +297,50 @@ - } - EXPORT_SYMBOL(phy_ethtool_gset); - -+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr) -+{ -+ u32 cmd; -+ int tmp; -+ struct ethtool_cmd ecmd = { ETHTOOL_GSET }; -+ struct ethtool_value edata = { ETHTOOL_GLINK }; -+ -+ if (get_user(cmd, (u32 *) useraddr)) -+ return -EFAULT; -+ -+ switch (cmd) { -+ case ETHTOOL_GSET: -+ phy_ethtool_gset(phydev, &ecmd); -+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) -+ return -EFAULT; -+ return 0; -+ -+ case ETHTOOL_SSET: -+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) -+ return -EFAULT; -+ return phy_ethtool_sset(phydev, &ecmd); -+ -+ case ETHTOOL_NWAY_RST: -+ /* if autoneg is off, it's an error */ -+ tmp = phy_read(phydev, MII_BMCR); -+ if (tmp & BMCR_ANENABLE) { -+ tmp |= (BMCR_ANRESTART); -+ phy_write(phydev, MII_BMCR, tmp); -+ return 0; -+ } -+ return -EINVAL; -+ -+ case ETHTOOL_GLINK: -+ edata.data = (phy_read(phydev, -+ MII_BMSR) & BMSR_LSTATUS) ? 1 : 0; -+ if (copy_to_user(useraddr, &edata, sizeof(edata))) -+ return -EFAULT; -+ return 0; -+ } -+ -+ return -EOPNOTSUPP; -+} -+EXPORT_SYMBOL(phy_ethtool_ioctl); -+ - /** - * phy_mii_ioctl - generic PHY MII ioctl interface - * @phydev: the phy_device struct -@@ -472,7 +516,7 @@ - int idx; - - idx = phy_find_setting(phydev->speed, phydev->duplex); -- -+ - idx++; - - idx = phy_find_valid(idx, phydev->supported); -diff -Nur linux-2.6.39.orig/drivers/net/phy/phy_device.c linux-2.6.39/drivers/net/phy/phy_device.c ---- linux-2.6.39.orig/drivers/net/phy/phy_device.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/phy/phy_device.c 2011-08-22 22:00:06.817981347 +0200 -@@ -149,6 +149,18 @@ - } - EXPORT_SYMBOL(phy_scan_fixups); - -+static int generic_receive_skb(struct sk_buff *skb) -+{ -+ skb->protocol = eth_type_trans(skb, skb->dev); -+ return netif_receive_skb(skb); -+} -+ -+static int generic_rx(struct sk_buff *skb) -+{ -+ skb->protocol = eth_type_trans(skb, skb->dev); -+ return netif_rx(skb); -+} -+ - static struct phy_device* phy_device_create(struct mii_bus *bus, - int addr, int phy_id) - { -@@ -180,6 +192,8 @@ - dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr); - - dev->state = PHY_DOWN; -+ dev->netif_receive_skb = &generic_receive_skb; -+ dev->netif_rx = &generic_rx; - - mutex_init(&dev->lock); - INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); -diff -Nur linux-2.6.39.orig/drivers/net/phy/swconfig.c linux-2.6.39/drivers/net/phy/swconfig.c ---- linux-2.6.39.orig/drivers/net/phy/swconfig.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/net/phy/swconfig.c 2011-08-22 22:18:58.887990974 +0200 -@@ -0,0 +1,954 @@ -+/* -+ * swconfig.c: Switch configuration API -+ * -+ * Copyright (C) 2008 Felix Fietkau -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+//#define DEBUG 1 -+#ifdef DEBUG -+#define DPRINTF(format, ...) printk("%s: " format, __func__, ##__VA_ARGS__) -+#else -+#define DPRINTF(...) do {} while(0) -+#endif -+ -+#define SWCONFIG_DEVNAME "switch%d" -+ -+MODULE_AUTHOR("Felix Fietkau "); -+MODULE_LICENSE("GPL"); -+ -+static int swdev_id = 0; -+static struct list_head swdevs; -+static DEFINE_SPINLOCK(swdevs_lock); -+struct swconfig_callback; -+ -+struct swconfig_callback -+{ -+ struct sk_buff *msg; -+ struct genlmsghdr *hdr; -+ struct genl_info *info; -+ int cmd; -+ -+ /* callback for filling in the message data */ -+ int (*fill)(struct swconfig_callback *cb, void *arg); -+ -+ /* callback for closing the message before sending it */ -+ int (*close)(struct swconfig_callback *cb, void *arg); -+ -+ struct nlattr *nest[4]; -+ int args[4]; -+}; -+ -+/* defaults */ -+ -+static int -+swconfig_get_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ int ret; -+ if (val->port_vlan >= dev->vlans) -+ return -EINVAL; -+ -+ if (!dev->ops->get_vlan_ports) -+ return -EOPNOTSUPP; -+ -+ ret = dev->ops->get_vlan_ports(dev, val); -+ return ret; -+} -+ -+static int -+swconfig_set_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct switch_port *ports = val->value.ports; -+ const struct switch_dev_ops *ops = dev->ops; -+ int i; -+ -+ if (val->port_vlan >= dev->vlans) -+ return -EINVAL; -+ -+ /* validate ports */ -+ if (val->len > dev->ports) -+ return -EINVAL; -+ -+ if (!ops->set_vlan_ports) -+ return -EOPNOTSUPP; -+ -+ for (i = 0; i < val->len; i++) { -+ if (ports[i].id >= dev->ports) -+ return -EINVAL; -+ -+ if (ops->set_port_pvid && -+ !(ports[i].flags & (1 << SWITCH_PORT_FLAG_TAGGED))) -+ ops->set_port_pvid(dev, ports[i].id, val->port_vlan); -+ } -+ -+ return ops->set_vlan_ports(dev, val); -+} -+ -+static int -+swconfig_set_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ if (val->port_vlan >= dev->ports) -+ return -EINVAL; -+ -+ if (!dev->ops->set_port_pvid) -+ return -EOPNOTSUPP; -+ -+ return dev->ops->set_port_pvid(dev, val->port_vlan, val->value.i); -+} -+ -+static int -+swconfig_get_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ if (val->port_vlan >= dev->ports) -+ return -EINVAL; -+ -+ if (!dev->ops->get_port_pvid) -+ return -EOPNOTSUPP; -+ -+ return dev->ops->get_port_pvid(dev, val->port_vlan, &val->value.i); -+} -+ -+static int -+swconfig_apply_config(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ /* don't complain if not supported by the switch driver */ -+ if (!dev->ops->apply_config) -+ return 0; -+ -+ return dev->ops->apply_config(dev); -+} -+ -+static int -+swconfig_reset_switch(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ /* don't complain if not supported by the switch driver */ -+ if (!dev->ops->reset_switch) -+ return 0; -+ -+ return dev->ops->reset_switch(dev); -+} -+ -+enum global_defaults { -+ GLOBAL_APPLY, -+ GLOBAL_RESET, -+}; -+ -+enum vlan_defaults { -+ VLAN_PORTS, -+}; -+ -+enum port_defaults { -+ PORT_PVID, -+}; -+ -+static struct switch_attr default_global[] = { -+ [GLOBAL_APPLY] = { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "apply", -+ .description = "Activate changes in the hardware", -+ .set = swconfig_apply_config, -+ }, -+ [GLOBAL_RESET] = { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset", -+ .description = "Reset the switch", -+ .set = swconfig_reset_switch, -+ } -+}; -+ -+static struct switch_attr default_port[] = { -+ [PORT_PVID] = { -+ .type = SWITCH_TYPE_INT, -+ .name = "pvid", -+ .description = "Primary VLAN ID", -+ .set = swconfig_set_pvid, -+ .get = swconfig_get_pvid, -+ } -+}; -+ -+static struct switch_attr default_vlan[] = { -+ [VLAN_PORTS] = { -+ .type = SWITCH_TYPE_PORTS, -+ .name = "ports", -+ .description = "VLAN port mapping", -+ .set = swconfig_set_vlan_ports, -+ .get = swconfig_get_vlan_ports, -+ }, -+}; -+ -+ -+static void swconfig_defaults_init(struct switch_dev *dev) -+{ -+ const struct switch_dev_ops *ops = dev->ops; -+ -+ dev->def_global = 0; -+ dev->def_vlan = 0; -+ dev->def_port = 0; -+ -+ if (ops->get_vlan_ports || ops->set_vlan_ports) -+ set_bit(VLAN_PORTS, &dev->def_vlan); -+ -+ if (ops->get_port_pvid || ops->set_port_pvid) -+ set_bit(PORT_PVID, &dev->def_port); -+ -+ /* always present, can be no-op */ -+ set_bit(GLOBAL_APPLY, &dev->def_global); -+ set_bit(GLOBAL_RESET, &dev->def_global); -+} -+ -+ -+static struct genl_family switch_fam = { -+ .id = GENL_ID_GENERATE, -+ .name = "switch", -+ .hdrsize = 0, -+ .version = 1, -+ .maxattr = SWITCH_ATTR_MAX, -+}; -+ -+static const struct nla_policy switch_policy[SWITCH_ATTR_MAX+1] = { -+ [SWITCH_ATTR_ID] = { .type = NLA_U32 }, -+ [SWITCH_ATTR_OP_ID] = { .type = NLA_U32 }, -+ [SWITCH_ATTR_OP_PORT] = { .type = NLA_U32 }, -+ [SWITCH_ATTR_OP_VLAN] = { .type = NLA_U32 }, -+ [SWITCH_ATTR_OP_VALUE_INT] = { .type = NLA_U32 }, -+ [SWITCH_ATTR_OP_VALUE_STR] = { .type = NLA_NUL_STRING }, -+ [SWITCH_ATTR_OP_VALUE_PORTS] = { .type = NLA_NESTED }, -+ [SWITCH_ATTR_TYPE] = { .type = NLA_U32 }, -+}; -+ -+static const struct nla_policy port_policy[SWITCH_PORT_ATTR_MAX+1] = { -+ [SWITCH_PORT_ID] = { .type = NLA_U32 }, -+ [SWITCH_PORT_FLAG_TAGGED] = { .type = NLA_FLAG }, -+}; -+ -+static inline void -+swconfig_lock(void) -+{ -+ spin_lock(&swdevs_lock); -+} -+ -+static inline void -+swconfig_unlock(void) -+{ -+ spin_unlock(&swdevs_lock); -+} -+ -+static struct switch_dev * -+swconfig_get_dev(struct genl_info *info) -+{ -+ struct switch_dev *dev = NULL; -+ struct switch_dev *p; -+ int id; -+ -+ if (!info->attrs[SWITCH_ATTR_ID]) -+ goto done; -+ -+ id = nla_get_u32(info->attrs[SWITCH_ATTR_ID]); -+ swconfig_lock(); -+ list_for_each_entry(p, &swdevs, dev_list) { -+ if (id != p->id) -+ continue; -+ -+ dev = p; -+ break; -+ } -+ if (dev) -+ spin_lock(&dev->lock); -+ else -+ DPRINTF("device %d not found\n", id); -+ swconfig_unlock(); -+done: -+ return dev; -+} -+ -+static inline void -+swconfig_put_dev(struct switch_dev *dev) -+{ -+ spin_unlock(&dev->lock); -+} -+ -+static int -+swconfig_dump_attr(struct swconfig_callback *cb, void *arg) -+{ -+ struct switch_attr *op = arg; -+ struct genl_info *info = cb->info; -+ struct sk_buff *msg = cb->msg; -+ int id = cb->args[0]; -+ void *hdr; -+ -+ hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, &switch_fam, -+ NLM_F_MULTI, SWITCH_CMD_NEW_ATTR); -+ if (IS_ERR(hdr)) -+ return -1; -+ -+ NLA_PUT_U32(msg, SWITCH_ATTR_OP_ID, id); -+ NLA_PUT_U32(msg, SWITCH_ATTR_OP_TYPE, op->type); -+ NLA_PUT_STRING(msg, SWITCH_ATTR_OP_NAME, op->name); -+ if (op->description) -+ NLA_PUT_STRING(msg, SWITCH_ATTR_OP_DESCRIPTION, -+ op->description); -+ -+ return genlmsg_end(msg, hdr); -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+/* spread multipart messages across multiple message buffers */ -+static int -+swconfig_send_multipart(struct swconfig_callback *cb, void *arg) -+{ -+ struct genl_info *info = cb->info; -+ int restart = 0; -+ int err; -+ -+ do { -+ if (!cb->msg) { -+ cb->msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); -+ if (cb->msg == NULL) -+ goto error; -+ } -+ -+ if (!(cb->fill(cb, arg) < 0)) -+ break; -+ -+ /* fill failed, check if this was already the second attempt */ -+ if (restart) -+ goto error; -+ -+ /* try again in a new message, send the current one */ -+ restart = 1; -+ if (cb->close) { -+ if (cb->close(cb, arg) < 0) -+ goto error; -+ } -+ err = genlmsg_reply(cb->msg, info); -+ cb->msg = NULL; -+ if (err < 0) -+ goto error; -+ -+ } while (restart); -+ -+ return 0; -+ -+error: -+ if (cb->msg) -+ nlmsg_free(cb->msg); -+ return -1; -+} -+ -+static int -+swconfig_list_attrs(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); -+ const struct switch_attrlist *alist; -+ struct switch_dev *dev; -+ struct swconfig_callback cb; -+ int err = -EINVAL; -+ int i; -+ -+ /* defaults */ -+ struct switch_attr *def_list; -+ unsigned long *def_active; -+ int n_def; -+ -+ dev = swconfig_get_dev(info); -+ if (!dev) -+ return -EINVAL; -+ -+ switch(hdr->cmd) { -+ case SWITCH_CMD_LIST_GLOBAL: -+ alist = &dev->ops->attr_global; -+ def_list = default_global; -+ def_active = &dev->def_global; -+ n_def = ARRAY_SIZE(default_global); -+ break; -+ case SWITCH_CMD_LIST_VLAN: -+ alist = &dev->ops->attr_vlan; -+ def_list = default_vlan; -+ def_active = &dev->def_vlan; -+ n_def = ARRAY_SIZE(default_vlan); -+ break; -+ case SWITCH_CMD_LIST_PORT: -+ alist = &dev->ops->attr_port; -+ def_list = default_port; -+ def_active = &dev->def_port; -+ n_def = ARRAY_SIZE(default_port); -+ break; -+ default: -+ WARN_ON(1); -+ goto out; -+ } -+ -+ memset(&cb, 0, sizeof(cb)); -+ cb.info = info; -+ cb.fill = swconfig_dump_attr; -+ for (i = 0; i < alist->n_attr; i++) { -+ if (alist->attr[i].disabled) -+ continue; -+ cb.args[0] = i; -+ err = swconfig_send_multipart(&cb, (void *) &alist->attr[i]); -+ if (err < 0) -+ goto error; -+ } -+ -+ /* defaults */ -+ for (i = 0; i < n_def; i++) { -+ if (!test_bit(i, def_active)) -+ continue; -+ cb.args[0] = SWITCH_ATTR_DEFAULTS_OFFSET + i; -+ err = swconfig_send_multipart(&cb, (void *) &def_list[i]); -+ if (err < 0) -+ goto error; -+ } -+ swconfig_put_dev(dev); -+ -+ if (!cb.msg) -+ return 0; -+ -+ return genlmsg_reply(cb.msg, info); -+ -+error: -+ if (cb.msg) -+ nlmsg_free(cb.msg); -+out: -+ swconfig_put_dev(dev); -+ return err; -+} -+ -+static const struct switch_attr * -+swconfig_lookup_attr(struct switch_dev *dev, struct genl_info *info, -+ struct switch_val *val) -+{ -+ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); -+ const struct switch_attrlist *alist; -+ const struct switch_attr *attr = NULL; -+ int attr_id; -+ -+ /* defaults */ -+ struct switch_attr *def_list; -+ unsigned long *def_active; -+ int n_def; -+ -+ if (!info->attrs[SWITCH_ATTR_OP_ID]) -+ goto done; -+ -+ switch(hdr->cmd) { -+ case SWITCH_CMD_SET_GLOBAL: -+ case SWITCH_CMD_GET_GLOBAL: -+ alist = &dev->ops->attr_global; -+ def_list = default_global; -+ def_active = &dev->def_global; -+ n_def = ARRAY_SIZE(default_global); -+ break; -+ case SWITCH_CMD_SET_VLAN: -+ case SWITCH_CMD_GET_VLAN: -+ alist = &dev->ops->attr_vlan; -+ def_list = default_vlan; -+ def_active = &dev->def_vlan; -+ n_def = ARRAY_SIZE(default_vlan); -+ if (!info->attrs[SWITCH_ATTR_OP_VLAN]) -+ goto done; -+ val->port_vlan = nla_get_u32(info->attrs[SWITCH_ATTR_OP_VLAN]); -+ if (val->port_vlan >= dev->vlans) -+ goto done; -+ break; -+ case SWITCH_CMD_SET_PORT: -+ case SWITCH_CMD_GET_PORT: -+ alist = &dev->ops->attr_port; -+ def_list = default_port; -+ def_active = &dev->def_port; -+ n_def = ARRAY_SIZE(default_port); -+ if (!info->attrs[SWITCH_ATTR_OP_PORT]) -+ goto done; -+ val->port_vlan = nla_get_u32(info->attrs[SWITCH_ATTR_OP_PORT]); -+ if (val->port_vlan >= dev->ports) -+ goto done; -+ break; -+ default: -+ WARN_ON(1); -+ goto done; -+ } -+ -+ if (!alist) -+ goto done; -+ -+ attr_id = nla_get_u32(info->attrs[SWITCH_ATTR_OP_ID]); -+ if (attr_id >= SWITCH_ATTR_DEFAULTS_OFFSET) { -+ attr_id -= SWITCH_ATTR_DEFAULTS_OFFSET; -+ if (attr_id >= n_def) -+ goto done; -+ if (!test_bit(attr_id, def_active)) -+ goto done; -+ attr = &def_list[attr_id]; -+ } else { -+ if (attr_id >= alist->n_attr) -+ goto done; -+ attr = &alist->attr[attr_id]; -+ } -+ -+ if (attr->disabled) -+ attr = NULL; -+ -+done: -+ if (!attr) -+ DPRINTF("attribute lookup failed\n"); -+ val->attr = attr; -+ return attr; -+} -+ -+static int -+swconfig_parse_ports(struct sk_buff *msg, struct nlattr *head, -+ struct switch_val *val, int max) -+{ -+ struct nlattr *nla; -+ int rem; -+ -+ val->len = 0; -+ nla_for_each_nested(nla, head, rem) { -+ struct nlattr *tb[SWITCH_PORT_ATTR_MAX+1]; -+ struct switch_port *port = &val->value.ports[val->len]; -+ -+ if (val->len >= max) -+ return -EINVAL; -+ -+ if (nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, nla, -+ port_policy)) -+ return -EINVAL; -+ -+ if (!tb[SWITCH_PORT_ID]) -+ return -EINVAL; -+ -+ port->id = nla_get_u32(tb[SWITCH_PORT_ID]); -+ if (tb[SWITCH_PORT_FLAG_TAGGED]) -+ port->flags |= (1 << SWITCH_PORT_FLAG_TAGGED); -+ val->len++; -+ } -+ -+ return 0; -+} -+ -+static int -+swconfig_set_attr(struct sk_buff *skb, struct genl_info *info) -+{ -+ const struct switch_attr *attr; -+ struct switch_dev *dev; -+ struct switch_val val; -+ int err = -EINVAL; -+ -+ dev = swconfig_get_dev(info); -+ if (!dev) -+ return -EINVAL; -+ -+ memset(&val, 0, sizeof(val)); -+ attr = swconfig_lookup_attr(dev, info, &val); -+ if (!attr || !attr->set) -+ goto error; -+ -+ val.attr = attr; -+ switch(attr->type) { -+ case SWITCH_TYPE_NOVAL: -+ break; -+ case SWITCH_TYPE_INT: -+ if (!info->attrs[SWITCH_ATTR_OP_VALUE_INT]) -+ goto error; -+ val.value.i = -+ nla_get_u32(info->attrs[SWITCH_ATTR_OP_VALUE_INT]); -+ break; -+ case SWITCH_TYPE_STRING: -+ if (!info->attrs[SWITCH_ATTR_OP_VALUE_STR]) -+ goto error; -+ val.value.s = -+ nla_data(info->attrs[SWITCH_ATTR_OP_VALUE_STR]); -+ break; -+ case SWITCH_TYPE_PORTS: -+ val.value.ports = dev->portbuf; -+ memset(dev->portbuf, 0, -+ sizeof(struct switch_port) * dev->ports); -+ -+ /* TODO: implement multipart? */ -+ if (info->attrs[SWITCH_ATTR_OP_VALUE_PORTS]) { -+ err = swconfig_parse_ports(skb, -+ info->attrs[SWITCH_ATTR_OP_VALUE_PORTS], &val, dev->ports); -+ if (err < 0) -+ goto error; -+ } else { -+ val.len = 0; -+ err = 0; -+ } -+ break; -+ default: -+ goto error; -+ } -+ -+ err = attr->set(dev, attr, &val); -+error: -+ swconfig_put_dev(dev); -+ return err; -+} -+ -+static int -+swconfig_close_portlist(struct swconfig_callback *cb, void *arg) -+{ -+ if (cb->nest[0]) -+ nla_nest_end(cb->msg, cb->nest[0]); -+ return 0; -+} -+ -+static int -+swconfig_send_port(struct swconfig_callback *cb, void *arg) -+{ -+ const struct switch_port *port = arg; -+ struct nlattr *p = NULL; -+ -+ if (!cb->nest[0]) { -+ cb->nest[0] = nla_nest_start(cb->msg, cb->cmd); -+ if (!cb->nest[0]) -+ return -1; -+ } -+ -+ p = nla_nest_start(cb->msg, SWITCH_ATTR_PORT); -+ if (!p) -+ goto error; -+ -+ NLA_PUT_U32(cb->msg, SWITCH_PORT_ID, port->id); -+ if (port->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) -+ NLA_PUT_FLAG(cb->msg, SWITCH_PORT_FLAG_TAGGED); -+ -+ nla_nest_end(cb->msg, p); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(cb->msg, p); -+error: -+ nla_nest_cancel(cb->msg, cb->nest[0]); -+ return -1; -+} -+ -+static int -+swconfig_send_ports(struct sk_buff **msg, struct genl_info *info, int attr, -+ const struct switch_val *val) + } + +-static int kszphy_config_init(struct phy_device *phydev) +-{ +- return 0; +-} +- +-static int ks8051_config_init(struct phy_device *phydev) +-{ +- int regval; +- +- if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { +- regval = phy_read(phydev, MII_KSZPHY_CTRL); +- regval |= KSZ8051_RMII_50MHZ_CLK; +- phy_write(phydev, MII_KSZPHY_CTRL, regval); +- } +- +- return 0; +-} +- +-static struct phy_driver ks8737_driver = { +- .phy_id = PHY_ID_KS8737, +- .phy_id_mask = 0x00fffff0, +- .name = "Micrel KS8737", +- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), +- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, +- .config_init = kszphy_config_init, ++static struct phy_driver ksz8041_phy_driver = { ++ .phy_id = 0x00221512, ++ .name = "Micrel KSZ8041", ++ .phy_id_mask = 0x001fffff, ++ .features = PHY_BASIC_FEATURES, ++ .flags = PHY_HAS_INTERRUPT, + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, +- .ack_interrupt = kszphy_ack_interrupt, +- .config_intr = ks8737_config_intr, +- .driver = { .owner = THIS_MODULE,}, ++ .ack_interrupt = ksz8041_ack_interrupt, ++ .config_intr = ksz8041_config_intr, ++ .driver = { ++ .owner = THIS_MODULE, ++ }, + }; + +-static struct phy_driver ks8041_driver = { +- .phy_id = PHY_ID_KS8041, +- .phy_id_mask = 0x00fffff0, +- .name = "Micrel KS8041", +- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause +- | SUPPORTED_Asym_Pause), +- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, +- .config_init = kszphy_config_init, +- .config_aneg = genphy_config_aneg, +- .read_status = genphy_read_status, +- .ack_interrupt = kszphy_ack_interrupt, +- .config_intr = kszphy_config_intr, +- .driver = { .owner = THIS_MODULE,}, +-}; +- +-static struct phy_driver ks8051_driver = { +- .phy_id = PHY_ID_KS8051, +- .phy_id_mask = 0x00fffff0, +- .name = "Micrel KS8051", +- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause +- | SUPPORTED_Asym_Pause), +- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, +- .config_init = ks8051_config_init, +- .config_aneg = genphy_config_aneg, +- .read_status = genphy_read_status, +- .ack_interrupt = kszphy_ack_interrupt, +- .config_intr = kszphy_config_intr, +- .driver = { .owner = THIS_MODULE,}, +-}; +- +-static struct phy_driver ks8001_driver = { +- .phy_id = PHY_ID_KS8001, +- .name = "Micrel KS8001 or KS8721", +- .phy_id_mask = 0x00fffff0, +- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), +- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, +- .config_init = kszphy_config_init, +- .config_aneg = genphy_config_aneg, +- .read_status = genphy_read_status, +- .ack_interrupt = kszphy_ack_interrupt, +- .config_intr = kszphy_config_intr, +- .driver = { .owner = THIS_MODULE,}, +-}; +- +-static struct phy_driver ksz9021_driver = { +- .phy_id = PHY_ID_KSZ9021, +- .phy_id_mask = 0x000fff10, +- .name = "Micrel KSZ9021 Gigabit PHY", +- .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause +- | SUPPORTED_Asym_Pause), +- .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, +- .config_init = kszphy_config_init, +- .config_aneg = genphy_config_aneg, +- .read_status = genphy_read_status, +- .ack_interrupt = kszphy_ack_interrupt, +- .config_intr = ksz9021_config_intr, +- .driver = { .owner = THIS_MODULE, }, +-}; +- +-static int __init ksphy_init(void) ++static int __init micrel_phy_init(void) + { +- int ret; +- +- ret = phy_driver_register(&ks8001_driver); +- if (ret) +- goto err1; +- +- ret = phy_driver_register(&ksz9021_driver); +- if (ret) +- goto err2; +- +- ret = phy_driver_register(&ks8737_driver); +- if (ret) +- goto err3; +- ret = phy_driver_register(&ks8041_driver); +- if (ret) +- goto err4; +- ret = phy_driver_register(&ks8051_driver); +- if (ret) +- goto err5; +- +- return 0; +- +-err5: +- phy_driver_unregister(&ks8041_driver); +-err4: +- phy_driver_unregister(&ks8737_driver); +-err3: +- phy_driver_unregister(&ksz9021_driver); +-err2: +- phy_driver_unregister(&ks8001_driver); +-err1: +- return ret; ++ return phy_driver_register(&ksz8041_phy_driver); + } + +-static void __exit ksphy_exit(void) ++static void __exit micrel_phy_exit(void) + { +- phy_driver_unregister(&ks8001_driver); +- phy_driver_unregister(&ks8737_driver); +- phy_driver_unregister(&ksz9021_driver); +- phy_driver_unregister(&ks8041_driver); +- phy_driver_unregister(&ks8051_driver); ++ phy_driver_unregister(&ksz8041_phy_driver); + } + +-module_init(ksphy_init); +-module_exit(ksphy_exit); +- +-MODULE_DESCRIPTION("Micrel PHY driver"); +-MODULE_AUTHOR("David J. Choi"); +-MODULE_LICENSE("GPL"); +- +-static struct mdio_device_id __maybe_unused micrel_tbl[] = { +- { PHY_ID_KSZ9021, 0x000fff10 }, +- { PHY_ID_KS8001, 0x00fffff0 }, +- { PHY_ID_KS8737, 0x00fffff0 }, +- { PHY_ID_KS8041, 0x00fffff0 }, +- { PHY_ID_KS8051, 0x00fffff0 }, +- { } +-}; ++#ifdef MODULE ++module_init(micrel_phy_init); ++module_exit(micrel_phy_exit); ++#else ++subsys_initcall(micrel_phy_init); ++#endif + +-MODULE_DEVICE_TABLE(mdio, micrel_tbl); ++MODULE_DESCRIPTION("Micrel/Kendin PHY driver"); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_AUTHOR("Imre Kaloz "); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-2.6.39.orig/drivers/net/phy/phy.c linux-2.6.39/drivers/net/phy/phy.c +--- linux-2.6.39.orig/drivers/net/phy/phy.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/phy/phy.c 2011-08-24 18:17:24.000000000 +0200 +@@ -297,6 +297,50 @@ + } + EXPORT_SYMBOL(phy_ethtool_gset); + ++int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr) +{ -+ struct swconfig_callback cb; -+ int err = 0; -+ int i; -+ -+ if (!val->value.ports) -+ return -EINVAL; -+ -+ memset(&cb, 0, sizeof(cb)); -+ cb.cmd = attr; -+ cb.msg = *msg; -+ cb.info = info; -+ cb.fill = swconfig_send_port; -+ cb.close = swconfig_close_portlist; ++ u32 cmd; ++ int tmp; ++ struct ethtool_cmd ecmd = { ETHTOOL_GSET }; ++ struct ethtool_value edata = { ETHTOOL_GLINK }; + -+ cb.nest[0] = nla_nest_start(cb.msg, cb.cmd); -+ for (i = 0; i < val->len; i++) { -+ err = swconfig_send_multipart(&cb, &val->value.ports[i]); -+ if (err) -+ goto done; -+ } -+ err = val->len; -+ swconfig_close_portlist(&cb, NULL); -+ *msg = cb.msg; ++ if (get_user(cmd, (u32 *) useraddr)) ++ return -EFAULT; + -+done: -+ return err; -+} ++ switch (cmd) { ++ case ETHTOOL_GSET: ++ phy_ethtool_gset(phydev, &ecmd); ++ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) ++ return -EFAULT; ++ return 0; + -+static int -+swconfig_get_attr(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); -+ const struct switch_attr *attr; -+ struct switch_dev *dev; -+ struct sk_buff *msg = NULL; -+ struct switch_val val; -+ int err = -EINVAL; -+ int cmd = hdr->cmd; ++ case ETHTOOL_SSET: ++ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) ++ return -EFAULT; ++ return phy_ethtool_sset(phydev, &ecmd); + -+ dev = swconfig_get_dev(info); -+ if (!dev) ++ case ETHTOOL_NWAY_RST: ++ /* if autoneg is off, it's an error */ ++ tmp = phy_read(phydev, MII_BMCR); ++ if (tmp & BMCR_ANENABLE) { ++ tmp |= (BMCR_ANRESTART); ++ phy_write(phydev, MII_BMCR, tmp); ++ return 0; ++ } + return -EINVAL; + -+ memset(&val, 0, sizeof(val)); -+ attr = swconfig_lookup_attr(dev, info, &val); -+ if (!attr || !attr->get) -+ goto error; -+ -+ if (attr->type == SWITCH_TYPE_PORTS) { -+ val.value.ports = dev->portbuf; -+ memset(dev->portbuf, 0, -+ sizeof(struct switch_port) * dev->ports); ++ case ETHTOOL_GLINK: ++ edata.data = (phy_read(phydev, ++ MII_BMSR) & BMSR_LSTATUS) ? 1 : 0; ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; + } + -+ err = attr->get(dev, attr, &val); -+ if (err) -+ goto error; ++ return -EOPNOTSUPP; ++} ++EXPORT_SYMBOL(phy_ethtool_ioctl); + -+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); -+ if (!msg) -+ goto error; + /** + * phy_mii_ioctl - generic PHY MII ioctl interface + * @phydev: the phy_device struct +@@ -472,7 +516,7 @@ + int idx; + + idx = phy_find_setting(phydev->speed, phydev->duplex); +- + -+ hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, &switch_fam, -+ 0, cmd); -+ if (IS_ERR(hdr)) -+ goto nla_put_failure; + idx++; + + idx = phy_find_valid(idx, phydev->supported); +diff -Nur linux-2.6.39.orig/drivers/net/phy/phy_device.c linux-2.6.39/drivers/net/phy/phy_device.c +--- linux-2.6.39.orig/drivers/net/phy/phy_device.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/net/phy/phy_device.c 2011-08-24 18:17:24.000000000 +0200 +@@ -149,6 +149,18 @@ + } + EXPORT_SYMBOL(phy_scan_fixups); + ++static int generic_receive_skb(struct sk_buff *skb) ++{ ++ skb->protocol = eth_type_trans(skb, skb->dev); ++ return netif_receive_skb(skb); ++} + -+ switch(attr->type) { -+ case SWITCH_TYPE_INT: -+ NLA_PUT_U32(msg, SWITCH_ATTR_OP_VALUE_INT, val.value.i); -+ break; -+ case SWITCH_TYPE_STRING: -+ NLA_PUT_STRING(msg, SWITCH_ATTR_OP_VALUE_STR, val.value.s); -+ break; -+ case SWITCH_TYPE_PORTS: -+ err = swconfig_send_ports(&msg, info, -+ SWITCH_ATTR_OP_VALUE_PORTS, &val); -+ if (err < 0) -+ goto nla_put_failure; -+ break; -+ default: -+ DPRINTF("invalid type in attribute\n"); -+ err = -EINVAL; -+ goto error; -+ } -+ err = genlmsg_end(msg, hdr); -+ if (err < 0) -+ goto nla_put_failure; ++static int generic_rx(struct sk_buff *skb) ++{ ++ skb->protocol = eth_type_trans(skb, skb->dev); ++ return netif_rx(skb); ++} + -+ swconfig_put_dev(dev); -+ return genlmsg_reply(msg, info); + static struct phy_device* phy_device_create(struct mii_bus *bus, + int addr, int phy_id) + { +@@ -180,6 +192,8 @@ + dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr); + + dev->state = PHY_DOWN; ++ dev->netif_receive_skb = &generic_receive_skb; ++ dev->netif_rx = &generic_rx; + + mutex_init(&dev->lock); + INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); +diff -Nur linux-2.6.39.orig/drivers/net/phy/swconfig.c linux-2.6.39/drivers/net/phy/swconfig.c +--- linux-2.6.39.orig/drivers/net/phy/swconfig.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/net/phy/swconfig.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,954 @@ ++/* ++ * swconfig.c: Switch configuration API ++ * ++ * Copyright (C) 2008 Felix Fietkau ++ * ++ * 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. ++ */ + -+nla_put_failure: -+ if (msg) -+ nlmsg_free(msg); -+error: -+ swconfig_put_dev(dev); -+ if (!err) -+ err = -ENOMEM; -+ return err; -+} ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+static int -+swconfig_send_switch(struct sk_buff *msg, u32 pid, u32 seq, int flags, -+ const struct switch_dev *dev) -+{ -+ void *hdr; ++//#define DEBUG 1 ++#ifdef DEBUG ++#define DPRINTF(format, ...) printk("%s: " format, __func__, ##__VA_ARGS__) ++#else ++#define DPRINTF(...) do {} while(0) ++#endif + -+ hdr = genlmsg_put(msg, pid, seq, &switch_fam, flags, -+ SWITCH_CMD_NEW_ATTR); -+ if (IS_ERR(hdr)) -+ return -1; ++#define SWCONFIG_DEVNAME "switch%d" + -+ NLA_PUT_U32(msg, SWITCH_ATTR_ID, dev->id); -+ NLA_PUT_STRING(msg, SWITCH_ATTR_DEV_NAME, dev->devname); -+ NLA_PUT_STRING(msg, SWITCH_ATTR_ALIAS, dev->alias); -+ NLA_PUT_STRING(msg, SWITCH_ATTR_NAME, dev->name); -+ NLA_PUT_U32(msg, SWITCH_ATTR_VLANS, dev->vlans); -+ NLA_PUT_U32(msg, SWITCH_ATTR_PORTS, dev->ports); -+ NLA_PUT_U32(msg, SWITCH_ATTR_CPU_PORT, dev->cpu_port); ++MODULE_AUTHOR("Felix Fietkau "); ++MODULE_LICENSE("GPL"); + -+ return genlmsg_end(msg, hdr); -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} ++static int swdev_id = 0; ++static struct list_head swdevs; ++static DEFINE_SPINLOCK(swdevs_lock); ++struct swconfig_callback; + -+static int swconfig_dump_switches(struct sk_buff *skb, -+ struct netlink_callback *cb) ++struct swconfig_callback +{ -+ struct switch_dev *dev; -+ int start = cb->args[0]; -+ int idx = 0; ++ struct sk_buff *msg; ++ struct genlmsghdr *hdr; ++ struct genl_info *info; ++ int cmd; + -+ swconfig_lock(); -+ list_for_each_entry(dev, &swdevs, dev_list) { -+ if (++idx <= start) -+ continue; -+ if (swconfig_send_switch(skb, NETLINK_CB(cb->skb).pid, -+ cb->nlh->nlmsg_seq, NLM_F_MULTI, -+ dev) < 0) -+ break; -+ } -+ swconfig_unlock(); -+ cb->args[0] = idx; ++ /* callback for filling in the message data */ ++ int (*fill)(struct swconfig_callback *cb, void *arg); + -+ return skb->len; -+} ++ /* callback for closing the message before sending it */ ++ int (*close)(struct swconfig_callback *cb, void *arg); ++ ++ struct nlattr *nest[4]; ++ int args[4]; ++}; ++ ++/* defaults */ + +static int -+swconfig_done(struct netlink_callback *cb) ++swconfig_get_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) +{ -+ return 0; -+} ++ int ret; ++ if (val->port_vlan >= dev->vlans) ++ return -EINVAL; + -+static struct genl_ops swconfig_ops[] = { -+ { -+ .cmd = SWITCH_CMD_LIST_GLOBAL, -+ .doit = swconfig_list_attrs, -+ .policy = switch_policy, -+ }, -+ { -+ .cmd = SWITCH_CMD_LIST_VLAN, -+ .doit = swconfig_list_attrs, -+ .policy = switch_policy, -+ }, -+ { -+ .cmd = SWITCH_CMD_LIST_PORT, -+ .doit = swconfig_list_attrs, -+ .policy = switch_policy, -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_GLOBAL, -+ .doit = swconfig_get_attr, -+ .policy = switch_policy, -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_VLAN, -+ .doit = swconfig_get_attr, -+ .policy = switch_policy, -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_PORT, -+ .doit = swconfig_get_attr, -+ .policy = switch_policy, -+ }, -+ { -+ .cmd = SWITCH_CMD_SET_GLOBAL, -+ .doit = swconfig_set_attr, -+ .policy = switch_policy, -+ }, -+ { -+ .cmd = SWITCH_CMD_SET_VLAN, -+ .doit = swconfig_set_attr, -+ .policy = switch_policy, -+ }, -+ { -+ .cmd = SWITCH_CMD_SET_PORT, -+ .doit = swconfig_set_attr, -+ .policy = switch_policy, -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_SWITCH, -+ .dumpit = swconfig_dump_switches, -+ .policy = switch_policy, -+ .done = swconfig_done, -+ } -+}; ++ if (!dev->ops->get_vlan_ports) ++ return -EOPNOTSUPP; + -+int -+register_switch(struct switch_dev *dev, struct net_device *netdev) ++ ret = dev->ops->get_vlan_ports(dev, val); ++ return ret; ++} ++ ++static int ++swconfig_set_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) +{ -+ struct switch_dev *sdev; -+ const int max_switches = 8 * sizeof(unsigned long); -+ unsigned long in_use = 0; ++ struct switch_port *ports = val->value.ports; ++ const struct switch_dev_ops *ops = dev->ops; + int i; + -+ INIT_LIST_HEAD(&dev->dev_list); -+ if (netdev) { -+ dev->netdev = netdev; -+ if (!dev->alias) -+ dev->alias = netdev->name; -+ } -+ BUG_ON(!dev->alias); -+ -+ if (dev->ports > 0) { -+ dev->portbuf = kzalloc(sizeof(struct switch_port) * dev->ports, -+ GFP_KERNEL); -+ if (!dev->portbuf) -+ return -ENOMEM; -+ } -+ swconfig_defaults_init(dev); -+ spin_lock_init(&dev->lock); -+ swconfig_lock(); -+ dev->id = ++swdev_id; -+ -+ list_for_each_entry(sdev, &swdevs, dev_list) { -+ if (!sscanf(sdev->devname, SWCONFIG_DEVNAME, &i)) -+ continue; -+ if (i < 0 || i > max_switches) -+ continue; ++ if (val->port_vlan >= dev->vlans) ++ return -EINVAL; + -+ set_bit(i, &in_use); -+ } -+ i = find_first_zero_bit(&in_use, max_switches); ++ /* validate ports */ ++ if (val->len > dev->ports) ++ return -EINVAL; + -+ if (i == max_switches) -+ return -ENFILE; ++ if (!ops->set_vlan_ports) ++ return -EOPNOTSUPP; + -+ /* fill device name */ -+ snprintf(dev->devname, IFNAMSIZ, SWCONFIG_DEVNAME, i); ++ for (i = 0; i < val->len; i++) { ++ if (ports[i].id >= dev->ports) ++ return -EINVAL; + -+ list_add(&dev->dev_list, &swdevs); -+ swconfig_unlock(); ++ if (ops->set_port_pvid && ++ !(ports[i].flags & (1 << SWITCH_PORT_FLAG_TAGGED))) ++ ops->set_port_pvid(dev, ports[i].id, val->port_vlan); ++ } + -+ return 0; ++ return ops->set_vlan_ports(dev, val); +} -+EXPORT_SYMBOL_GPL(register_switch); + -+void -+unregister_switch(struct switch_dev *dev) ++static int ++swconfig_set_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) +{ -+ kfree(dev->portbuf); -+ spin_lock(&dev->lock); -+ swconfig_lock(); -+ list_del(&dev->dev_list); -+ swconfig_unlock(); -+ spin_unlock(&dev->lock); -+} -+EXPORT_SYMBOL_GPL(unregister_switch); -+ ++ if (val->port_vlan >= dev->ports) ++ return -EINVAL; + -+static int __init -+swconfig_init(void) -+{ -+ int i, err; ++ if (!dev->ops->set_port_pvid) ++ return -EOPNOTSUPP; + -+ INIT_LIST_HEAD(&swdevs); -+ err = genl_register_family(&switch_fam); -+ if (err) -+ return err; ++ return dev->ops->set_port_pvid(dev, val->port_vlan, val->value.i); ++} + -+ for (i = 0; i < ARRAY_SIZE(swconfig_ops); i++) { -+ err = genl_register_ops(&switch_fam, &swconfig_ops[i]); -+ if (err) -+ goto unregister; -+ } ++static int ++swconfig_get_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) ++{ ++ if (val->port_vlan >= dev->ports) ++ return -EINVAL; + -+ return 0; ++ if (!dev->ops->get_port_pvid) ++ return -EOPNOTSUPP; + -+unregister: -+ genl_unregister_family(&switch_fam); -+ return err; ++ return dev->ops->get_port_pvid(dev, val->port_vlan, &val->value.i); +} + -+static void __exit -+swconfig_exit(void) ++static int ++swconfig_apply_config(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) +{ -+ genl_unregister_family(&switch_fam); -+} ++ /* don't complain if not supported by the switch driver */ ++ if (!dev->ops->apply_config) ++ return 0; + -+module_init(swconfig_init); -+module_exit(swconfig_exit); ++ return dev->ops->apply_config(dev); ++} + -diff -Nur linux-2.6.39.orig/drivers/spi/ap83_spi.c linux-2.6.39/drivers/spi/ap83_spi.c ---- linux-2.6.39.orig/drivers/spi/ap83_spi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/ap83_spi.c 2011-04-27 12:19:22.317665385 +0200 -@@ -0,0 +1,283 @@ -+/* -+ * Atheros AP83 board specific SPI Controller driver -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ ++static int ++swconfig_reset_switch(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) ++{ ++ /* don't complain if not supported by the switch driver */ ++ if (!dev->ops->reset_switch) ++ return 0; + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ return dev->ops->reset_switch(dev); ++} + -+#include -+#include ++enum global_defaults { ++ GLOBAL_APPLY, ++ GLOBAL_RESET, ++}; + -+#define DRV_DESC "Atheros AP83 board SPI Controller driver" -+#define DRV_VERSION "0.1.0" -+#define DRV_NAME "ap83-spi" ++enum vlan_defaults { ++ VLAN_PORTS, ++}; + -+#define AP83_SPI_CLK_HIGH (1 << 23) -+#define AP83_SPI_CLK_LOW 0 -+#define AP83_SPI_MOSI_HIGH (1 << 22) -+#define AP83_SPI_MOSI_LOW 0 ++enum port_defaults { ++ PORT_PVID, ++}; + -+#define AP83_SPI_GPIO_CS 1 -+#define AP83_SPI_GPIO_MISO 3 ++static struct switch_attr default_global[] = { ++ [GLOBAL_APPLY] = { ++ .type = SWITCH_TYPE_NOVAL, ++ .name = "apply", ++ .description = "Activate changes in the hardware", ++ .set = swconfig_apply_config, ++ }, ++ [GLOBAL_RESET] = { ++ .type = SWITCH_TYPE_NOVAL, ++ .name = "reset", ++ .description = "Reset the switch", ++ .set = swconfig_reset_switch, ++ } ++}; + -+struct ap83_spi { -+ struct spi_bitbang bitbang; -+ void __iomem *base; -+ u32 addr; ++static struct switch_attr default_port[] = { ++ [PORT_PVID] = { ++ .type = SWITCH_TYPE_INT, ++ .name = "pvid", ++ .description = "Primary VLAN ID", ++ .set = swconfig_set_pvid, ++ .get = swconfig_get_pvid, ++ } ++}; + -+ struct platform_device *pdev; ++static struct switch_attr default_vlan[] = { ++ [VLAN_PORTS] = { ++ .type = SWITCH_TYPE_PORTS, ++ .name = "ports", ++ .description = "VLAN port mapping", ++ .set = swconfig_set_vlan_ports, ++ .get = swconfig_get_vlan_ports, ++ }, +}; + -+static inline u32 ap83_spi_rr(struct ap83_spi *sp, u32 reg) -+{ -+ return __raw_readl(sp->base + reg); -+} + -+static inline struct ap83_spi *spidev_to_sp(struct spi_device *spi) ++static void swconfig_defaults_init(struct switch_dev *dev) +{ -+ return spi_master_get_devdata(spi->master); -+} ++ const struct switch_dev_ops *ops = dev->ops; + -+static inline void setsck(struct spi_device *spi, int val) -+{ -+ struct ap83_spi *sp = spidev_to_sp(spi); ++ dev->def_global = 0; ++ dev->def_vlan = 0; ++ dev->def_port = 0; + -+ if (val) -+ sp->addr |= AP83_SPI_CLK_HIGH; -+ else -+ sp->addr &= ~AP83_SPI_CLK_HIGH; ++ if (ops->get_vlan_ports || ops->set_vlan_ports) ++ set_bit(VLAN_PORTS, &dev->def_vlan); + -+ dev_dbg(&spi->dev, "addr=%08x, SCK set to %s\n", -+ sp->addr, (val) ? "HIGH" : "LOW"); ++ if (ops->get_port_pvid || ops->set_port_pvid) ++ set_bit(PORT_PVID, &dev->def_port); + -+ ap83_spi_rr(sp, sp->addr); ++ /* always present, can be no-op */ ++ set_bit(GLOBAL_APPLY, &dev->def_global); ++ set_bit(GLOBAL_RESET, &dev->def_global); +} + -+static inline void setmosi(struct spi_device *spi, int val) -+{ -+ struct ap83_spi *sp = spidev_to_sp(spi); + -+ if (val) -+ sp->addr |= AP83_SPI_MOSI_HIGH; -+ else -+ sp->addr &= ~AP83_SPI_MOSI_HIGH; ++static struct genl_family switch_fam = { ++ .id = GENL_ID_GENERATE, ++ .name = "switch", ++ .hdrsize = 0, ++ .version = 1, ++ .maxattr = SWITCH_ATTR_MAX, ++}; + -+ dev_dbg(&spi->dev, "addr=%08x, MOSI set to %s\n", -+ sp->addr, (val) ? "HIGH" : "LOW"); ++static const struct nla_policy switch_policy[SWITCH_ATTR_MAX+1] = { ++ [SWITCH_ATTR_ID] = { .type = NLA_U32 }, ++ [SWITCH_ATTR_OP_ID] = { .type = NLA_U32 }, ++ [SWITCH_ATTR_OP_PORT] = { .type = NLA_U32 }, ++ [SWITCH_ATTR_OP_VLAN] = { .type = NLA_U32 }, ++ [SWITCH_ATTR_OP_VALUE_INT] = { .type = NLA_U32 }, ++ [SWITCH_ATTR_OP_VALUE_STR] = { .type = NLA_NUL_STRING }, ++ [SWITCH_ATTR_OP_VALUE_PORTS] = { .type = NLA_NESTED }, ++ [SWITCH_ATTR_TYPE] = { .type = NLA_U32 }, ++}; + -+ ap83_spi_rr(sp, sp->addr); -+} ++static const struct nla_policy port_policy[SWITCH_PORT_ATTR_MAX+1] = { ++ [SWITCH_PORT_ID] = { .type = NLA_U32 }, ++ [SWITCH_PORT_FLAG_TAGGED] = { .type = NLA_FLAG }, ++}; + -+static inline u32 getmiso(struct spi_device *spi) ++static inline void ++swconfig_lock(void) +{ -+ u32 ret; -+ -+ ret = gpio_get_value(AP83_SPI_GPIO_MISO) ? 1 : 0; -+ dev_dbg(&spi->dev, "get MISO: %d\n", ret); -+ -+ return ret; ++ spin_lock(&swdevs_lock); +} + -+static inline void do_spidelay(struct spi_device *spi, unsigned nsecs) ++static inline void ++swconfig_unlock(void) +{ -+ ndelay(nsecs); ++ spin_unlock(&swdevs_lock); +} + -+static void ap83_spi_chipselect(struct spi_device *spi, int on) ++static struct switch_dev * ++swconfig_get_dev(struct genl_info *info) +{ -+ struct ap83_spi *sp = spidev_to_sp(spi); -+ -+ dev_dbg(&spi->dev, "set CS to %d\n", (on) ? 0 : 1); ++ struct switch_dev *dev = NULL; ++ struct switch_dev *p; ++ int id; + -+ if (on) { -+ ar71xx_flash_acquire(); ++ if (!info->attrs[SWITCH_ATTR_ID]) ++ goto done; + -+ sp->addr = 0; -+ ap83_spi_rr(sp, sp->addr); ++ id = nla_get_u32(info->attrs[SWITCH_ATTR_ID]); ++ swconfig_lock(); ++ list_for_each_entry(p, &swdevs, dev_list) { ++ if (id != p->id) ++ continue; + -+ gpio_set_value(AP83_SPI_GPIO_CS, 0); -+ } else { -+ gpio_set_value(AP83_SPI_GPIO_CS, 1); -+ ar71xx_flash_release(); ++ dev = p; ++ break; + } ++ if (dev) ++ spin_lock(&dev->lock); ++ else ++ DPRINTF("device %d not found\n", id); ++ swconfig_unlock(); ++done: ++ return dev; +} + -+#define spidelay(nsecs) \ -+ do { \ -+ /* Steal the spi_device pointer from our caller. \ -+ * The bitbang-API should probably get fixed here... */ \ -+ do_spidelay(spi, nsecs); \ -+ } while (0) -+ -+#define EXPAND_BITBANG_TXRX -+#include -+#include "spi_bitbang_txrx.h" -+ -+static u32 ap83_spi_txrx_mode0(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) ++static inline void ++swconfig_put_dev(struct switch_dev *dev) +{ -+ dev_dbg(&spi->dev, "TXRX0 word=%08x, bits=%u\n", word, bits); -+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); ++ spin_unlock(&dev->lock); +} + -+static u32 ap83_spi_txrx_mode1(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) ++static int ++swconfig_dump_attr(struct swconfig_callback *cb, void *arg) +{ -+ dev_dbg(&spi->dev, "TXRX1 word=%08x, bits=%u\n", word, bits); -+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); -+} ++ struct switch_attr *op = arg; ++ struct genl_info *info = cb->info; ++ struct sk_buff *msg = cb->msg; ++ int id = cb->args[0]; ++ void *hdr; + -+static u32 ap83_spi_txrx_mode2(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) -+{ -+ dev_dbg(&spi->dev, "TXRX2 word=%08x, bits=%u\n", word, bits); -+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); -+} ++ hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, &switch_fam, ++ NLM_F_MULTI, SWITCH_CMD_NEW_ATTR); ++ if (IS_ERR(hdr)) ++ return -1; + -+static u32 ap83_spi_txrx_mode3(struct spi_device *spi, -+ unsigned nsecs, u32 word, u8 bits) -+{ -+ dev_dbg(&spi->dev, "TXRX3 word=%08x, bits=%u\n", word, bits); -+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); ++ NLA_PUT_U32(msg, SWITCH_ATTR_OP_ID, id); ++ NLA_PUT_U32(msg, SWITCH_ATTR_OP_TYPE, op->type); ++ NLA_PUT_STRING(msg, SWITCH_ATTR_OP_NAME, op->name); ++ if (op->description) ++ NLA_PUT_STRING(msg, SWITCH_ATTR_OP_DESCRIPTION, ++ op->description); ++ ++ return genlmsg_end(msg, hdr); ++nla_put_failure: ++ genlmsg_cancel(msg, hdr); ++ return -EMSGSIZE; +} + -+static int ap83_spi_probe(struct platform_device *pdev) ++/* spread multipart messages across multiple message buffers */ ++static int ++swconfig_send_multipart(struct swconfig_callback *cb, void *arg) +{ -+ struct spi_master *master; -+ struct ap83_spi *sp; -+ struct ap83_spi_platform_data *pdata; -+ struct resource *r; -+ int ret; -+ -+ ret = gpio_request(AP83_SPI_GPIO_MISO, "spi-miso"); -+ if (ret) { -+ dev_err(&pdev->dev, "gpio request failed for MISO\n"); -+ return ret; -+ } -+ -+ ret = gpio_request(AP83_SPI_GPIO_CS, "spi-cs"); -+ if (ret) { -+ dev_err(&pdev->dev, "gpio request failed for CS\n"); -+ goto err_free_miso; -+ } -+ -+ ret = gpio_direction_input(AP83_SPI_GPIO_MISO); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set direction of MISO\n"); -+ goto err_free_cs; -+ } -+ -+ ret = gpio_direction_output(AP83_SPI_GPIO_CS, 0); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set direction of CS\n"); -+ goto err_free_cs; -+ } -+ -+ master = spi_alloc_master(&pdev->dev, sizeof(*sp)); -+ if (master == NULL) { -+ dev_err(&pdev->dev, "failed to allocate spi master\n"); -+ return -ENOMEM; -+ } -+ -+ sp = spi_master_get_devdata(master); -+ platform_set_drvdata(pdev, sp); -+ -+ pdata = pdev->dev.platform_data; -+ -+ sp->bitbang.master = spi_master_get(master); -+ sp->bitbang.chipselect = ap83_spi_chipselect; -+ sp->bitbang.txrx_word[SPI_MODE_0] = ap83_spi_txrx_mode0; -+ sp->bitbang.txrx_word[SPI_MODE_1] = ap83_spi_txrx_mode1; -+ sp->bitbang.txrx_word[SPI_MODE_2] = ap83_spi_txrx_mode2; -+ sp->bitbang.txrx_word[SPI_MODE_3] = ap83_spi_txrx_mode3; -+ -+ sp->bitbang.master->bus_num = pdev->id; -+ sp->bitbang.master->num_chipselect = 1; -+ -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (r == NULL) { -+ ret = -ENOENT; -+ goto err_spi_put; -+ } ++ struct genl_info *info = cb->info; ++ int restart = 0; ++ int err; + -+ sp->base = ioremap_nocache(r->start, r->end - r->start + 1); -+ if (!sp->base) { -+ ret = -ENXIO; -+ goto err_spi_put; -+ } ++ do { ++ if (!cb->msg) { ++ cb->msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); ++ if (cb->msg == NULL) ++ goto error; ++ } + -+ ret = spi_bitbang_start(&sp->bitbang); -+ if (!ret) -+ goto err_unmap; ++ if (!(cb->fill(cb, arg) < 0)) ++ break; + -+ dev_info(&pdev->dev, "AP83 SPI adapter at %08x\n", r->start); ++ /* fill failed, check if this was already the second attempt */ ++ if (restart) ++ goto error; + -+ return 0; ++ /* try again in a new message, send the current one */ ++ restart = 1; ++ if (cb->close) { ++ if (cb->close(cb, arg) < 0) ++ goto error; ++ } ++ err = genlmsg_reply(cb->msg, info); ++ cb->msg = NULL; ++ if (err < 0) ++ goto error; + -+err_unmap: -+ iounmap(sp->base); -+err_spi_put: -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); ++ } while (restart); + -+err_free_cs: -+ gpio_free(AP83_SPI_GPIO_CS); -+err_free_miso: -+ gpio_free(AP83_SPI_GPIO_MISO); -+ return ret; ++ return 0; ++ ++error: ++ if (cb->msg) ++ nlmsg_free(cb->msg); ++ return -1; +} + -+static int ap83_spi_remove(struct platform_device *pdev) ++static int ++swconfig_list_attrs(struct sk_buff *skb, struct genl_info *info) +{ -+ struct ap83_spi *sp = platform_get_drvdata(pdev); ++ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); ++ const struct switch_attrlist *alist; ++ struct switch_dev *dev; ++ struct swconfig_callback cb; ++ int err = -EINVAL; ++ int i; + -+ spi_bitbang_stop(&sp->bitbang); -+ iounmap(sp->base); -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); ++ /* defaults */ ++ struct switch_attr *def_list; ++ unsigned long *def_active; ++ int n_def; + -+ return 0; -+} ++ dev = swconfig_get_dev(info); ++ if (!dev) ++ return -EINVAL; + -+static struct platform_driver ap83_spi_drv = { -+ .probe = ap83_spi_probe, -+ .remove = ap83_spi_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; ++ switch(hdr->cmd) { ++ case SWITCH_CMD_LIST_GLOBAL: ++ alist = &dev->ops->attr_global; ++ def_list = default_global; ++ def_active = &dev->def_global; ++ n_def = ARRAY_SIZE(default_global); ++ break; ++ case SWITCH_CMD_LIST_VLAN: ++ alist = &dev->ops->attr_vlan; ++ def_list = default_vlan; ++ def_active = &dev->def_vlan; ++ n_def = ARRAY_SIZE(default_vlan); ++ break; ++ case SWITCH_CMD_LIST_PORT: ++ alist = &dev->ops->attr_port; ++ def_list = default_port; ++ def_active = &dev->def_port; ++ n_def = ARRAY_SIZE(default_port); ++ break; ++ default: ++ WARN_ON(1); ++ goto out; ++ } + -+static int __init ap83_spi_init(void) -+{ -+ return platform_driver_register(&ap83_spi_drv); -+} -+module_init(ap83_spi_init); ++ memset(&cb, 0, sizeof(cb)); ++ cb.info = info; ++ cb.fill = swconfig_dump_attr; ++ for (i = 0; i < alist->n_attr; i++) { ++ if (alist->attr[i].disabled) ++ continue; ++ cb.args[0] = i; ++ err = swconfig_send_multipart(&cb, (void *) &alist->attr[i]); ++ if (err < 0) ++ goto error; ++ } + -+static void __exit ap83_spi_exit(void) -+{ -+ platform_driver_unregister(&ap83_spi_drv); -+} -+module_exit(ap83_spi_exit); ++ /* defaults */ ++ for (i = 0; i < n_def; i++) { ++ if (!test_bit(i, def_active)) ++ continue; ++ cb.args[0] = SWITCH_ATTR_DEFAULTS_OFFSET + i; ++ err = swconfig_send_multipart(&cb, (void *) &def_list[i]); ++ if (err < 0) ++ goto error; ++ } ++ swconfig_put_dev(dev); + -+MODULE_ALIAS("platform:" DRV_NAME); -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.39.orig/drivers/spi/ar71xx_spi.c linux-2.6.39/drivers/spi/ar71xx_spi.c ---- linux-2.6.39.orig/drivers/spi/ar71xx_spi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/ar71xx_spi.c 2011-04-27 12:19:22.317665385 +0200 -@@ -0,0 +1,283 @@ -+/* -+ * Atheros AR71xx SPI Controller driver -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ ++ if (!cb.msg) ++ return 0; + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ return genlmsg_reply(cb.msg, info); + -+#include -+#include ++error: ++ if (cb.msg) ++ nlmsg_free(cb.msg); ++out: ++ swconfig_put_dev(dev); ++ return err; ++} + -+#define DRV_DESC "Atheros AR71xx SPI Controller driver" -+#define DRV_VERSION "0.2.4" -+#define DRV_NAME "ar71xx-spi" ++static const struct switch_attr * ++swconfig_lookup_attr(struct switch_dev *dev, struct genl_info *info, ++ struct switch_val *val) ++{ ++ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); ++ const struct switch_attrlist *alist; ++ const struct switch_attr *attr = NULL; ++ int attr_id; + -+#undef PER_BIT_READ ++ /* defaults */ ++ struct switch_attr *def_list; ++ unsigned long *def_active; ++ int n_def; + -+struct ar71xx_spi { -+ struct spi_bitbang bitbang; -+ u32 ioc_base; -+ u32 reg_ctrl; ++ if (!info->attrs[SWITCH_ATTR_OP_ID]) ++ goto done; + -+ void __iomem *base; ++ switch(hdr->cmd) { ++ case SWITCH_CMD_SET_GLOBAL: ++ case SWITCH_CMD_GET_GLOBAL: ++ alist = &dev->ops->attr_global; ++ def_list = default_global; ++ def_active = &dev->def_global; ++ n_def = ARRAY_SIZE(default_global); ++ break; ++ case SWITCH_CMD_SET_VLAN: ++ case SWITCH_CMD_GET_VLAN: ++ alist = &dev->ops->attr_vlan; ++ def_list = default_vlan; ++ def_active = &dev->def_vlan; ++ n_def = ARRAY_SIZE(default_vlan); ++ if (!info->attrs[SWITCH_ATTR_OP_VLAN]) ++ goto done; ++ val->port_vlan = nla_get_u32(info->attrs[SWITCH_ATTR_OP_VLAN]); ++ if (val->port_vlan >= dev->vlans) ++ goto done; ++ break; ++ case SWITCH_CMD_SET_PORT: ++ case SWITCH_CMD_GET_PORT: ++ alist = &dev->ops->attr_port; ++ def_list = default_port; ++ def_active = &dev->def_port; ++ n_def = ARRAY_SIZE(default_port); ++ if (!info->attrs[SWITCH_ATTR_OP_PORT]) ++ goto done; ++ val->port_vlan = nla_get_u32(info->attrs[SWITCH_ATTR_OP_PORT]); ++ if (val->port_vlan >= dev->ports) ++ goto done; ++ break; ++ default: ++ WARN_ON(1); ++ goto done; ++ } + -+ struct platform_device *pdev; -+ u32 (*get_ioc_base)(u8 chip_select, int cs_high, -+ int is_on); -+}; ++ if (!alist) ++ goto done; + -+static inline u32 ar71xx_spi_rr(struct ar71xx_spi *sp, unsigned reg) -+{ -+ return __raw_readl(sp->base + reg); -+} ++ attr_id = nla_get_u32(info->attrs[SWITCH_ATTR_OP_ID]); ++ if (attr_id >= SWITCH_ATTR_DEFAULTS_OFFSET) { ++ attr_id -= SWITCH_ATTR_DEFAULTS_OFFSET; ++ if (attr_id >= n_def) ++ goto done; ++ if (!test_bit(attr_id, def_active)) ++ goto done; ++ attr = &def_list[attr_id]; ++ } else { ++ if (attr_id >= alist->n_attr) ++ goto done; ++ attr = &alist->attr[attr_id]; ++ } + -+static inline void ar71xx_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val) -+{ -+ __raw_writel(val, sp->base + reg); ++ if (attr->disabled) ++ attr = NULL; ++ ++done: ++ if (!attr) ++ DPRINTF("attribute lookup failed\n"); ++ val->attr = attr; ++ return attr; +} + -+static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi) ++static int ++swconfig_parse_ports(struct sk_buff *msg, struct nlattr *head, ++ struct switch_val *val, int max) +{ -+ return spi_master_get_devdata(spi->master); -+} ++ struct nlattr *nla; ++ int rem; + -+static u32 ar71xx_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on) -+{ -+ u32 ret; ++ val->len = 0; ++ nla_for_each_nested(nla, head, rem) { ++ struct nlattr *tb[SWITCH_PORT_ATTR_MAX+1]; ++ struct switch_port *port = &val->value.ports[val->len]; + -+ if (is_on == AR71XX_SPI_CS_INACTIVE) -+ ret = SPI_IOC_CS_ALL; -+ else -+ ret = SPI_IOC_CS_ALL & ~SPI_IOC_CS(chip_select); ++ if (val->len >= max) ++ return -EINVAL; + -+ return ret; ++ if (nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, nla, ++ port_policy)) ++ return -EINVAL; ++ ++ if (!tb[SWITCH_PORT_ID]) ++ return -EINVAL; ++ ++ port->id = nla_get_u32(tb[SWITCH_PORT_ID]); ++ if (tb[SWITCH_PORT_FLAG_TAGGED]) ++ port->flags |= (1 << SWITCH_PORT_FLAG_TAGGED); ++ val->len++; ++ } ++ ++ return 0; +} + -+static void ar71xx_spi_chipselect(struct spi_device *spi, int value) ++static int ++swconfig_set_attr(struct sk_buff *skb, struct genl_info *info) +{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ void __iomem *base = sp->base; -+ u32 ioc_base; ++ const struct switch_attr *attr; ++ struct switch_dev *dev; ++ struct switch_val val; ++ int err = -EINVAL; + -+ switch (value) { -+ case BITBANG_CS_INACTIVE: -+ ioc_base = sp->get_ioc_base(spi->chip_select, -+ (spi->mode & SPI_CS_HIGH) != 0, -+ AR71XX_SPI_CS_INACTIVE); -+ __raw_writel(ioc_base, base + SPI_REG_IOC); -+ break; ++ dev = swconfig_get_dev(info); ++ if (!dev) ++ return -EINVAL; + -+ case BITBANG_CS_ACTIVE: -+ ioc_base = sp->get_ioc_base(spi->chip_select, -+ (spi->mode & SPI_CS_HIGH) != 0, -+ AR71XX_SPI_CS_ACTIVE); ++ memset(&val, 0, sizeof(val)); ++ attr = swconfig_lookup_attr(dev, info, &val); ++ if (!attr || !attr->set) ++ goto error; + -+ __raw_writel(ioc_base, base + SPI_REG_IOC); -+ sp->ioc_base = ioc_base; ++ val.attr = attr; ++ switch(attr->type) { ++ case SWITCH_TYPE_NOVAL: ++ break; ++ case SWITCH_TYPE_INT: ++ if (!info->attrs[SWITCH_ATTR_OP_VALUE_INT]) ++ goto error; ++ val.value.i = ++ nla_get_u32(info->attrs[SWITCH_ATTR_OP_VALUE_INT]); ++ break; ++ case SWITCH_TYPE_STRING: ++ if (!info->attrs[SWITCH_ATTR_OP_VALUE_STR]) ++ goto error; ++ val.value.s = ++ nla_data(info->attrs[SWITCH_ATTR_OP_VALUE_STR]); ++ break; ++ case SWITCH_TYPE_PORTS: ++ val.value.ports = dev->portbuf; ++ memset(dev->portbuf, 0, ++ sizeof(struct switch_port) * dev->ports); ++ ++ /* TODO: implement multipart? */ ++ if (info->attrs[SWITCH_ATTR_OP_VALUE_PORTS]) { ++ err = swconfig_parse_ports(skb, ++ info->attrs[SWITCH_ATTR_OP_VALUE_PORTS], &val, dev->ports); ++ if (err < 0) ++ goto error; ++ } else { ++ val.len = 0; ++ err = 0; ++ } + break; ++ default: ++ goto error; + } ++ ++ err = attr->set(dev, attr, &val); ++error: ++ swconfig_put_dev(dev); ++ return err; +} + -+static void ar71xx_spi_setup_regs(struct spi_device *spi) ++static int ++swconfig_close_portlist(struct swconfig_callback *cb, void *arg) +{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ if (cb->nest[0]) ++ nla_nest_end(cb->msg, cb->nest[0]); ++ return 0; ++} + -+ /* enable GPIO mode */ -+ ar71xx_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO); ++static int ++swconfig_send_port(struct swconfig_callback *cb, void *arg) ++{ ++ const struct switch_port *port = arg; ++ struct nlattr *p = NULL; + -+ /* save CTRL register */ -+ sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_CTRL); ++ if (!cb->nest[0]) { ++ cb->nest[0] = nla_nest_start(cb->msg, cb->cmd); ++ if (!cb->nest[0]) ++ return -1; ++ } + -+ /* TODO: setup speed? */ -+ ar71xx_spi_wr(sp, SPI_REG_CTRL, 0x43); -+} ++ p = nla_nest_start(cb->msg, SWITCH_ATTR_PORT); ++ if (!p) ++ goto error; + -+static void ar71xx_spi_restore_regs(struct spi_device *spi) -+{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ NLA_PUT_U32(cb->msg, SWITCH_PORT_ID, port->id); ++ if (port->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) ++ NLA_PUT_FLAG(cb->msg, SWITCH_PORT_FLAG_TAGGED); + -+ /* restore CTRL register */ -+ ar71xx_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl); -+ /* disable GPIO mode */ -+ ar71xx_spi_wr(sp, SPI_REG_FS, 0); ++ nla_nest_end(cb->msg, p); ++ return 0; ++ ++nla_put_failure: ++ nla_nest_cancel(cb->msg, p); ++error: ++ nla_nest_cancel(cb->msg, cb->nest[0]); ++ return -1; +} + -+static int ar71xx_spi_setup(struct spi_device *spi) ++static int ++swconfig_send_ports(struct sk_buff **msg, struct genl_info *info, int attr, ++ const struct switch_val *val) +{ -+ int status; ++ struct swconfig_callback cb; ++ int err = 0; ++ int i; + -+ if (spi->bits_per_word > 32) ++ if (!val->value.ports) + return -EINVAL; + -+ if (!spi->controller_state) -+ ar71xx_spi_setup_regs(spi); ++ memset(&cb, 0, sizeof(cb)); ++ cb.cmd = attr; ++ cb.msg = *msg; ++ cb.info = info; ++ cb.fill = swconfig_send_port; ++ cb.close = swconfig_close_portlist; + -+ status = spi_bitbang_setup(spi); -+ if (status && !spi->controller_state) -+ ar71xx_spi_restore_regs(spi); ++ cb.nest[0] = nla_nest_start(cb.msg, cb.cmd); ++ for (i = 0; i < val->len; i++) { ++ err = swconfig_send_multipart(&cb, &val->value.ports[i]); ++ if (err) ++ goto done; ++ } ++ err = val->len; ++ swconfig_close_portlist(&cb, NULL); ++ *msg = cb.msg; + -+ return status; ++done: ++ return err; +} + -+static void ar71xx_spi_cleanup(struct spi_device *spi) ++static int ++swconfig_get_attr(struct sk_buff *skb, struct genl_info *info) +{ -+ ar71xx_spi_restore_regs(spi); -+ spi_bitbang_cleanup(spi); -+} ++ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); ++ const struct switch_attr *attr; ++ struct switch_dev *dev; ++ struct sk_buff *msg = NULL; ++ struct switch_val val; ++ int err = -EINVAL; ++ int cmd = hdr->cmd; + -+static u32 ar71xx_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs, -+ u32 word, u8 bits) -+{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ void __iomem *base = sp->base; -+ u32 ioc = sp->ioc_base; -+ u32 ret; ++ dev = swconfig_get_dev(info); ++ if (!dev) ++ return -EINVAL; + -+ /* clock starts at inactive polarity */ -+ for (word <<= (32 - bits); likely(bits); bits--) { -+ u32 out; ++ memset(&val, 0, sizeof(val)); ++ attr = swconfig_lookup_attr(dev, info, &val); ++ if (!attr || !attr->get) ++ goto error; + -+ if (word & (1 << 31)) -+ out = ioc | SPI_IOC_DO; -+ else -+ out = ioc & ~SPI_IOC_DO; ++ if (attr->type == SWITCH_TYPE_PORTS) { ++ val.value.ports = dev->portbuf; ++ memset(dev->portbuf, 0, ++ sizeof(struct switch_port) * dev->ports); ++ } ++ ++ err = attr->get(dev, attr, &val); ++ if (err) ++ goto error; ++ ++ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); ++ if (!msg) ++ goto error; ++ ++ hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, &switch_fam, ++ 0, cmd); ++ if (IS_ERR(hdr)) ++ goto nla_put_failure; ++ ++ switch(attr->type) { ++ case SWITCH_TYPE_INT: ++ NLA_PUT_U32(msg, SWITCH_ATTR_OP_VALUE_INT, val.value.i); ++ break; ++ case SWITCH_TYPE_STRING: ++ NLA_PUT_STRING(msg, SWITCH_ATTR_OP_VALUE_STR, val.value.s); ++ break; ++ case SWITCH_TYPE_PORTS: ++ err = swconfig_send_ports(&msg, info, ++ SWITCH_ATTR_OP_VALUE_PORTS, &val); ++ if (err < 0) ++ goto nla_put_failure; ++ break; ++ default: ++ DPRINTF("invalid type in attribute\n"); ++ err = -EINVAL; ++ goto error; ++ } ++ err = genlmsg_end(msg, hdr); ++ if (err < 0) ++ goto nla_put_failure; + -+ /* setup MSB (to slave) on trailing edge */ -+ __raw_writel(out, base + SPI_REG_IOC); ++ swconfig_put_dev(dev); ++ return genlmsg_reply(msg, info); + -+ __raw_writel(out | SPI_IOC_CLK, base + SPI_REG_IOC); ++nla_put_failure: ++ if (msg) ++ nlmsg_free(msg); ++error: ++ swconfig_put_dev(dev); ++ if (!err) ++ err = -ENOMEM; ++ return err; ++} + -+ word <<= 1; ++static int ++swconfig_send_switch(struct sk_buff *msg, u32 pid, u32 seq, int flags, ++ const struct switch_dev *dev) ++{ ++ void *hdr; + -+#ifdef PER_BIT_READ -+ /* sample MSB (from slave) on leading edge */ -+ ret = __raw_readl(base + SPI_REG_RDS); -+ __raw_writel(out, base + SPI_REG_IOC); -+#endif ++ hdr = genlmsg_put(msg, pid, seq, &switch_fam, flags, ++ SWITCH_CMD_NEW_ATTR); ++ if (IS_ERR(hdr)) ++ return -1; + -+ } ++ NLA_PUT_U32(msg, SWITCH_ATTR_ID, dev->id); ++ NLA_PUT_STRING(msg, SWITCH_ATTR_DEV_NAME, dev->devname); ++ NLA_PUT_STRING(msg, SWITCH_ATTR_ALIAS, dev->alias); ++ NLA_PUT_STRING(msg, SWITCH_ATTR_NAME, dev->name); ++ NLA_PUT_U32(msg, SWITCH_ATTR_VLANS, dev->vlans); ++ NLA_PUT_U32(msg, SWITCH_ATTR_PORTS, dev->ports); ++ NLA_PUT_U32(msg, SWITCH_ATTR_CPU_PORT, dev->cpu_port); + -+#ifndef PER_BIT_READ -+ ret = __raw_readl(base + SPI_REG_RDS); -+#endif -+ return ret; ++ return genlmsg_end(msg, hdr); ++nla_put_failure: ++ genlmsg_cancel(msg, hdr); ++ return -EMSGSIZE; +} + -+static int ar71xx_spi_probe(struct platform_device *pdev) ++static int swconfig_dump_switches(struct sk_buff *skb, ++ struct netlink_callback *cb) +{ -+ struct spi_master *master; -+ struct ar71xx_spi *sp; -+ struct ar71xx_spi_platform_data *pdata; -+ struct resource *r; -+ int ret; ++ struct switch_dev *dev; ++ int start = cb->args[0]; ++ int idx = 0; + -+ master = spi_alloc_master(&pdev->dev, sizeof(*sp)); -+ if (master == NULL) { -+ dev_err(&pdev->dev, "failed to allocate spi master\n"); -+ return -ENOMEM; ++ swconfig_lock(); ++ list_for_each_entry(dev, &swdevs, dev_list) { ++ if (++idx <= start) ++ continue; ++ if (swconfig_send_switch(skb, NETLINK_CB(cb->skb).pid, ++ cb->nlh->nlmsg_seq, NLM_F_MULTI, ++ dev) < 0) ++ break; + } ++ swconfig_unlock(); ++ cb->args[0] = idx; + -+ sp = spi_master_get_devdata(master); -+ platform_set_drvdata(pdev, sp); ++ return skb->len; ++} + -+ pdata = pdev->dev.platform_data; ++static int ++swconfig_done(struct netlink_callback *cb) ++{ ++ return 0; ++} + -+ master->setup = ar71xx_spi_setup; -+ master->cleanup = ar71xx_spi_cleanup; ++static struct genl_ops swconfig_ops[] = { ++ { ++ .cmd = SWITCH_CMD_LIST_GLOBAL, ++ .doit = swconfig_list_attrs, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_LIST_VLAN, ++ .doit = swconfig_list_attrs, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_LIST_PORT, ++ .doit = swconfig_list_attrs, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_GET_GLOBAL, ++ .doit = swconfig_get_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_GET_VLAN, ++ .doit = swconfig_get_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_GET_PORT, ++ .doit = swconfig_get_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_SET_GLOBAL, ++ .doit = swconfig_set_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_SET_VLAN, ++ .doit = swconfig_set_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_SET_PORT, ++ .doit = swconfig_set_attr, ++ .policy = switch_policy, ++ }, ++ { ++ .cmd = SWITCH_CMD_GET_SWITCH, ++ .dumpit = swconfig_dump_switches, ++ .policy = switch_policy, ++ .done = swconfig_done, ++ } ++}; + -+ sp->bitbang.master = spi_master_get(master); -+ sp->bitbang.chipselect = ar71xx_spi_chipselect; -+ sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0; -+ sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; ++int ++register_switch(struct switch_dev *dev, struct net_device *netdev) ++{ ++ struct switch_dev *sdev; ++ const int max_switches = 8 * sizeof(unsigned long); ++ unsigned long in_use = 0; ++ int i; + -+ sp->get_ioc_base = ar71xx_spi_get_ioc_base; -+ if (pdata) { -+ sp->bitbang.master->bus_num = pdata->bus_num; -+ sp->bitbang.master->num_chipselect = pdata->num_chipselect; -+ if (pdata->get_ioc_base) -+ sp->get_ioc_base = pdata->get_ioc_base; -+ } else { -+ sp->bitbang.master->bus_num = 0; -+ sp->bitbang.master->num_chipselect = 3; ++ INIT_LIST_HEAD(&dev->dev_list); ++ if (netdev) { ++ dev->netdev = netdev; ++ if (!dev->alias) ++ dev->alias = netdev->name; + } ++ BUG_ON(!dev->alias); + -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (r == NULL) { -+ ret = -ENOENT; -+ goto err1; ++ if (dev->ports > 0) { ++ dev->portbuf = kzalloc(sizeof(struct switch_port) * dev->ports, ++ GFP_KERNEL); ++ if (!dev->portbuf) ++ return -ENOMEM; + } ++ swconfig_defaults_init(dev); ++ spin_lock_init(&dev->lock); ++ swconfig_lock(); ++ dev->id = ++swdev_id; + -+ sp->base = ioremap_nocache(r->start, r->end - r->start + 1); -+ if (!sp->base) { -+ ret = -ENXIO; -+ goto err1; ++ list_for_each_entry(sdev, &swdevs, dev_list) { ++ if (!sscanf(sdev->devname, SWCONFIG_DEVNAME, &i)) ++ continue; ++ if (i < 0 || i > max_switches) ++ continue; ++ ++ set_bit(i, &in_use); + } ++ i = find_first_zero_bit(&in_use, max_switches); + -+ ret = spi_bitbang_start(&sp->bitbang); -+ if (!ret) -+ return 0; ++ if (i == max_switches) ++ return -ENFILE; + -+ iounmap(sp->base); -+err1: -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); ++ /* fill device name */ ++ snprintf(dev->devname, IFNAMSIZ, SWCONFIG_DEVNAME, i); + -+ return ret; ++ list_add(&dev->dev_list, &swdevs); ++ swconfig_unlock(); ++ ++ return 0; +} ++EXPORT_SYMBOL_GPL(register_switch); + -+static int ar71xx_spi_remove(struct platform_device *pdev) ++void ++unregister_switch(struct switch_dev *dev) +{ -+ struct ar71xx_spi *sp = platform_get_drvdata(pdev); -+ -+ spi_bitbang_stop(&sp->bitbang); -+ iounmap(sp->base); -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); -+ -+ return 0; ++ kfree(dev->portbuf); ++ spin_lock(&dev->lock); ++ swconfig_lock(); ++ list_del(&dev->dev_list); ++ swconfig_unlock(); ++ spin_unlock(&dev->lock); +} ++EXPORT_SYMBOL_GPL(unregister_switch); + -+static struct platform_driver ar71xx_spi_drv = { -+ .probe = ar71xx_spi_probe, -+ .remove = ar71xx_spi_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; + -+static int __init ar71xx_spi_init(void) ++static int __init ++swconfig_init(void) +{ -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); -+ return platform_driver_register(&ar71xx_spi_drv); ++ int i, err; ++ ++ INIT_LIST_HEAD(&swdevs); ++ err = genl_register_family(&switch_fam); ++ if (err) ++ return err; ++ ++ for (i = 0; i < ARRAY_SIZE(swconfig_ops); i++) { ++ err = genl_register_ops(&switch_fam, &swconfig_ops[i]); ++ if (err) ++ goto unregister; ++ } ++ ++ return 0; ++ ++unregister: ++ genl_unregister_family(&switch_fam); ++ return err; +} -+module_init(ar71xx_spi_init); + -+static void __exit ar71xx_spi_exit(void) ++static void __exit ++swconfig_exit(void) +{ -+ platform_driver_unregister(&ar71xx_spi_drv); ++ genl_unregister_family(&switch_fam); +} -+module_exit(ar71xx_spi_exit); + -+MODULE_ALIAS("platform:" DRV_NAME); -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_AUTHOR("Imre Kaloz "); -+MODULE_LICENSE("GPL v2"); ++module_init(swconfig_init); ++module_exit(swconfig_exit); ++ diff -Nur linux-2.6.39.orig/drivers/spi/Kconfig linux-2.6.39/drivers/spi/Kconfig --- linux-2.6.39.orig/drivers/spi/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/spi/Kconfig 2011-08-23 15:10:24.167989908 +0200 ++++ linux-2.6.39/drivers/spi/Kconfig 2011-08-24 18:17:24.000000000 +0200 @@ -67,6 +67,13 @@ This enables support for the SPI controller present on the Atheros AR71XX/AR724X/AR913X SoCs. @@ -23518,601 +20468,610 @@ diff -Nur linux-2.6.39.orig/drivers/spi/Kconfig linux-2.6.39/drivers/spi/Kconfig # # Add new SPI protocol masters in alphabetical order above this line # -diff -Nur linux-2.6.39.orig/drivers/spi/Kconfig.orig linux-2.6.39/drivers/spi/Kconfig.orig ---- linux-2.6.39.orig/drivers/spi/Kconfig.orig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/Kconfig.orig 2011-08-23 15:10:11.277991848 +0200 -@@ -0,0 +1,482 @@ -+# -+# SPI driver configuration -+# -+# NOTE: the reason this doesn't show SPI slave support is mostly that -+# nobody's needed a slave side API yet. The master-role API is not -+# fully appropriate there, so it'd need some thought to do well. -+# -+menuconfig SPI -+ bool "SPI support" -+ depends on HAS_IOMEM -+ help -+ The "Serial Peripheral Interface" is a low level synchronous -+ protocol. Chips that support SPI can have data transfer rates -+ up to several tens of Mbit/sec. Chips are addressed with a -+ controller and a chipselect. Most SPI slaves don't support -+ dynamic device discovery; some are even write-only or read-only. -+ -+ SPI is widely used by microcontrollers to talk with sensors, -+ eeprom and flash memory, codecs and various other controller -+ chips, analog to digital (and d-to-a) converters, and more. -+ MMC and SD cards can be accessed using SPI protocol; and for -+ DataFlash cards used in MMC sockets, SPI must always be used. -+ -+ SPI is one of a family of similar protocols using a four wire -+ interface (select, clock, data in, data out) including Microwire -+ (half duplex), SSP, SSI, and PSP. This driver framework should -+ work with most such devices and controllers. -+ -+if SPI -+ -+config SPI_DEBUG -+ boolean "Debug support for SPI drivers" -+ depends on DEBUG_KERNEL -+ help -+ Say "yes" to enable debug messaging (like dev_dbg and pr_debug), -+ sysfs, and debugfs support in SPI controller and protocol drivers. +diff -Nur linux-2.6.39.orig/drivers/spi/Makefile linux-2.6.39/drivers/spi/Makefile +--- linux-2.6.39.orig/drivers/spi/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/spi/Makefile 2011-08-24 18:17:24.000000000 +0200 +@@ -10,6 +10,7 @@ + + # SPI master controller drivers (bus) + obj-$(CONFIG_SPI_ALTERA) += spi_altera.o ++obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o + obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o + obj-$(CONFIG_SPI_ATH79) += ath79_spi.o + obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o +@@ -54,6 +55,7 @@ + obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o + obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o + obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o ++obj-$(CONFIG_SPI_RB4XX) += rb4xx_spi.o + + # special build for s3c24xx spi driver with fiq support + spi_s3c24xx_hw-y := spi_s3c24xx.o +@@ -62,6 +64,7 @@ + # ... add above this line ... + + # SPI protocol drivers (device/link on bus) ++obj-$(CONFIG_SPI_RB4XX_CPLD) += spi_rb4xx_cpld.o + obj-$(CONFIG_SPI_SPIDEV) += spidev.o + obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o + # ... add above this line ... +diff -Nur linux-2.6.39.orig/drivers/spi/ap83_spi.c linux-2.6.39/drivers/spi/ap83_spi.c +--- linux-2.6.39.orig/drivers/spi/ap83_spi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/spi/ap83_spi.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,283 @@ ++/* ++ * Atheros AP83 board specific SPI Controller driver ++ * ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ + -+# -+# MASTER side ... talking to discrete SPI slave chips including microcontrollers -+# ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define DRV_DESC "Atheros AP83 board SPI Controller driver" ++#define DRV_VERSION "0.1.0" ++#define DRV_NAME "ap83-spi" ++ ++#define AP83_SPI_CLK_HIGH (1 << 23) ++#define AP83_SPI_CLK_LOW 0 ++#define AP83_SPI_MOSI_HIGH (1 << 22) ++#define AP83_SPI_MOSI_LOW 0 ++ ++#define AP83_SPI_GPIO_CS 1 ++#define AP83_SPI_GPIO_MISO 3 ++ ++struct ap83_spi { ++ struct spi_bitbang bitbang; ++ void __iomem *base; ++ u32 addr; ++ ++ struct platform_device *pdev; ++}; ++ ++static inline u32 ap83_spi_rr(struct ap83_spi *sp, u32 reg) ++{ ++ return __raw_readl(sp->base + reg); ++} ++ ++static inline struct ap83_spi *spidev_to_sp(struct spi_device *spi) ++{ ++ return spi_master_get_devdata(spi->master); ++} ++ ++static inline void setsck(struct spi_device *spi, int val) ++{ ++ struct ap83_spi *sp = spidev_to_sp(spi); ++ ++ if (val) ++ sp->addr |= AP83_SPI_CLK_HIGH; ++ else ++ sp->addr &= ~AP83_SPI_CLK_HIGH; ++ ++ dev_dbg(&spi->dev, "addr=%08x, SCK set to %s\n", ++ sp->addr, (val) ? "HIGH" : "LOW"); ++ ++ ap83_spi_rr(sp, sp->addr); ++} ++ ++static inline void setmosi(struct spi_device *spi, int val) ++{ ++ struct ap83_spi *sp = spidev_to_sp(spi); ++ ++ if (val) ++ sp->addr |= AP83_SPI_MOSI_HIGH; ++ else ++ sp->addr &= ~AP83_SPI_MOSI_HIGH; ++ ++ dev_dbg(&spi->dev, "addr=%08x, MOSI set to %s\n", ++ sp->addr, (val) ? "HIGH" : "LOW"); ++ ++ ap83_spi_rr(sp, sp->addr); ++} ++ ++static inline u32 getmiso(struct spi_device *spi) ++{ ++ u32 ret; ++ ++ ret = gpio_get_value(AP83_SPI_GPIO_MISO) ? 1 : 0; ++ dev_dbg(&spi->dev, "get MISO: %d\n", ret); ++ ++ return ret; ++} ++ ++static inline void do_spidelay(struct spi_device *spi, unsigned nsecs) ++{ ++ ndelay(nsecs); ++} ++ ++static void ap83_spi_chipselect(struct spi_device *spi, int on) ++{ ++ struct ap83_spi *sp = spidev_to_sp(spi); ++ ++ dev_dbg(&spi->dev, "set CS to %d\n", (on) ? 0 : 1); ++ ++ if (on) { ++ ar71xx_flash_acquire(); ++ ++ sp->addr = 0; ++ ap83_spi_rr(sp, sp->addr); ++ ++ gpio_set_value(AP83_SPI_GPIO_CS, 0); ++ } else { ++ gpio_set_value(AP83_SPI_GPIO_CS, 1); ++ ar71xx_flash_release(); ++ } ++} ++ ++#define spidelay(nsecs) \ ++ do { \ ++ /* Steal the spi_device pointer from our caller. \ ++ * The bitbang-API should probably get fixed here... */ \ ++ do_spidelay(spi, nsecs); \ ++ } while (0) ++ ++#define EXPAND_BITBANG_TXRX ++#include ++#include "spi_bitbang_txrx.h" ++ ++static u32 ap83_spi_txrx_mode0(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ dev_dbg(&spi->dev, "TXRX0 word=%08x, bits=%u\n", word, bits); ++ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); ++} ++ ++static u32 ap83_spi_txrx_mode1(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ dev_dbg(&spi->dev, "TXRX1 word=%08x, bits=%u\n", word, bits); ++ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); ++} ++ ++static u32 ap83_spi_txrx_mode2(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ dev_dbg(&spi->dev, "TXRX2 word=%08x, bits=%u\n", word, bits); ++ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); ++} ++ ++static u32 ap83_spi_txrx_mode3(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ dev_dbg(&spi->dev, "TXRX3 word=%08x, bits=%u\n", word, bits); ++ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); ++} ++ ++static int ap83_spi_probe(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct ap83_spi *sp; ++ struct ap83_spi_platform_data *pdata; ++ struct resource *r; ++ int ret; ++ ++ ret = gpio_request(AP83_SPI_GPIO_MISO, "spi-miso"); ++ if (ret) { ++ dev_err(&pdev->dev, "gpio request failed for MISO\n"); ++ return ret; ++ } ++ ++ ret = gpio_request(AP83_SPI_GPIO_CS, "spi-cs"); ++ if (ret) { ++ dev_err(&pdev->dev, "gpio request failed for CS\n"); ++ goto err_free_miso; ++ } ++ ++ ret = gpio_direction_input(AP83_SPI_GPIO_MISO); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set direction of MISO\n"); ++ goto err_free_cs; ++ } ++ ++ ret = gpio_direction_output(AP83_SPI_GPIO_CS, 0); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to set direction of CS\n"); ++ goto err_free_cs; ++ } ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(*sp)); ++ if (master == NULL) { ++ dev_err(&pdev->dev, "failed to allocate spi master\n"); ++ return -ENOMEM; ++ } ++ ++ sp = spi_master_get_devdata(master); ++ platform_set_drvdata(pdev, sp); ++ ++ pdata = pdev->dev.platform_data; ++ ++ sp->bitbang.master = spi_master_get(master); ++ sp->bitbang.chipselect = ap83_spi_chipselect; ++ sp->bitbang.txrx_word[SPI_MODE_0] = ap83_spi_txrx_mode0; ++ sp->bitbang.txrx_word[SPI_MODE_1] = ap83_spi_txrx_mode1; ++ sp->bitbang.txrx_word[SPI_MODE_2] = ap83_spi_txrx_mode2; ++ sp->bitbang.txrx_word[SPI_MODE_3] = ap83_spi_txrx_mode3; + -+config SPI_MASTER -+# boolean "SPI Master Support" -+ boolean -+ default SPI -+ help -+ If your system has an master-capable SPI controller (which -+ provides the clock and chipselect), you can enable that -+ controller and the protocol drivers for the SPI slave chips -+ that are connected. ++ sp->bitbang.master->bus_num = pdev->id; ++ sp->bitbang.master->num_chipselect = 1; + -+if SPI_MASTER ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (r == NULL) { ++ ret = -ENOENT; ++ goto err_spi_put; ++ } + -+comment "SPI Master Controller Drivers" ++ sp->base = ioremap_nocache(r->start, r->end - r->start + 1); ++ if (!sp->base) { ++ ret = -ENXIO; ++ goto err_spi_put; ++ } + -+config SPI_ALTERA -+ tristate "Altera SPI Controller" -+ select SPI_BITBANG -+ help -+ This is the driver for the Altera SPI Controller. ++ ret = spi_bitbang_start(&sp->bitbang); ++ if (!ret) ++ goto err_unmap; + -+config SPI_ATH79 -+ tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver" -+ depends on ATH79 && GENERIC_GPIO -+ select SPI_BITBANG -+ help -+ This enables support for the SPI controller present on the -+ Atheros AR71XX/AR724X/AR913X SoCs. ++ dev_info(&pdev->dev, "AP83 SPI adapter at %08x\n", r->start); + -+config SPI_AR71XX -+ tristate "Atheros AR71xx SPI Controller" -+ depends on SPI_MASTER && ATHEROS_AR71XX -+ select SPI_BITBANG -+ help -+ This is the SPI contoller driver for Atheros AR71xx. ++ return 0; + -+config SPI_ATMEL -+ tristate "Atmel SPI Controller" -+ depends on (ARCH_AT91 || AVR32) -+ help -+ This selects a driver for the Atmel SPI Controller, present on -+ many AT32 (AVR32) and AT91 (ARM) chips. ++err_unmap: ++ iounmap(sp->base); ++err_spi_put: ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(sp->bitbang.master); + -+config SPI_BFIN -+ tristate "SPI controller driver for ADI Blackfin5xx" -+ depends on BLACKFIN -+ help -+ This is the SPI controller master driver for Blackfin 5xx processor. ++err_free_cs: ++ gpio_free(AP83_SPI_GPIO_CS); ++err_free_miso: ++ gpio_free(AP83_SPI_GPIO_MISO); ++ return ret; ++} + -+config SPI_AU1550 -+ tristate "Au1550/Au12x0 SPI Controller" -+ depends on (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL -+ select SPI_BITBANG -+ help -+ If you say yes to this option, support will be included for the -+ Au1550 SPI controller (may also work with Au1200,Au1210,Au1250). ++static int ap83_spi_remove(struct platform_device *pdev) ++{ ++ struct ap83_spi *sp = platform_get_drvdata(pdev); + -+ This driver can also be built as a module. If so, the module -+ will be called au1550_spi. ++ spi_bitbang_stop(&sp->bitbang); ++ iounmap(sp->base); ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(sp->bitbang.master); + -+config SPI_BITBANG -+ tristate "Utilities for Bitbanging SPI masters" -+ help -+ With a few GPIO pins, your system can bitbang the SPI protocol. -+ Select this to get SPI support through I/O pins (GPIO, parallel -+ port, etc). Or, some systems' SPI master controller drivers use -+ this code to manage the per-word or per-transfer accesses to the -+ hardware shift registers. -+ -+ This is library code, and is automatically selected by drivers that -+ need it. You only need to select this explicitly to support driver -+ modules that aren't part of this kernel tree. -+ -+config SPI_BUTTERFLY -+ tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)" -+ depends on PARPORT -+ select SPI_BITBANG -+ help -+ This uses a custom parallel port cable to connect to an AVR -+ Butterfly , an -+ inexpensive battery powered microcontroller evaluation board. -+ This same cable can be used to flash new firmware. -+ -+config SPI_COLDFIRE_QSPI -+ tristate "Freescale Coldfire QSPI controller" -+ depends on (M520x || M523x || M5249 || M527x || M528x || M532x) -+ help -+ This enables support for the Coldfire QSPI controller in master -+ mode. ++ return 0; ++} + -+ This driver can also be built as a module. If so, the module -+ will be called coldfire_qspi. ++static struct platform_driver ap83_spi_drv = { ++ .probe = ap83_spi_probe, ++ .remove = ap83_spi_remove, ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; + -+config SPI_DAVINCI -+ tristate "Texas Instruments DaVinci/DA8x/OMAP-L/AM1x SoC SPI controller" -+ depends on SPI_MASTER && ARCH_DAVINCI -+ select SPI_BITBANG -+ help -+ SPI master controller for DaVinci/DA8x/OMAP-L/AM1x SPI modules. ++static int __init ap83_spi_init(void) ++{ ++ return platform_driver_register(&ap83_spi_drv); ++} ++module_init(ap83_spi_init); + -+ This driver can also be built as a module. The module will be called -+ davinci_spi. ++static void __exit ap83_spi_exit(void) ++{ ++ platform_driver_unregister(&ap83_spi_drv); ++} ++module_exit(ap83_spi_exit); + -+config SPI_EP93XX -+ tristate "Cirrus Logic EP93xx SPI controller" -+ depends on ARCH_EP93XX -+ help -+ This enables using the Cirrus EP93xx SPI controller in master -+ mode. ++MODULE_ALIAS("platform:" DRV_NAME); ++MODULE_DESCRIPTION(DRV_DESC); ++MODULE_VERSION(DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-2.6.39.orig/drivers/spi/ar71xx_spi.c linux-2.6.39/drivers/spi/ar71xx_spi.c +--- linux-2.6.39.orig/drivers/spi/ar71xx_spi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39/drivers/spi/ar71xx_spi.c 2011-08-24 18:17:24.000000000 +0200 +@@ -0,0 +1,283 @@ ++/* ++ * Atheros AR71xx SPI Controller driver ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ + -+ To compile this driver as a module, choose M here. The module will be -+ called ep93xx_spi. ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+config SPI_GPIO -+ tristate "GPIO-based bitbanging SPI Master" -+ depends on GENERIC_GPIO -+ select SPI_BITBANG -+ help -+ This simple GPIO bitbanging SPI master uses the arch-neutral GPIO -+ interface to manage MOSI, MISO, SCK, and chipselect signals. SPI -+ slaves connected to a bus using this driver are configured as usual, -+ except that the spi_board_info.controller_data holds the GPIO number -+ for the chipselect used by this controller driver. ++#include ++#include + -+ Note that this driver often won't achieve even 1 Mbit/sec speeds, -+ making it unusually slow for SPI. If your platform can inline -+ GPIO operations, you should be able to leverage that for better -+ speed with a custom version of this driver; see the source code. ++#define DRV_DESC "Atheros AR71xx SPI Controller driver" ++#define DRV_VERSION "0.2.4" ++#define DRV_NAME "ar71xx-spi" + -+config SPI_IMX_VER_IMX1 -+ def_bool y if SOC_IMX1 ++#undef PER_BIT_READ + -+config SPI_IMX_VER_0_0 -+ def_bool y if SOC_IMX21 || SOC_IMX27 ++struct ar71xx_spi { ++ struct spi_bitbang bitbang; ++ u32 ioc_base; ++ u32 reg_ctrl; + -+config SPI_IMX_VER_0_4 -+ def_bool y if SOC_IMX31 ++ void __iomem *base; + -+config SPI_IMX_VER_0_7 -+ def_bool y if ARCH_MX25 || SOC_IMX35 || SOC_IMX51 || SOC_IMX53 ++ struct platform_device *pdev; ++ u32 (*get_ioc_base)(u8 chip_select, int cs_high, ++ int is_on); ++}; + -+config SPI_IMX_VER_2_3 -+ def_bool y if SOC_IMX51 || SOC_IMX53 ++static inline u32 ar71xx_spi_rr(struct ar71xx_spi *sp, unsigned reg) ++{ ++ return __raw_readl(sp->base + reg); ++} + -+config SPI_IMX -+ tristate "Freescale i.MX SPI controllers" -+ depends on ARCH_MXC -+ select SPI_BITBANG -+ default m if IMX_HAVE_PLATFORM_SPI_IMX -+ help -+ This enables using the Freescale i.MX SPI controllers in master -+ mode. ++static inline void ar71xx_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val) ++{ ++ __raw_writel(val, sp->base + reg); ++} + -+config SPI_LM70_LLP -+ tristate "Parallel port adapter for LM70 eval board (DEVELOPMENT)" -+ depends on PARPORT && EXPERIMENTAL -+ select SPI_BITBANG -+ help -+ This driver supports the NS LM70 LLP Evaluation Board, -+ which interfaces to an LM70 temperature sensor using -+ a parallel port. -+ -+config SPI_MPC52xx -+ tristate "Freescale MPC52xx SPI (non-PSC) controller support" -+ depends on PPC_MPC52xx && SPI -+ select SPI_MASTER_OF -+ help -+ This drivers supports the MPC52xx SPI controller in master SPI -+ mode. ++static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi) ++{ ++ return spi_master_get_devdata(spi->master); ++} + -+config SPI_MPC52xx_PSC -+ tristate "Freescale MPC52xx PSC SPI controller" -+ depends on PPC_MPC52xx && EXPERIMENTAL -+ help -+ This enables using the Freescale MPC52xx Programmable Serial -+ Controller in master SPI mode. ++static u32 ar71xx_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on) ++{ ++ u32 ret; + -+config SPI_MPC512x_PSC -+ tristate "Freescale MPC512x PSC SPI controller" -+ depends on SPI_MASTER && PPC_MPC512x -+ help -+ This enables using the Freescale MPC5121 Programmable Serial -+ Controller in SPI master mode. ++ if (is_on == AR71XX_SPI_CS_INACTIVE) ++ ret = SPI_IOC_CS_ALL; ++ else ++ ret = SPI_IOC_CS_ALL & ~SPI_IOC_CS(chip_select); + -+config SPI_FSL_LIB -+ tristate -+ depends on FSL_SOC ++ return ret; ++} + -+config SPI_FSL_SPI -+ tristate "Freescale SPI controller" -+ depends on FSL_SOC -+ select SPI_FSL_LIB -+ help -+ This enables using the Freescale SPI controllers in master mode. -+ MPC83xx platform uses the controller in cpu mode or CPM/QE mode. -+ MPC8569 uses the controller in QE mode, MPC8610 in cpu mode. -+ -+config SPI_FSL_ESPI -+ tristate "Freescale eSPI controller" -+ depends on FSL_SOC -+ select SPI_FSL_LIB -+ help -+ This enables using the Freescale eSPI controllers in master mode. -+ From MPC8536, 85xx platform uses the controller, and all P10xx, -+ P20xx, P30xx,P40xx, P50xx uses this controller. ++static void ar71xx_spi_chipselect(struct spi_device *spi, int value) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ void __iomem *base = sp->base; ++ u32 ioc_base; + -+config SPI_OC_TINY -+ tristate "OpenCores tiny SPI" -+ depends on GENERIC_GPIO -+ select SPI_BITBANG -+ help -+ This is the driver for OpenCores tiny SPI master controller. ++ switch (value) { ++ case BITBANG_CS_INACTIVE: ++ ioc_base = sp->get_ioc_base(spi->chip_select, ++ (spi->mode & SPI_CS_HIGH) != 0, ++ AR71XX_SPI_CS_INACTIVE); ++ __raw_writel(ioc_base, base + SPI_REG_IOC); ++ break; + -+config SPI_OMAP_UWIRE -+ tristate "OMAP1 MicroWire" -+ depends on ARCH_OMAP1 -+ select SPI_BITBANG -+ help -+ This hooks up to the MicroWire controller on OMAP1 chips. ++ case BITBANG_CS_ACTIVE: ++ ioc_base = sp->get_ioc_base(spi->chip_select, ++ (spi->mode & SPI_CS_HIGH) != 0, ++ AR71XX_SPI_CS_ACTIVE); + -+config SPI_OMAP24XX -+ tristate "McSPI driver for OMAP" -+ depends on ARCH_OMAP2PLUS -+ help -+ SPI master controller for OMAP24XX and later Multichannel SPI -+ (McSPI) modules. ++ __raw_writel(ioc_base, base + SPI_REG_IOC); ++ sp->ioc_base = ioc_base; ++ break; ++ } ++} + -+config SPI_OMAP_100K -+ tristate "OMAP SPI 100K" -+ depends on SPI_MASTER && (ARCH_OMAP850 || ARCH_OMAP730) -+ help -+ OMAP SPI 100K master controller for omap7xx boards. ++static void ar71xx_spi_setup_regs(struct spi_device *spi) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); + -+config SPI_ORION -+ tristate "Orion SPI master (EXPERIMENTAL)" -+ depends on PLAT_ORION && EXPERIMENTAL -+ help -+ This enables using the SPI master controller on the Orion chips. -+ -+config SPI_PL022 -+ tristate "ARM AMBA PL022 SSP controller (EXPERIMENTAL)" -+ depends on ARM_AMBA && EXPERIMENTAL -+ default y if MACH_U300 -+ default y if ARCH_REALVIEW -+ default y if INTEGRATOR_IMPD1 -+ default y if ARCH_VERSATILE -+ help -+ This selects the ARM(R) AMBA(R) PrimeCell PL022 SSP -+ controller. If you have an embedded system with an AMBA(R) -+ bus and a PL022 controller, say Y or M here. ++ /* enable GPIO mode */ ++ ar71xx_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO); + -+config SPI_PPC4xx -+ tristate "PPC4xx SPI Controller" -+ depends on PPC32 && 4xx && SPI_MASTER -+ select SPI_BITBANG -+ help -+ This selects a driver for the PPC4xx SPI Controller. ++ /* save CTRL register */ ++ sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_CTRL); + -+config SPI_PXA2XX -+ tristate "PXA2xx SSP SPI master" -+ depends on (ARCH_PXA || (X86_32 && PCI)) && EXPERIMENTAL -+ select PXA_SSP if ARCH_PXA -+ help -+ This enables using a PXA2xx or Sodaville SSP port as a SPI master -+ controller. The driver can be configured to use any SSP port and -+ additional documentation can be found a Documentation/spi/pxa2xx. ++ /* TODO: setup speed? */ ++ ar71xx_spi_wr(sp, SPI_REG_CTRL, 0x43); ++} + -+config SPI_PXA2XX_PCI -+ def_bool SPI_PXA2XX && X86_32 && PCI ++static void ar71xx_spi_restore_regs(struct spi_device *spi) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); + -+config SPI_S3C24XX -+ tristate "Samsung S3C24XX series SPI" -+ depends on ARCH_S3C2410 && EXPERIMENTAL -+ select SPI_BITBANG -+ help -+ SPI driver for Samsung S3C24XX series ARM SoCs ++ /* restore CTRL register */ ++ ar71xx_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl); ++ /* disable GPIO mode */ ++ ar71xx_spi_wr(sp, SPI_REG_FS, 0); ++} + -+config SPI_S3C24XX_FIQ -+ bool "S3C24XX driver with FIQ pseudo-DMA" -+ depends on SPI_S3C24XX -+ select FIQ -+ help -+ Enable FIQ support for the S3C24XX SPI driver to provide pseudo -+ DMA by using the fast-interrupt request framework, This allows -+ the driver to get DMA-like performance when there are either -+ no free DMA channels, or when doing transfers that required both -+ TX and RX data paths. -+ -+config SPI_S3C24XX_GPIO -+ tristate "Samsung S3C24XX series SPI by GPIO" -+ depends on ARCH_S3C2410 && EXPERIMENTAL -+ select SPI_BITBANG -+ help -+ SPI driver for Samsung S3C24XX series ARM SoCs using -+ GPIO lines to provide the SPI bus. This can be used where -+ the inbuilt hardware cannot provide the transfer mode, or -+ where the board is using non hardware connected pins. -+ -+config SPI_S3C64XX -+ tristate "Samsung S3C64XX series type SPI" -+ depends on (ARCH_S3C64XX || ARCH_S5P64X0) -+ select S3C64XX_DMA if ARCH_S3C64XX -+ help -+ SPI driver for Samsung S3C64XX and newer SoCs. ++static int ar71xx_spi_setup(struct spi_device *spi) ++{ ++ int status; + -+config SPI_SH_MSIOF -+ tristate "SuperH MSIOF SPI controller" -+ depends on SUPERH && HAVE_CLK -+ select SPI_BITBANG -+ help -+ SPI driver for SuperH MSIOF blocks. ++ if (spi->bits_per_word > 32) ++ return -EINVAL; + -+config SPI_SH -+ tristate "SuperH SPI controller" -+ depends on SUPERH -+ help -+ SPI driver for SuperH SPI blocks. ++ if (!spi->controller_state) ++ ar71xx_spi_setup_regs(spi); + -+config SPI_SH_SCI -+ tristate "SuperH SCI SPI controller" -+ depends on SUPERH -+ select SPI_BITBANG -+ help -+ SPI driver for SuperH SCI blocks. ++ status = spi_bitbang_setup(spi); ++ if (status && !spi->controller_state) ++ ar71xx_spi_restore_regs(spi); + -+config SPI_STMP3XXX -+ tristate "Freescale STMP37xx/378x SPI/SSP controller" -+ depends on ARCH_STMP3XXX && SPI_MASTER -+ help -+ SPI driver for Freescale STMP37xx/378x SoC SSP interface ++ return status; ++} + -+config SPI_TEGRA -+ tristate "Nvidia Tegra SPI controller" -+ depends on ARCH_TEGRA -+ select TEGRA_SYSTEM_DMA -+ help -+ SPI driver for NVidia Tegra SoCs ++static void ar71xx_spi_cleanup(struct spi_device *spi) ++{ ++ ar71xx_spi_restore_regs(spi); ++ spi_bitbang_cleanup(spi); ++} + -+config SPI_TI_SSP -+ tristate "TI Sequencer Serial Port - SPI Support" -+ depends on MFD_TI_SSP -+ help -+ This selects an SPI master implementation using a TI sequencer -+ serial port. ++static u32 ar71xx_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs, ++ u32 word, u8 bits) ++{ ++ struct ar71xx_spi *sp = spidev_to_sp(spi); ++ void __iomem *base = sp->base; ++ u32 ioc = sp->ioc_base; ++ u32 ret; + -+ To compile this driver as a module, choose M here: the -+ module will be called ti-ssp-spi. ++ /* clock starts at inactive polarity */ ++ for (word <<= (32 - bits); likely(bits); bits--) { ++ u32 out; + -+config SPI_TOPCLIFF_PCH -+ tristate "Topcliff PCH SPI Controller" -+ depends on PCI -+ help -+ SPI driver for the Topcliff PCH (Platform Controller Hub) SPI bus -+ used in some x86 embedded processors. ++ if (word & (1 << 31)) ++ out = ioc | SPI_IOC_DO; ++ else ++ out = ioc & ~SPI_IOC_DO; + -+config SPI_TXX9 -+ tristate "Toshiba TXx9 SPI controller" -+ depends on GENERIC_GPIO && CPU_TX49XX -+ help -+ SPI driver for Toshiba TXx9 MIPS SoCs ++ /* setup MSB (to slave) on trailing edge */ ++ __raw_writel(out, base + SPI_REG_IOC); + -+config SPI_XILINX -+ tristate "Xilinx SPI controller common module" -+ depends on HAS_IOMEM && EXPERIMENTAL -+ select SPI_BITBANG -+ help -+ This exposes the SPI controller IP from the Xilinx EDK. ++ __raw_writel(out | SPI_IOC_CLK, base + SPI_REG_IOC); ++ ++ word <<= 1; + -+ See the "OPB Serial Peripheral Interface (SPI) (v1.00e)" -+ Product Specification document (DS464) for hardware details. ++#ifdef PER_BIT_READ ++ /* sample MSB (from slave) on leading edge */ ++ ret = __raw_readl(base + SPI_REG_RDS); ++ __raw_writel(out, base + SPI_REG_IOC); ++#endif + -+ Or for the DS570, see "XPS Serial Peripheral Interface (SPI) (v2.00b)" ++ } + -+config SPI_NUC900 -+ tristate "Nuvoton NUC900 series SPI" -+ depends on ARCH_W90X900 && EXPERIMENTAL -+ select SPI_BITBANG -+ help -+ SPI driver for Nuvoton NUC900 series ARM SoCs ++#ifndef PER_BIT_READ ++ ret = __raw_readl(base + SPI_REG_RDS); ++#endif ++ return ret; ++} + -+# -+# Add new SPI master controllers in alphabetical order above this line -+# ++static int ar71xx_spi_probe(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct ar71xx_spi *sp; ++ struct ar71xx_spi_platform_data *pdata; ++ struct resource *r; ++ int ret; + -+config SPI_DESIGNWARE -+ tristate "DesignWare SPI controller core support" -+ depends on SPI_MASTER -+ help -+ general driver for SPI controller core from DesignWare ++ master = spi_alloc_master(&pdev->dev, sizeof(*sp)); ++ if (master == NULL) { ++ dev_err(&pdev->dev, "failed to allocate spi master\n"); ++ return -ENOMEM; ++ } + -+config SPI_DW_PCI -+ tristate "PCI interface driver for DW SPI core" -+ depends on SPI_DESIGNWARE && PCI ++ sp = spi_master_get_devdata(master); ++ platform_set_drvdata(pdev, sp); + -+config SPI_DW_MID_DMA -+ bool "DMA support for DW SPI controller on Intel Moorestown platform" -+ depends on SPI_DW_PCI && INTEL_MID_DMAC ++ pdata = pdev->dev.platform_data; + -+config SPI_DW_MMIO -+ tristate "Memory-mapped io interface driver for DW SPI core" -+ depends on SPI_DESIGNWARE && HAVE_CLK ++ master->setup = ar71xx_spi_setup; ++ master->cleanup = ar71xx_spi_cleanup; + -+# -+# There are lots of SPI device types, with sensors and memory -+# being probably the most widely used ones. -+# -+comment "SPI Protocol Masters" ++ sp->bitbang.master = spi_master_get(master); ++ sp->bitbang.chipselect = ar71xx_spi_chipselect; ++ sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0; ++ sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; + -+config SPI_SPIDEV -+ tristate "User mode SPI device driver support" -+ depends on EXPERIMENTAL -+ help -+ This supports user mode SPI protocol drivers. ++ sp->get_ioc_base = ar71xx_spi_get_ioc_base; ++ if (pdata) { ++ sp->bitbang.master->bus_num = pdata->bus_num; ++ sp->bitbang.master->num_chipselect = pdata->num_chipselect; ++ if (pdata->get_ioc_base) ++ sp->get_ioc_base = pdata->get_ioc_base; ++ } else { ++ sp->bitbang.master->bus_num = 0; ++ sp->bitbang.master->num_chipselect = 3; ++ } + -+ Note that this application programming interface is EXPERIMENTAL -+ and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes. ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (r == NULL) { ++ ret = -ENOENT; ++ goto err1; ++ } + -+config SPI_TLE62X0 -+ tristate "Infineon TLE62X0 (for power switching)" -+ depends on SYSFS -+ help -+ SPI driver for Infineon TLE62X0 series line driver chips, -+ such as the TLE6220, TLE6230 and TLE6240. This provides a -+ sysfs interface, with each line presented as a kind of GPIO -+ exposing both switch control and diagnostic feedback. ++ sp->base = ioremap_nocache(r->start, r->end - r->start + 1); ++ if (!sp->base) { ++ ret = -ENXIO; ++ goto err1; ++ } + -+config SPI_RB4XX_CPLD -+ tristate "MikroTik RB4XX CPLD driver" -+ depends on AR71XX_MACH_RB4XX -+ help -+ SPI driver for the Xilinx CPLD chip present on the -+ MikroTik RB4xx boards. ++ ret = spi_bitbang_start(&sp->bitbang); ++ if (!ret) ++ return 0; + -+# -+# Add new SPI protocol masters in alphabetical order above this line -+# ++ iounmap(sp->base); ++err1: ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(sp->bitbang.master); + -+endif # SPI_MASTER ++ return ret; ++} + -+# (slave support would go here) ++static int ar71xx_spi_remove(struct platform_device *pdev) ++{ ++ struct ar71xx_spi *sp = platform_get_drvdata(pdev); + -+endif # SPI -diff -Nur linux-2.6.39.orig/drivers/spi/Makefile linux-2.6.39/drivers/spi/Makefile ---- linux-2.6.39.orig/drivers/spi/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/spi/Makefile 2011-08-23 15:10:24.199233941 +0200 -@@ -10,6 +10,7 @@ - - # SPI master controller drivers (bus) - obj-$(CONFIG_SPI_ALTERA) += spi_altera.o -+obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o - obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o - obj-$(CONFIG_SPI_ATH79) += ath79_spi.o - obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o -@@ -54,6 +55,7 @@ - obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o - obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o - obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o -+obj-$(CONFIG_SPI_RB4XX) += rb4xx_spi.o - - # special build for s3c24xx spi driver with fiq support - spi_s3c24xx_hw-y := spi_s3c24xx.o -@@ -62,6 +64,7 @@ - # ... add above this line ... - - # SPI protocol drivers (device/link on bus) -+obj-$(CONFIG_SPI_RB4XX_CPLD) += spi_rb4xx_cpld.o - obj-$(CONFIG_SPI_SPIDEV) += spidev.o - obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o - # ... add above this line ... -diff -Nur linux-2.6.39.orig/drivers/spi/Makefile.orig linux-2.6.39/drivers/spi/Makefile.orig ---- linux-2.6.39.orig/drivers/spi/Makefile.orig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/Makefile.orig 2011-08-23 15:10:11.300479072 +0200 -@@ -0,0 +1,75 @@ -+# -+# Makefile for kernel SPI drivers. -+# ++ spi_bitbang_stop(&sp->bitbang); ++ iounmap(sp->base); ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(sp->bitbang.master); + -+ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG ++ return 0; ++} + -+# small core, mostly translating board-specific -+# config declarations into driver model code -+obj-$(CONFIG_SPI_MASTER) += spi.o ++static struct platform_driver ar71xx_spi_drv = { ++ .probe = ar71xx_spi_probe, ++ .remove = ar71xx_spi_remove, ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; + -+# SPI master controller drivers (bus) -+obj-$(CONFIG_SPI_ALTERA) += spi_altera.o -+obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o -+obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o -+obj-$(CONFIG_SPI_ATH79) += ath79_spi.o -+obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o -+obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o -+obj-$(CONFIG_SPI_AU1550) += au1550_spi.o -+obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o -+obj-$(CONFIG_SPI_COLDFIRE_QSPI) += coldfire_qspi.o -+obj-$(CONFIG_SPI_DAVINCI) += davinci_spi.o -+obj-$(CONFIG_SPI_DESIGNWARE) += dw_spi.o -+obj-$(CONFIG_SPI_DW_PCI) += dw_spi_midpci.o -+dw_spi_midpci-objs := dw_spi_pci.o dw_spi_mid.o -+obj-$(CONFIG_SPI_DW_MMIO) += dw_spi_mmio.o -+obj-$(CONFIG_SPI_EP93XX) += ep93xx_spi.o -+obj-$(CONFIG_SPI_GPIO) += spi_gpio.o -+obj-$(CONFIG_SPI_IMX) += spi_imx.o -+obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o -+obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o -+obj-$(CONFIG_SPI_PXA2XX_PCI) += pxa2xx_spi_pci.o -+obj-$(CONFIG_SPI_OC_TINY) += spi_oc_tiny.o -+obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o -+obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o -+obj-$(CONFIG_SPI_OMAP_100K) += omap_spi_100k.o -+obj-$(CONFIG_SPI_ORION) += orion_spi.o -+obj-$(CONFIG_SPI_PL022) += amba-pl022.o -+obj-$(CONFIG_SPI_MPC512x_PSC) += mpc512x_psc_spi.o -+obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o -+obj-$(CONFIG_SPI_MPC52xx) += mpc52xx_spi.o -+obj-$(CONFIG_SPI_FSL_LIB) += spi_fsl_lib.o -+obj-$(CONFIG_SPI_FSL_ESPI) += spi_fsl_espi.o -+obj-$(CONFIG_SPI_FSL_SPI) += spi_fsl_spi.o -+obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o -+obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o -+obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o -+obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o -+obj-$(CONFIG_SPI_TEGRA) += spi_tegra.o -+obj-$(CONFIG_SPI_TI_SSP) += ti-ssp-spi.o -+obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi_topcliff_pch.o -+obj-$(CONFIG_SPI_TXX9) += spi_txx9.o -+obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o -+obj-$(CONFIG_SPI_SH) += spi_sh.o -+obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o -+obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o -+obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o -+obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o -+ -+# special build for s3c24xx spi driver with fiq support -+spi_s3c24xx_hw-y := spi_s3c24xx.o -+spi_s3c24xx_hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi_s3c24xx_fiq.o -+ -+# ... add above this line ... -+ -+# SPI protocol drivers (device/link on bus) -+obj-$(CONFIG_SPI_RB4XX_CPLD) += spi_rb4xx_cpld.o -+obj-$(CONFIG_SPI_SPIDEV) += spidev.o -+obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o -+# ... add above this line ... ++static int __init ar71xx_spi_init(void) ++{ ++ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); ++ return platform_driver_register(&ar71xx_spi_drv); ++} ++module_init(ar71xx_spi_init); + -+# SPI slave controller drivers (upstream link) -+# ... add above this line ... ++static void __exit ar71xx_spi_exit(void) ++{ ++ platform_driver_unregister(&ar71xx_spi_drv); ++} ++module_exit(ar71xx_spi_exit); + -+# SPI slave drivers (protocol for that link) -+# ... add above this line ... ++MODULE_ALIAS("platform:" DRV_NAME); ++MODULE_DESCRIPTION(DRV_DESC); ++MODULE_VERSION(DRV_VERSION); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_AUTHOR("Imre Kaloz "); ++MODULE_LICENSE("GPL v2"); diff -Nur linux-2.6.39.orig/drivers/spi/pb44_spi.c linux-2.6.39/drivers/spi/pb44_spi.c --- linux-2.6.39.orig/drivers/spi/pb44_spi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/pb44_spi.c 2011-04-27 12:19:22.317665385 +0200 ++++ linux-2.6.39/drivers/spi/pb44_spi.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,299 @@ +/* + * Atheros PB44 board SPI controller driver @@ -24415,7 +21374,7 @@ diff -Nur linux-2.6.39.orig/drivers/spi/pb44_spi.c linux-2.6.39/drivers/spi/pb44 +MODULE_LICENSE("GPL v2"); diff -Nur linux-2.6.39.orig/drivers/spi/rb4xx_spi.c linux-2.6.39/drivers/spi/rb4xx_spi.c --- linux-2.6.39.orig/drivers/spi/rb4xx_spi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/rb4xx_spi.c 2011-04-27 12:19:22.307664943 +0200 ++++ linux-2.6.39/drivers/spi/rb4xx_spi.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,474 @@ +/* + * SPI controller driver for the Mikrotik RB4xx boards @@ -24893,7 +21852,7 @@ diff -Nur linux-2.6.39.orig/drivers/spi/rb4xx_spi.c linux-2.6.39/drivers/spi/rb4 +MODULE_LICENSE("GPL v2"); diff -Nur linux-2.6.39.orig/drivers/spi/spi_rb4xx_cpld.c linux-2.6.39/drivers/spi/spi_rb4xx_cpld.c --- linux-2.6.39.orig/drivers/spi/spi_rb4xx_cpld.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/spi_rb4xx_cpld.c 2011-04-27 12:19:22.317665385 +0200 ++++ linux-2.6.39/drivers/spi/spi_rb4xx_cpld.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,440 @@ +/* + * SPI driver for the CPLD chip on the Mikrotik RB4xx boards @@ -25337,7 +22296,7 @@ diff -Nur linux-2.6.39.orig/drivers/spi/spi_rb4xx_cpld.c linux-2.6.39/drivers/sp +MODULE_LICENSE("GPL v2"); diff -Nur linux-2.6.39.orig/drivers/spi/spi_vsc7385.c linux-2.6.39/drivers/spi/spi_vsc7385.c --- linux-2.6.39.orig/drivers/spi/spi_vsc7385.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/spi/spi_vsc7385.c 2011-04-27 12:19:22.317665385 +0200 ++++ linux-2.6.39/drivers/spi/spi_vsc7385.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,621 @@ +/* + * SPI driver for the Vitesse VSC7385 ethernet switch @@ -25962,7 +22921,7 @@ diff -Nur linux-2.6.39.orig/drivers/spi/spi_vsc7385.c linux-2.6.39/drivers/spi/s + diff -Nur linux-2.6.39.orig/drivers/tty/serial/ar933x_uart.c linux-2.6.39/drivers/tty/serial/ar933x_uart.c --- linux-2.6.39.orig/drivers/tty/serial/ar933x_uart.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/tty/serial/ar933x_uart.c 2011-08-06 09:32:37.098016752 +0200 ++++ linux-2.6.39/drivers/tty/serial/ar933x_uart.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,688 @@ +/* + * Atheros AR933X SoC built-in UART driver @@ -26652,9 +23611,40 @@ diff -Nur linux-2.6.39.orig/drivers/tty/serial/ar933x_uart.c linux-2.6.39/driver +MODULE_AUTHOR("Gabor Juhos "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRIVER_NAME); +diff -Nur linux-2.6.39.orig/drivers/usb/host/Kconfig linux-2.6.39/drivers/usb/host/Kconfig +--- linux-2.6.39.orig/drivers/usb/host/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/usb/host/Kconfig 2011-08-24 18:17:24.000000000 +0200 +@@ -129,6 +129,13 @@ + config USB_FSL_MPH_DR_OF + tristate + ++config USB_EHCI_AR71XX ++ bool "USB EHCI support for AR71xx" ++ depends on USB_EHCI_HCD && ATHEROS_AR71XX ++ default y ++ help ++ Support for Atheros AR71xx built-in EHCI controller ++ + config USB_EHCI_FSL + bool "Support for Freescale on-chip EHCI USB controller" + depends on USB_EHCI_HCD && FSL_SOC +@@ -287,6 +294,13 @@ + Enables support for the on-chip OHCI controller on + OMAP3 and later chips. + ++config USB_OHCI_AR71XX ++ bool "USB OHCI support for Atheros AR71xx" ++ depends on USB_OHCI_HCD && ATHEROS_AR71XX ++ default y ++ help ++ Support for Atheros AR71xx built-in OHCI controller ++ + config USB_OHCI_HCD_PPC_SOC + bool "OHCI support for on-chip PPC USB controller" + depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-ar71xx.c linux-2.6.39/drivers/usb/host/ehci-ar71xx.c --- linux-2.6.39.orig/drivers/usb/host/ehci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/usb/host/ehci-ar71xx.c 2011-04-27 12:19:22.267661616 +0200 ++++ linux-2.6.39/drivers/usb/host/ehci-ar71xx.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,242 @@ +/* + * Bus Glue for Atheros AR71xx built-in EHCI controller. @@ -26900,7 +23890,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-ar71xx.c linux-2.6.39/drivers/ +}; diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-hcd.c linux-2.6.39/drivers/usb/host/ehci-hcd.c --- linux-2.6.39.orig/drivers/usb/host/ehci-hcd.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/usb/host/ehci-hcd.c 2011-08-22 16:21:42.807985568 +0200 ++++ linux-2.6.39/drivers/usb/host/ehci-hcd.c 2011-08-24 18:17:24.000000000 +0200 @@ -1265,6 +1265,11 @@ #define PLATFORM_DRIVER tegra_ehci_driver #endif @@ -26913,40 +23903,9 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/ehci-hcd.c linux-2.6.39/drivers/usb #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ !defined(XILINX_OF_PLATFORM_DRIVER) -diff -Nur linux-2.6.39.orig/drivers/usb/host/Kconfig linux-2.6.39/drivers/usb/host/Kconfig ---- linux-2.6.39.orig/drivers/usb/host/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/usb/host/Kconfig 2011-08-22 16:21:42.767983341 +0200 -@@ -129,6 +129,13 @@ - config USB_FSL_MPH_DR_OF - tristate - -+config USB_EHCI_AR71XX -+ bool "USB EHCI support for AR71xx" -+ depends on USB_EHCI_HCD && ATHEROS_AR71XX -+ default y -+ help -+ Support for Atheros AR71xx built-in EHCI controller -+ - config USB_EHCI_FSL - bool "Support for Freescale on-chip EHCI USB controller" - depends on USB_EHCI_HCD && FSL_SOC -@@ -287,6 +294,13 @@ - Enables support for the on-chip OHCI controller on - OMAP3 and later chips. - -+config USB_OHCI_AR71XX -+ bool "USB OHCI support for Atheros AR71xx" -+ depends on USB_OHCI_HCD && ATHEROS_AR71XX -+ default y -+ help -+ Support for Atheros AR71xx built-in OHCI controller -+ - config USB_OHCI_HCD_PPC_SOC - bool "OHCI support for on-chip PPC USB controller" - depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-ar71xx.c linux-2.6.39/drivers/usb/host/ohci-ar71xx.c --- linux-2.6.39.orig/drivers/usb/host/ohci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/usb/host/ohci-ar71xx.c 2011-04-27 12:19:22.267661616 +0200 ++++ linux-2.6.39/drivers/usb/host/ohci-ar71xx.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,165 @@ +/* + * OHCI HCD (Host Controller Driver) for USB. @@ -27115,7 +24074,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-ar71xx.c linux-2.6.39/drivers/ +}; diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-hcd.c linux-2.6.39/drivers/usb/host/ohci-hcd.c --- linux-2.6.39.orig/drivers/usb/host/ohci-hcd.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/usb/host/ohci-hcd.c 2011-08-22 16:21:42.847983209 +0200 ++++ linux-2.6.39/drivers/usb/host/ohci-hcd.c 2011-08-24 18:17:24.000000000 +0200 @@ -1105,6 +1105,11 @@ #define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver #endif @@ -27128,9 +24087,37 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/ohci-hcd.c linux-2.6.39/drivers/usb #if !defined(PCI_DRIVER) && \ !defined(PLATFORM_DRIVER) && \ !defined(OMAP1_PLATFORM_DRIVER) && \ +diff -Nur linux-2.6.39.orig/drivers/watchdog/Kconfig linux-2.6.39/drivers/watchdog/Kconfig +--- linux-2.6.39.orig/drivers/watchdog/Kconfig 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/watchdog/Kconfig 2011-08-24 18:17:24.000000000 +0200 +@@ -990,6 +990,13 @@ + To compile this driver as a loadable module, choose M here. + The module will be called bcm63xx_wdt. + ++config AR71XX_WDT ++ tristate "Atheros AR71xx Watchdog Timer" ++ depends on ATHEROS_AR71XX ++ help ++ Hardware driver for the built-in watchdog timer on the Atheros ++ AR71xx SoCs. ++ + # PARISC Architecture + + # POWERPC Architecture +diff -Nur linux-2.6.39.orig/drivers/watchdog/Makefile linux-2.6.39/drivers/watchdog/Makefile +--- linux-2.6.39.orig/drivers/watchdog/Makefile 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/drivers/watchdog/Makefile 2011-08-24 18:17:24.000000000 +0200 +@@ -119,6 +119,7 @@ + obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o + obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o + obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o ++obj-$(CONFIG_AR71XX_WDT) += ar71xx_wdt.o + obj-$(CONFIG_AR7_WDT) += ar7_wdt.o + obj-$(CONFIG_TXX9_WDT) += txx9wdt.o + obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o diff -Nur linux-2.6.39.orig/drivers/watchdog/ar71xx_wdt.c linux-2.6.39/drivers/watchdog/ar71xx_wdt.c --- linux-2.6.39.orig/drivers/watchdog/ar71xx_wdt.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/watchdog/ar71xx_wdt.c 2011-08-06 09:32:37.118022037 +0200 ++++ linux-2.6.39/drivers/watchdog/ar71xx_wdt.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,299 @@ +/* + * Driver for the Atheros AR71xx SoC's built-in hardware watchdog timer. @@ -27431,37 +24418,9 @@ diff -Nur linux-2.6.39.orig/drivers/watchdog/ar71xx_wdt.c linux-2.6.39/drivers/w +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -diff -Nur linux-2.6.39.orig/drivers/watchdog/Kconfig linux-2.6.39/drivers/watchdog/Kconfig ---- linux-2.6.39.orig/drivers/watchdog/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/watchdog/Kconfig 2011-08-22 16:22:00.627980889 +0200 -@@ -990,6 +990,13 @@ - To compile this driver as a loadable module, choose M here. - The module will be called bcm63xx_wdt. - -+config AR71XX_WDT -+ tristate "Atheros AR71xx Watchdog Timer" -+ depends on ATHEROS_AR71XX -+ help -+ Hardware driver for the built-in watchdog timer on the Atheros -+ AR71xx SoCs. -+ - # PARISC Architecture - - # POWERPC Architecture -diff -Nur linux-2.6.39.orig/drivers/watchdog/Makefile linux-2.6.39/drivers/watchdog/Makefile ---- linux-2.6.39.orig/drivers/watchdog/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/watchdog/Makefile 2011-08-22 16:22:00.647986892 +0200 -@@ -119,6 +119,7 @@ - obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o - obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o - obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o -+obj-$(CONFIG_AR71XX_WDT) += ar71xx_wdt.o - obj-$(CONFIG_AR7_WDT) += ar7_wdt.o - obj-$(CONFIG_TXX9_WDT) += txx9wdt.o - obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o diff -Nur linux-2.6.39.orig/include/linux/ath9k_platform.h linux-2.6.39/include/linux/ath9k_platform.h --- linux-2.6.39.orig/include/linux/ath9k_platform.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/include/linux/ath9k_platform.h 2011-08-06 09:32:36.638021723 +0200 ++++ linux-2.6.39/include/linux/ath9k_platform.h 2011-08-24 18:17:24.000000000 +0200 @@ -23,6 +23,15 @@ struct ath9k_platform_data { @@ -27480,7 +24439,7 @@ diff -Nur linux-2.6.39.orig/include/linux/ath9k_platform.h linux-2.6.39/include/ #endif /* _LINUX_ATH9K_PLATFORM_H */ diff -Nur linux-2.6.39.orig/include/linux/ip.h linux-2.6.39/include/linux/ip.h --- linux-2.6.39.orig/include/linux/ip.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/include/linux/ip.h 2011-08-24 05:53:21.239229027 +0200 ++++ linux-2.6.39/include/linux/ip.h 2011-08-24 18:17:24.000000000 +0200 @@ -102,7 +102,7 @@ __be32 saddr; __be32 daddr; @@ -27492,7 +24451,7 @@ diff -Nur linux-2.6.39.orig/include/linux/ip.h linux-2.6.39/include/linux/ip.h #include diff -Nur linux-2.6.39.orig/include/linux/ipv6.h linux-2.6.39/include/linux/ipv6.h --- linux-2.6.39.orig/include/linux/ipv6.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/include/linux/ipv6.h 2011-08-24 05:53:21.289229059 +0200 ++++ linux-2.6.39/include/linux/ipv6.h 2011-08-24 18:17:24.000000000 +0200 @@ -126,7 +126,7 @@ struct in6_addr saddr; @@ -27504,7 +24463,7 @@ diff -Nur linux-2.6.39.orig/include/linux/ipv6.h linux-2.6.39/include/linux/ipv6 /* diff -Nur linux-2.6.39.orig/include/linux/myloader.h linux-2.6.39/include/linux/myloader.h --- linux-2.6.39.orig/include/linux/myloader.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/include/linux/myloader.h 2011-08-24 03:12:08.307985040 +0200 ++++ linux-2.6.39/include/linux/myloader.h 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,120 @@ +/* + * Compex's MyLoader specific definitions @@ -27628,7 +24587,7 @@ diff -Nur linux-2.6.39.orig/include/linux/myloader.h linux-2.6.39/include/linux/ +#endif /* _MYLOADER_H_*/ diff -Nur linux-2.6.39.orig/include/linux/netdevice.h linux-2.6.39/include/linux/netdevice.h --- linux-2.6.39.orig/include/linux/netdevice.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/include/linux/netdevice.h 2011-08-22 22:00:06.937981400 +0200 ++++ linux-2.6.39/include/linux/netdevice.h 2011-08-24 18:17:24.000000000 +0200 @@ -1182,6 +1182,7 @@ void *ax25_ptr; /* AX.25 specific data */ struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data, @@ -27639,7 +24598,7 @@ diff -Nur linux-2.6.39.orig/include/linux/netdevice.h linux-2.6.39/include/linux * Cache lines mostly used on receive path (including eth_type_trans()) diff -Nur linux-2.6.39.orig/include/linux/nxp_74hc153.h linux-2.6.39/include/linux/nxp_74hc153.h --- linux-2.6.39.orig/include/linux/nxp_74hc153.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/include/linux/nxp_74hc153.h 2011-04-27 12:19:21.817661653 +0200 ++++ linux-2.6.39/include/linux/nxp_74hc153.h 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,24 @@ +/* + * NXP 74HC153 - Dual 4-input multiplexer defines @@ -27667,7 +24626,7 @@ diff -Nur linux-2.6.39.orig/include/linux/nxp_74hc153.h linux-2.6.39/include/lin +#endif /* _NXP_74HC153_H */ diff -Nur linux-2.6.39.orig/include/linux/phy.h linux-2.6.39/include/linux/phy.h --- linux-2.6.39.orig/include/linux/phy.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/include/linux/phy.h 2011-08-22 22:00:06.867980866 +0200 ++++ linux-2.6.39/include/linux/phy.h 2011-08-24 18:17:24.000000000 +0200 @@ -332,6 +332,20 @@ void (*adjust_link)(struct net_device *dev); @@ -27699,7 +24658,7 @@ diff -Nur linux-2.6.39.orig/include/linux/phy.h linux-2.6.39/include/linux/phy.h int phy_start_interrupts(struct phy_device *phydev); diff -Nur linux-2.6.39.orig/include/linux/spi/spi.h linux-2.6.39/include/linux/spi/spi.h --- linux-2.6.39.orig/include/linux/spi/spi.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/include/linux/spi/spi.h 2011-08-23 15:10:37.559229523 +0200 ++++ linux-2.6.39/include/linux/spi/spi.h 2011-08-24 18:17:24.000000000 +0200 @@ -441,6 +441,8 @@ dma_addr_t rx_dma; @@ -27719,7 +24678,7 @@ diff -Nur linux-2.6.39.orig/include/linux/spi/spi.h linux-2.6.39/include/linux/s * last transfer ... allowing things like "read 16 bit length L" diff -Nur linux-2.6.39.orig/include/linux/spi/vsc7385.h linux-2.6.39/include/linux/spi/vsc7385.h --- linux-2.6.39.orig/include/linux/spi/vsc7385.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/include/linux/spi/vsc7385.h 2011-04-27 12:19:21.817661653 +0200 ++++ linux-2.6.39/include/linux/spi/vsc7385.h 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,19 @@ +/* + * Platform data definition for the Vitesse VSC7385 ethernet switch driver @@ -27742,7 +24701,7 @@ diff -Nur linux-2.6.39.orig/include/linux/spi/vsc7385.h linux-2.6.39/include/lin +}; diff -Nur linux-2.6.39.orig/include/linux/switch.h linux-2.6.39/include/linux/switch.h --- linux-2.6.39.orig/include/linux/switch.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/include/linux/switch.h 2011-08-22 22:09:59.799231408 +0200 ++++ linux-2.6.39/include/linux/switch.h 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,204 @@ +/* + * switch.h: Switch configuration API @@ -27950,7 +24909,7 @@ diff -Nur linux-2.6.39.orig/include/linux/switch.h linux-2.6.39/include/linux/sw +#endif diff -Nur linux-2.6.39.orig/include/linux/tcp.h linux-2.6.39/include/linux/tcp.h --- linux-2.6.39.orig/include/linux/tcp.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/include/linux/tcp.h 2011-08-24 05:53:21.379228748 +0200 ++++ linux-2.6.39/include/linux/tcp.h 2011-08-24 18:17:24.000000000 +0200 @@ -54,7 +54,7 @@ __be16 window; __sum16 check; @@ -27962,7 +24921,7 @@ diff -Nur linux-2.6.39.orig/include/linux/tcp.h linux-2.6.39/include/linux/tcp.h * The union cast uses a gcc extension to avoid aliasing problems diff -Nur linux-2.6.39.orig/include/linux/udp.h linux-2.6.39/include/linux/udp.h --- linux-2.6.39.orig/include/linux/udp.h 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/include/linux/udp.h 2011-08-24 05:53:21.428824967 +0200 ++++ linux-2.6.39/include/linux/udp.h 2011-08-24 18:17:24.000000000 +0200 @@ -24,7 +24,7 @@ __be16 dest; __be16 len; @@ -27974,7 +24933,7 @@ diff -Nur linux-2.6.39.orig/include/linux/udp.h linux-2.6.39/include/linux/udp.h #define UDP_CORK 1 /* Never send partially complete segments */ diff -Nur linux-2.6.39.orig/net/dsa/mv88e6063.c linux-2.6.39/net/dsa/mv88e6063.c --- linux-2.6.39.orig/net/dsa/mv88e6063.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/net/dsa/mv88e6063.c 2011-04-27 12:19:21.827661792 +0200 ++++ linux-2.6.39/net/dsa/mv88e6063.c 2011-08-24 18:17:24.000000000 +0200 @@ -0,0 +1,294 @@ +/* + * net/dsa/mv88e6063.c - Driver for Marvell 88e6063 switch chips @@ -28272,7 +25231,7 @@ diff -Nur linux-2.6.39.orig/net/dsa/mv88e6063.c linux-2.6.39/net/dsa/mv88e6063.c +module_exit(mv88e6063_cleanup); diff -Nur linux-2.6.39.orig/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c linux-2.6.39/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c --- linux-2.6.39.orig/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 2011-08-24 05:53:21.549229118 +0200 ++++ linux-2.6.39/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 2011-08-24 18:17:24.000000000 +0200 @@ -14,6 +14,7 @@ #include #include -- cgit v1.2.3 From 8aebf811b766c899d97620874cf39e37b6e4f7a7 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 24 Aug 2011 19:52:33 +0200 Subject: honour target cflags/cxxflags, add explizit search paths for headers and library for non-sysroot toolchains --- package/openjdk/Makefile | 4 ++++ package/openjdk/patches/cxxflags-nozlib.patch | 31 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 package/openjdk/patches/cxxflags-nozlib.patch diff --git a/package/openjdk/Makefile b/package/openjdk/Makefile index 347f3b01d..4bb68bb88 100644 --- a/package/openjdk/Makefile +++ b/package/openjdk/Makefile @@ -98,7 +98,10 @@ CONFIGURE_ENV+= PATH=$(STAGING_JAVA_HOST_DIR)/usr/bin:$${PATH}:${STAGING_TARGET MAKE_ENV+= ALT_COMPILER_PATH=$(STAGING_HOST_DIR)/$(REAL_GNU_TARGET_NAME) \ ADK_ECJ=$(STAGING_JAVA_HOST_DIR)/usr/bin/ecj \ PATH=$(STAGING_JAVA_HOST_DIR)/usr/bin:$${PATH}:${STAGING_TARGET_DIR}/usr/bin \ + OTHER_CFLAGS='$(TARGET_CFLAGS) $(TARGET_CPPFLAGS) $(TARGET_LDFLAGS)' \ + OTHER_CXXFLAGS='$(TARGET_CFLAGS) $(TARGET_CPPFLAGS) $(TARGET_LDFLAGS)' \ GCC_HONOUR_COPTS=s CROSS_COMPILE_ARCH=$(ARCH) + ALL_TARGET:= icedtea # add include path for Xrender.h from staging directory @@ -107,6 +110,7 @@ ifeq ($(QEMU),) $(error Fatal error: $$QEMU not set!) endif $(SED) "s#@ADK_TARGETDIR@#$(STAGING_TARGET_DIR)#" ${WRKDIST}/$(PKG_NAME)-$(PKG_VERSION)/jdk/make/sun/xawt/Makefile + $(SED) "s#OTHER_CXXFLAGS#CXXFLAGS_COMMON#" ${WRKDIST}/$(PKG_NAME)-$(PKG_VERSION)/jdk/make/com/sun/java/pack/Makefile do-extract: cd ${WRKDIST}; mkdir $(PKG_NAME)-$(PKG_VERSION); \ diff --git a/package/openjdk/patches/cxxflags-nozlib.patch b/package/openjdk/patches/cxxflags-nozlib.patch new file mode 100644 index 000000000..67812253a --- /dev/null +++ b/package/openjdk/patches/cxxflags-nozlib.patch @@ -0,0 +1,31 @@ +--- w-openjdk-6.orig/icedtea6-1.10/patches/libraries.patch 2011-02-23 23:32:34.602901049 +0100 ++++ w-openjdk-6/icedtea6-1.10/patches/libraries.patch 2011-08-24 15:07:24.347475241 +0200 +@@ -24648,7 +24648,7 @@ + - $(ZIPOBJDIR)/inffast.$(OBJECT_SUFFIX) + - + - ZINCLUDE=-I$(SHARE_SRC)/native/java/util/zip/zlib-1.1.3 +-- OTHER_CXXFLAGS += $(ZINCLUDE) ++- CXXFLAGS_COMMON += $(ZINCLUDE) + - LDDFLAGS += $(ZIPOBJS) + + $(ZIPOBJDIR)/deflate.$(OBJECT_SUFFIX) \ + + $(ZIPOBJDIR)/trees.$(OBJECT_SUFFIX) \ +@@ -24663,7 +24663,7 @@ + + + + OTHER_LDLIBS += -lz + else +- OTHER_CXXFLAGS += -DNO_ZLIB -DUNPACK_JNI ++ CXXFLAGS_COMMON += -DNO_ZLIB -DUNPACK_JNI + - OTHER_LDLIBS += $(JVMLIB) + + OTHER_LDLIBS += -lz $(JVMLIB) + endif +--- w-openjdk-6.orig/icedtea6-1.10/patches/linker-libs-order.patch 2011-02-23 23:32:34.653236038 +0100 ++++ w-openjdk-6/icedtea6-1.10/patches/linker-libs-order.patch 2011-08-24 15:53:05.047474381 +0200 +@@ -31,7 +31,7 @@ + + - OTHER_LDLIBS += -lz + else +- OTHER_CXXFLAGS += -DNO_ZLIB -DUNPACK_JNI ++ CXXFLAGS_COMMON += -DNO_ZLIB -DUNPACK_JNI + - OTHER_LDLIBS += -lz $(JVMLIB) + + OTHER_LDLIBS += $(JVMLIB) + endif -- cgit v1.2.3 From b2e4d29ea9c3c2f5b99264bd270d4257439dfc3f Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Fri, 26 Aug 2011 10:21:17 +0200 Subject: simplify patch, link instead of copy is okay for Linux host --- jtools/openjdk/patches/openjdk.patch | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/jtools/openjdk/patches/openjdk.patch b/jtools/openjdk/patches/openjdk.patch index 1ef7e195f..85fbb87f4 100644 --- a/jtools/openjdk/patches/openjdk.patch +++ b/jtools/openjdk/patches/openjdk.patch @@ -1,4 +1,6 @@ -diff -Nur openjdk-6.orig/Makefile openjdk-6/Makefile + +use precompiled ecj. + --- openjdk-6.orig/Makefile 2011-02-28 17:02:07.000000000 +0100 +++ openjdk-6/Makefile 2011-04-06 19:47:19.261818496 +0200 @@ -25,9 +25,7 @@ @@ -12,27 +14,8 @@ diff -Nur openjdk-6.orig/Makefile openjdk-6/Makefile ifndef JDK_TOPDIR JDK_TOPDIR=$(TOPDIR)/jdk -diff -Nur icedtea6-1.10.orig/Makefile.in icedtea6-1.10/Makefile.in --- icedtea6-1.10.orig/Makefile.in 2011-03-02 20:48:45.161291458 +0100 +++ icedtea6-1.10/Makefile.in 2011-04-06 20:10:40.581819545 +0200 -@@ -1329,7 +1329,7 @@ - @OPENJDK_SRC_DIR_FOUND_TRUE@ cp -pPR $(OPENJDK_SRC_DIR_LINK) $(OPENJDK_SRC_DIR) openjdk ; \ - @OPENJDK_SRC_DIR_FOUND_TRUE@ fi - @OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_TRUE@ if ! test -d openjdk ; then \ --@OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_TRUE@ cp -pPRl openjdk.hg openjdk ; \ -+@OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_TRUE@ cp -pPR openjdk.hg openjdk ; \ - @OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_TRUE@ fi - @OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_FALSE@ set -e ; \ - @OPENJDK_SRC_DIR_FOUND_FALSE@@USE_HG_FALSE@ if ! test -d openjdk ; \ -@@ -1576,7 +1576,7 @@ - # FIXME (missing): Rename to clone-ecj. - stamps/extract-ecj.stamp: $(OPENJDK_TREE) - if ! test -d openjdk-ecj ; then \ -- cp -pPRl openjdk openjdk-ecj ; \ -+ cp -pPR openjdk openjdk-ecj ; \ - fi - mkdir -p stamps - touch stamps/extract-ecj.stamp @@ -1643,10 +1643,14 @@ stamps/native-ecj.stamp: -- cgit v1.2.3 From 5b264e378044b2de6541676d0c04d50e97c98f60 Mon Sep 17 00:00:00 2001 From: warhog Date: Sat, 27 Aug 2011 17:34:45 +0200 Subject: added intel atom target --- target/config/Config.in | 16 ++++ target/config/Config.in.runtime | 125 ++++++++++++++++++++++++++++++++ target/linux/config/Config.in.block | 4 + target/linux/config/Config.in.cpu | 21 ++++++ target/linux/config/Config.in.graphics | 6 +- target/linux/config/Config.in.input | 10 +++ target/linux/config/Config.in.netdevice | 4 + target/linux/config/Config.in.pm | 6 ++ target/linux/config/Config.in.sensors | 25 +++++++ target/linux/config/Config.in.usb | 8 ++ target/x86/sys-available/intel-atom | 28 +++++++ 11 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 target/linux/config/Config.in.sensors create mode 100644 target/x86/sys-available/intel-atom diff --git a/target/config/Config.in b/target/config/Config.in index 62bcbf071..d2e55fe52 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -218,6 +218,16 @@ config ADK_TARGET_CPU_WITH_SSE config ADK_TARGET_CPU_WITH_SSE2 boolean +config ADK_TARGET_CPU_WITH_SSE3 + boolean + +config ADK_TARGET_CPU_WITH_SSSE3 + boolean + +# hyper threading +config ADK_TARGET_CPU_WITH_HT + boolean + config ADK_TARGET_CPU_WITH_3DNOW boolean @@ -255,6 +265,9 @@ config ADK_CPU_PPC64 config ADK_CPU_PENTIUM_M boolean +config ADK_CPU_ATOM + boolean + config ADK_CPU_AMDFAM10 select ADK_TARGET_CPU_WITH_VT boolean @@ -273,6 +286,7 @@ config ADK_TARGET_CPU_ARCH default "i686" if ADK_CPU_I686 default "i586" if ADK_CPU_GEODE default "i686" if ADK_CPU_PENTIUM_M + default "i686" if ADK_CPU_ATOM default "mips64" if ADK_LINUX_MIPS && ADK_big && ADK_TARGET_KERNEL64 default "mips64el" if ADK_LINUX_MIPS && ADK_little && ADK_TARGET_KERNEL64 default "mips" if ADK_LINUX_MIPS && ADK_big @@ -302,6 +316,7 @@ config ADK_TARGET_CFLAGS default "-march=i586" if ADK_CPU_I586 default "-march=i686" if ADK_CPU_I686 default "-march=pentium-m" if ADK_CPU_PENTIUM_M + default "-march=atom" if ADK_CPU_ATOM default "-march=amdfam10" if ADK_CPU_AMDFAM10 default "-mcpu=v8" if ADK_CPU_SPARC_V8 default "-m64 -mcpu=v9" if ADK_CPU_SPARC_V9 @@ -317,6 +332,7 @@ config ADK_TARGET_CMDLINE default "console=ttyS0,38400" if ADK_TARGET_SYSTEM_PCENGINES_WRAP default "console=ttyS0,115200 console=tty0 geodewdt.nowayout=1" if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_IBM_X40 + default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_INTEL_ATOM default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_FOXBOARD_LX diff --git a/target/config/Config.in.runtime b/target/config/Config.in.runtime index dec6f3839..0503eb8d9 100644 --- a/target/config/Config.in.runtime +++ b/target/config/Config.in.runtime @@ -141,3 +141,128 @@ config ADK_BINSH_ZSH Use zsh as system shell. This is probably a bad idea. endchoice + + + + + +config ADK_SIMPLE_NETWORK_CONFIG + prompt "simple network configuration" + boolean + help + Manually change network config + + WWW: http://www.openadk.org + +menu "eth0 Configuration" +depends on ADK_SIMPLE_NETWORK_CONFIG + +choice + prompt "Type" + default SIMPLE_NETWORK_CONFIG_ETH0_TYPE_NIC + +config SIMPLE_NETWORK_CONFIG_ETH0_TYPE_NIC + bool "NIC / DHCP" + +config SIMPLE_NETWORK_CONFIG_ETH0_TYPE_NIC_MANUAL + bool "NIC / manual IP" + +config SIMPLE_NETWORK_CONFIG_ETH0_TYPE_BRIDGE_IP + bool "Bridge with IP" + +config SIMPLE_NETWORK_CONFIG_ETH0_TYPE_BRIDGE + bool "Bridge w/o IP" + +config SIMPLE_NETWORK_CONFIG_ETH0_TYPE_NONE + bool "None" +endchoice + +config SIMPLE_NETWORK_CONFIG_ETH0_IP + depends on SIMPLE_NETWORK_CONFIG_ETH0_TYPE_NIC_MANUAL || SIMPLE_NETWORK_CONFIG_ETH0_TYPE_BRIDGE_IP + string "eth0 IP Address" + default "192.168.1.2" + +config SIMPLE_NETWORK_CONFIG_ETH0_NM + depends on SIMPLE_NETWORK_CONFIG_ETH0_TYPE_NIC_MANUAL || SIMPLE_NETWORK_CONFIG_ETH0_TYPE_BRIDGE_IP + string "eth0 Netmask" + default "255.255.255.0" + +config SIMPLE_NETWORK_CONFIG_ETH0_GW + depends on SIMPLE_NETWORK_CONFIG_ETH0_TYPE_NIC_MANUAL + string "eth0 Gateway" + default "192.168.1.1" + +config SIMPLE_NETWORK_CONFIG_ETH0_BRIDGE + depends on SIMPLE_NETWORK_CONFIG_ETH0_TYPE_BRIDGE || SIMPLE_NETWORK_CONFIG_ETH0_TYPE_BRIDGE_IP + string "Bridge ports" + default "eth0 eth1" + +config SIMPLE_NETWORK_CONFIG_ETH0_BC + depends on SIMPLE_NETWORK_CONFIG_ETH0_TYPE_NIC_MANUAL || SIMPLE_NETWORK_CONFIG_ETH0_TYPE_BRIDGE_IP + string "eth0 Broadcast" + default "+" + +endmenu + + + +menu "eth1 Configuration" +depends on ADK_SIMPLE_NETWORK_CONFIG + +choice + prompt "Type" + default SIMPLE_NETWORK_CONFIG_ETH1_TYPE_NONE + +config SIMPLE_NETWORK_CONFIG_ETH1_TYPE_NIC + bool "NIC / DHCP" + +config SIMPLE_NETWORK_CONFIG_ETH1_TYPE_NIC_MANUAL + bool "NIC / manual IP" + +config SIMPLE_NETWORK_CONFIG_ETH1_TYPE_BRIDGE_IP + bool "Bridge with IP" + +config SIMPLE_NETWORK_CONFIG_ETH1_TYPE_BRIDGE + bool "Bridge w/o IP" + +config SIMPLE_NETWORK_CONFIG_ETH1_TYPE_NONE + bool "None" +endchoice + +config SIMPLE_NETWORK_CONFIG_ETH1_IP + depends on SIMPLE_NETWORK_CONFIG_ETH1_TYPE_NIC_MANUAL || SIMPLE_NETWORK_CONFIG_ETH1_TYPE_BRIDGE_IP + string "eth1 IP Address" + default "192.168.1.2" + +config SIMPLE_NETWORK_CONFIG_ETH1_NM + depends on SIMPLE_NETWORK_CONFIG_ETH1_TYPE_NIC_MANUAL || SIMPLE_NETWORK_CONFIG_ETH1_TYPE_BRIDGE_IP + string "eth1 Netmask" + default "255.255.255.0" + +config SIMPLE_NETWORK_CONFIG_ETH1_GW + depends on SIMPLE_NETWORK_CONFIG_ETH1_TYPE_NIC_MANUAL + string "eth1 Gateway" + default "192.168.1.1" + +config SIMPLE_NETWORK_CONFIG_ETH1_BRIDGE + depends on SIMPLE_NETWORK_CONFIG_ETH1_TYPE_BRIDGE || SIMPLE_NETWORK_CONFIG_ETH1_TYPE_BRIDGE_IP + string "Bridge ports" + default "eth1 eth2" + +config SIMPLE_NETWORK_CONFIG_ETH1_BC + depends on SIMPLE_NETWORK_CONFIG_ETH1_TYPE_NIC_MANUAL || SIMPLE_NETWORK_CONFIG_ETH1_TYPE_BRIDGE_IP + string "eth1 Broadcast" + default "+" + +endmenu + + +menu "Resolver Configuration" +depends on ADK_SIMPLE_NETWORK_CONFIG + +config SIMPLE_NETWORK_CONFIG_RESOLV + string "Nameserver" + default "192.168.1.1" + +endmenu + diff --git a/target/linux/config/Config.in.block b/target/linux/config/Config.in.block index 78e7b1bd5..8f673438d 100644 --- a/target/linux/config/Config.in.block +++ b/target/linux/config/Config.in.block @@ -129,6 +129,8 @@ config ADK_KERNEL_ATA_PIIX default y if ADK_TARGET_SYSTEM_QEMU_X86_64 default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default n config ADK_KERNEL_SATA_AHCI @@ -150,6 +152,8 @@ config ADK_KPACKAGE_KMOD_SATA_AHCI select ADK_KERNEL_BLK_DEV_SD depends on !ADK_KERNEL_SATA_AHCI depends on ADK_TARGET_WITH_SATA + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default n help Enables support for AHCI Serial ATA. diff --git a/target/linux/config/Config.in.cpu b/target/linux/config/Config.in.cpu index 64d9e9f3f..5be6dacfc 100644 --- a/target/linux/config/Config.in.cpu +++ b/target/linux/config/Config.in.cpu @@ -11,3 +11,24 @@ config ADK_KERNEL_MTRR boolean default y if ADK_TARGET_CPU_WITH_MTRR default n + +# hyper threading +config ADK_KERNEL_PM_SLEEP_SMP + boolean + default y if ADK_TARGET_CPU_WITH_HT + default n + +config ADK_KERNEL_SMP + boolean + default y if ADK_TARGET_CPU_WITH_HT + default n + +config ADK_KERNEL_X86_HT + boolean + default y if ADK_TARGET_CPU_WITH_HT + default n + +config ADK_KERNEL_USE_GENERIC_SMP_HELPERS + boolean + default y if ADK_TARGET_CPU_WITH_HT + default n diff --git a/target/linux/config/Config.in.graphics b/target/linux/config/Config.in.graphics index 667593de9..5cbe307f0 100644 --- a/target/linux/config/Config.in.graphics +++ b/target/linux/config/Config.in.graphics @@ -3,6 +3,7 @@ config ADK_KERNEL_VT default y if ADK_HARDWARE_QEMU default y if ADK_TARGET_WITH_VGA default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default n config ADK_KERNEL_VT_CONSOLE @@ -10,6 +11,7 @@ config ADK_KERNEL_VT_CONSOLE default y if ADK_HARDWARE_QEMU default y if ADK_TARGET_WITH_VGA default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default n config ADK_KERNEL_FONTS @@ -71,7 +73,7 @@ config ADK_KERNEL_FB_SM7XX Framebuffer support for Lemote Yeelong. config ADK_HARDWARE_GRAPHICS_INTEL_I915 - prompt "................................ Support for Intel graphic cards (AGP/DRM/KMS)" + prompt "............................ Support for Intel graphic cards (AGP/DRM/KMS/NM10)" boolean select ADK_KERNEL_FB select ADK_KERNEL_DRM @@ -83,7 +85,7 @@ config ADK_HARDWARE_GRAPHICS_INTEL_I915 default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 default n - depends on ADK_TARGET_SYSTEM_IBM_X40 || ADK_NATIVE_SYSTEM_IBM_X40 + depends on ADK_TARGET_SYSTEM_IBM_X40 || ADK_NATIVE_SYSTEM_IBM_X40 || ADK_TARGET_SYSTEM_INTEL_ATOM || ADK_NATIVE_SYSTEM_INTEL_ATOM help AGP/DRM/KMS support for Intel chipset i915. diff --git a/target/linux/config/Config.in.input b/target/linux/config/Config.in.input index b8566e569..65524a0d3 100644 --- a/target/linux/config/Config.in.input +++ b/target/linux/config/Config.in.input @@ -6,6 +6,8 @@ config ADK_KERNEL_INPUT default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG default y if ADK_TARGET_SYSTEM_SHUTTLE_SA76G2 default n @@ -15,6 +17,8 @@ config ADK_KERNEL_INPUT_KEYBOARD default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG default y if ADK_TARGET_SYSTEM_SHUTTLE_SA76G2 default n @@ -24,6 +28,8 @@ config ADK_KERNEL_KEYBOARD_ATKBD default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG default y if ADK_TARGET_SYSTEM_SHUTTLE_SA76G2 default n @@ -33,6 +39,8 @@ config ADK_KERNEL_INPUT_MOUSE default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG default y if ADK_TARGET_SYSTEM_SHUTTLE_SA76G2 default n @@ -42,6 +50,8 @@ config ADK_KERNEL_INPUT_MOUSEDEV default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG default y if ADK_TARGET_SYSTEM_SHUTTLE_SA76G2 default n diff --git a/target/linux/config/Config.in.netdevice b/target/linux/config/Config.in.netdevice index d9a8cd9dc..c4df54f32 100644 --- a/target/linux/config/Config.in.netdevice +++ b/target/linux/config/Config.in.netdevice @@ -154,6 +154,8 @@ config ADK_KERNEL_R8169 select ADK_KERNEL_NETDEVICES select ADK_KERNEL_NET_ETHERNET select ADK_KERNEL_NETDEV_1000 + select ADK_KERNEL_MII + select ADK_KPACKAGE_KMOD_FW_LOADER default y if ADK_TARGET_SYSTEM_OVH_RPS default n help @@ -246,6 +248,8 @@ config ADK_KPACKAGE_KMOD_R8169 select ADK_KERNEL_NETDEVICES select ADK_KERNEL_NET_ETHERNET select ADK_KERNEL_NETDEV_1000 + select ADK_KERNEL_MII + select ADK_KPACKAGE_KMOD_FW_LOADER depends on !ADK_KERNEL_R8169 default n help diff --git a/target/linux/config/Config.in.pm b/target/linux/config/Config.in.pm index 5ffd8aca9..4e35a12b2 100644 --- a/target/linux/config/Config.in.pm +++ b/target/linux/config/Config.in.pm @@ -36,6 +36,8 @@ config ADK_HARDWARE_ACPI select ADK_KERNEL_ACPI_BUTTON select ADK_KERNEL_ACPI_FAN select ADK_KERNEL_ACPI_DOCK + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 default n @@ -46,6 +48,8 @@ config ADK_KERNEL_SUSPEND prompt "Enable Suspend-to-RAM support" boolean select ADK_KERNEL_PM + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 default n @@ -58,6 +62,8 @@ config ADK_KERNEL_HIBERNATION select ADK_KERNEL_PM select ADK_KERNEL_SWAP select BUSYBOX_SWAPONOFF + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 default n diff --git a/target/linux/config/Config.in.sensors b/target/linux/config/Config.in.sensors new file mode 100644 index 000000000..941913bbd --- /dev/null +++ b/target/linux/config/Config.in.sensors @@ -0,0 +1,25 @@ +menu "Sensors" + +config ADK_KERNEL_HWMON + boolean + +config ADK_KPACKAGE_KMOD_CORETEMP + prompt "kmod-coretemp..................... Coretemp" + boolean + select ADK_KERNEL_I2C + select ADK_KERNEL_I2C_CHARDEV + select ADK_KERNEL_HWMON + select ADK_KERNEL_EXPERIMENTAL + default n + help + Coretemp module + +config ADK_KPACKAGE_KMOD_IT87 + prompt "kmod-it87......................... it87" + boolean + default n + help + Module for IT87 smbus chipsets + +endmenu + diff --git a/target/linux/config/Config.in.usb b/target/linux/config/Config.in.usb index f16ef7dab..057fa1ffc 100644 --- a/target/linux/config/Config.in.usb +++ b/target/linux/config/Config.in.usb @@ -35,6 +35,8 @@ config ADK_KPACKAGE_KMOD_USB default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG default y if ADK_TARGET_SYSTEM_ACMESYSTEMS_FOXG20 default y if ADK_TARGET_SYSTEM_FOXBOARD_LX @@ -78,6 +80,8 @@ config ADK_KPACKAGE_KMOD_USB_UHCI_HCD depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG default n help @@ -101,6 +105,8 @@ config ADK_KPACKAGE_KMOD_USB_OHCI_HCD default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 default y if ADK_TARGET_SYSTEM_ACMESYSTEMS_FOXG20 + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default n help The Open Host Controller Interface (OHCI) is a standard for accessing @@ -152,6 +158,8 @@ config ADK_KPACKAGE_KMOD_USB_EHCI_HCD default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 + default y if ADK_TARGET_SYSTEM_INTEL_ATOM + default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG diff --git a/target/x86/sys-available/intel-atom b/target/x86/sys-available/intel-atom new file mode 100644 index 000000000..392a74d64 --- /dev/null +++ b/target/x86/sys-available/intel-atom @@ -0,0 +1,28 @@ +config ADK_TARGET_SYSTEM_INTEL_ATOM + bool "Intel Atom (NM10)" + select ADK_x86 + select ADK_intel_atom + select ADK_CPU_ATOM + select ADK_KERNEL_MATOM + select ADK_KERNEL_MII + select ADK_TARGET_CPU_WITH_MMX + select ADK_TARGET_CPU_WITH_SSE + select ADK_TARGET_CPU_WITH_SSE2 + select ADK_TARGET_CPU_WITH_SSE3 + select ADK_TARGET_CPU_WITH_SSSE3 + select ADK_TARGET_CPU_WITH_HT + select ADK_TARGET_CPU_WITH_MTRR + select ADK_TARGET_WITH_USB_BOOT + select ADK_TARGET_WITH_USB + select ADK_TARGET_WITH_VGA + select ADK_TARGET_WITH_INPUT + select ADK_TARGET_WITH_RTC + select ADK_TARGET_WITH_CF + select ADK_TARGET_WITH_INPUT + select ADK_TARGET_WITH_HDD + select ADK_TARGET_WITH_PCI + select ADK_TARGET_WITH_ACPI + select ADK_TARGET_WITH_SATA + help + System profile for Intel Atom. + -- cgit v1.2.3 From 8bc6ce6bdbd29ff06c88f67b1237ee02e2fc7325 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sat, 27 Aug 2011 20:50:06 +0200 Subject: enable serial output again --- target/config/Config.in | 1 + 1 file changed, 1 insertion(+) diff --git a/target/config/Config.in b/target/config/Config.in index 62bcbf071..e664c7b53 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -317,6 +317,7 @@ config ADK_TARGET_CMDLINE default "console=ttyS0,38400" if ADK_TARGET_SYSTEM_PCENGINES_WRAP default "console=ttyS0,115200 console=tty0 geodewdt.nowayout=1" if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_IBM_X40 + default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_QEMU_X86 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_FOXBOARD_LX -- cgit v1.2.3 From d2c0d07368dbc7a9160b34970048e1b65b446222 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 29 Aug 2011 04:50:55 +0200 Subject: unbreak qemu mips --- target/linux/patches/2.6.39/mips-malta.patch | 135 +++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 target/linux/patches/2.6.39/mips-malta.patch diff --git a/target/linux/patches/2.6.39/mips-malta.patch b/target/linux/patches/2.6.39/mips-malta.patch new file mode 100644 index 000000000..cc8789dca --- /dev/null +++ b/target/linux/patches/2.6.39/mips-malta.patch @@ -0,0 +1,135 @@ +http://lkml.indiana.edu/hypermail/linux/kernel/1105.3/02199.html + +diff -Nur linux-2.6.39.orig/arch/mips/include/asm/smp-ops.h linux-2.6.39/arch/mips/include/asm/smp-ops.h +--- linux-2.6.39.orig/arch/mips/include/asm/smp-ops.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/include/asm/smp-ops.h 2011-08-29 04:39:03.360480881 +0200 +@@ -56,8 +56,43 @@ + + #endif /* !CONFIG_SMP */ + +-extern struct plat_smp_ops up_smp_ops; +-extern struct plat_smp_ops cmp_smp_ops; +-extern struct plat_smp_ops vsmp_smp_ops; ++static inline int register_up_smp_ops(void) ++{ ++#ifdef CONFIG_SMP_UP ++ extern struct plat_smp_ops up_smp_ops; ++ ++ register_smp_ops(&up_smp_ops); ++ ++ return 0; ++#else ++ return -ENODEV; ++#endif ++} ++ ++static inline int register_cmp_smp_ops(void) ++{ ++#ifdef CONFIG_MIPS_CMP ++ extern struct plat_smp_ops cmp_smp_ops; ++ ++ register_smp_ops(&cmp_smp_ops); ++ ++ return 0; ++#else ++ return -ENODEV; ++#endif ++} ++ ++static inline int register_vsmp_smp_ops(void) ++{ ++#ifdef CONFIG_MIPS_MT_SMP ++ extern struct plat_smp_ops vsmp_smp_ops; ++ ++ register_smp_ops(&vsmp_smp_ops); ++ ++ return 0; ++#else ++ return -ENODEV; ++#endif ++} + + #endif /* __ASM_SMP_OPS_H */ +diff -Nur linux-2.6.39.orig/arch/mips/mipssim/sim_setup.c linux-2.6.39/arch/mips/mipssim/sim_setup.c +--- linux-2.6.39.orig/arch/mips/mipssim/sim_setup.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/mipssim/sim_setup.c 2011-08-29 04:39:03.390480572 +0200 +@@ -59,18 +59,17 @@ + + prom_meminit(); + +-#ifdef CONFIG_MIPS_MT_SMP +- if (cpu_has_mipsmt) +- register_smp_ops(&vsmp_smp_ops); +- else +- register_smp_ops(&up_smp_ops); +-#endif ++ if (cpu_has_mipsmt) { ++ if (!register_vsmp_smp_ops()) ++ return; ++ + #ifdef CONFIG_MIPS_MT_SMTC +- if (cpu_has_mipsmt) + register_smp_ops(&ssmtc_smp_ops); +- else +- register_smp_ops(&up_smp_ops); ++ return; + #endif ++ } ++ ++ register_up_smp_ops(); + } + + static void __init serial_init(void) +diff -Nur linux-2.6.39.orig/arch/mips/mti-malta/malta-init.c linux-2.6.39/arch/mips/mti-malta/malta-init.c +--- linux-2.6.39.orig/arch/mips/mti-malta/malta-init.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/mti-malta/malta-init.c 2011-08-29 04:39:03.700480601 +0200 +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -358,15 +359,14 @@ + #ifdef CONFIG_SERIAL_8250_CONSOLE + console_config(); + #endif +-#ifdef CONFIG_MIPS_CMP + /* Early detection of CMP support */ + if (gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ)) +- register_smp_ops(&cmp_smp_ops); +- else +-#endif +-#ifdef CONFIG_MIPS_MT_SMP +- register_smp_ops(&vsmp_smp_ops); +-#endif ++ if (!register_cmp_smp_ops()) ++ return; ++ ++ if (!register_vsmp_smp_ops()) ++ return; ++ + #ifdef CONFIG_MIPS_MT_SMTC + register_smp_ops(&msmtc_smp_ops); + #endif +diff -Nur linux-2.6.39.orig/arch/mips/pmc-sierra/msp71xx/msp_setup.c linux-2.6.39/arch/mips/pmc-sierra/msp71xx/msp_setup.c +--- linux-2.6.39.orig/arch/mips/pmc-sierra/msp71xx/msp_setup.c 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/mips/pmc-sierra/msp71xx/msp_setup.c 2011-08-29 04:39:03.790480302 +0200 +@@ -228,13 +228,11 @@ + */ + msp_serial_setup(); + +-#ifdef CONFIG_MIPS_MT_SMP +- register_smp_ops(&vsmp_smp_ops); +-#endif +- ++ if (register_vsmp_smp_ops()) { + #ifdef CONFIG_MIPS_MT_SMTC +- register_smp_ops(&msp_smtc_smp_ops); ++ register_smp_ops(&msp_smtc_smp_ops); + #endif ++ } + + #ifdef CONFIG_PMCTWILED + /* -- cgit v1.2.3 From ad513e1935dcd2644e70e78f974b681366fb1bcf Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 29 Aug 2011 04:51:46 +0200 Subject: set pagesize to 4 kb for qemu --- target/linux/config/Config.in.systems | 8 ++++++++ target/mips/Makefile | 12 +++++++----- target/mips/sys-available/qemu-mipsel | 1 + 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/target/linux/config/Config.in.systems b/target/linux/config/Config.in.systems index 8750ac281..369727277 100644 --- a/target/linux/config/Config.in.systems +++ b/target/linux/config/Config.in.systems @@ -1,3 +1,10 @@ +# page size +config ADK_KERNEL_PAGE_SIZE_4KB + boolean + +config ADK_KERNEL_PAGE_SIZE_16KB + boolean + # mips systems config ADK_KERNEL_ATHEROS_AR231X boolean @@ -37,6 +44,7 @@ config ADK_KERNEL_ARCH_AT91SAM9G20 config ADK_KERNEL_MACH_ACMENETUSFOXG20 boolean +# endianesss and ABI config ADK_KERNEL_AEABI boolean diff --git a/target/mips/Makefile b/target/mips/Makefile index 00a3e8bdc..97533275a 100644 --- a/target/mips/Makefile +++ b/target/mips/Makefile @@ -98,6 +98,8 @@ imageinstall: kernel-install $(BIN_DIR)/$(ROOTFSTARBALL) endif ifeq ($(ADK_TARGET_FS),archive) imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) + @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) + @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo "The RootFS tarball is: $(BIN_DIR)/$(ROOTFSTARBALL)" ifneq ($(ADK_HARDWARE_QEMU),) @echo "Use following command to create a QEMU Image:" @@ -152,12 +154,12 @@ imageinstall: kernel-install ${BUILD_DIR}/${ROOTFSSQUASHFS} echo The image file is $(ROOTFSSQUASHFS); \ fi ifeq ($(ADK_TARGET_SYSTEM_FON_FON2100),y) - echo The kernel file is $(TARGET_KERNEL) + echo The kernel file is $(TARGET_KERNEL) endif ifeq ($(ADK_TARGET_SYSTEM_BROADCOM_BCM47XX),y) - echo 'You can flash the image via tftp:' - echo 'tftp 192.168.1.1' - echo 'tftp> binary' - echo "tftp> put $(ROOTFSSQUASHFS) upgrade_code.bin" + echo 'You can flash the image via tftp:' + echo 'tftp 192.168.1.1' + echo 'tftp> binary' + echo "tftp> put $(ROOTFSSQUASHFS) upgrade_code.bin" endif endif diff --git a/target/mips/sys-available/qemu-mipsel b/target/mips/sys-available/qemu-mipsel index fe64a6db2..918ec223e 100644 --- a/target/mips/sys-available/qemu-mipsel +++ b/target/mips/sys-available/qemu-mipsel @@ -4,6 +4,7 @@ config ADK_TARGET_SYSTEM_QEMU_MIPSEL select ADK_qemu_mipsel select ADK_little select ADK_KERNEL_MIPS_MALTA + select ADK_KERNEL_PAGE_SIZE_4KB select ADK_KERNEL_CPU_LITTLE_ENDIAN select ADK_HARDWARE_QEMU select ADK_TARGET_WITH_VGA -- cgit v1.2.3 From 83b06f4f07ae26ef02fd909f18288f43ed4c3c29 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 29 Aug 2011 04:52:58 +0200 Subject: it must be cpuarch, otherwise qemu-mips is not distinguished from qemu-mipsel --- scripts/update-sys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update-sys b/scripts/update-sys index 268184428..bcfbfa84e 100755 --- a/scripts/update-sys +++ b/scripts/update-sys @@ -50,7 +50,7 @@ config $archsym EOF if [ "${system}" = "toolchain" -o "${system}" = "qemu" ];then - sys=${system}-$arch + sys=${system}-$cpuarch else sys=$system fi -- cgit v1.2.3 From a3f13b147ab6e48be91dedbe116411196f1448b0 Mon Sep 17 00:00:00 2001 From: warhog Date: Sun, 28 Aug 2011 15:05:13 +0200 Subject: added logic for simple network config --- package/base-files/Makefile | 71 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/package/base-files/Makefile b/package/base-files/Makefile index a1cf05491..974823904 100644 --- a/package/base-files/Makefile +++ b/package/base-files/Makefile @@ -81,4 +81,75 @@ ifneq (${ADK_PACKAGE_CONFIG_IN_ETC},) chmod 600 $(IDIR_BASE_FILES)/etc/adkconfig.gz endif + + +# simple network configuration +ifneq (${ADK_SIMPLE_NETWORK_CONFIG},) + ${INSTALL_DIR} ${IDIR_BASE_FILES}/etc/network + + # network config local + echo -e "auto lo\niface lo inet loopback" > ${IDIR_BASE_FILES}/etc/network/interfaces + + # network config eth0 + # configure nic with manual ip +ifeq (${SIMPLE_NETWORK_CONFIG_ETH0_TYPE_NIC},y) + echo -e "\nauto eth0\niface eth0 inet dhcp" >> ${IDIR_BASE_FILES}/etc/network/interfaces +endif + # configure nic with dhcp +ifeq (${SIMPLE_NETWORK_CONFIG_ETH0_TYPE_NIC_MANUAL},y) + echo -e "\nauto eth0\niface eth0 inet static" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " address ${SIMPLE_NETWORK_CONFIG_ETH0_IP}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " netmask ${SIMPLE_NETWORK_CONFIG_ETH0_NM}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " broadcast ${SIMPLE_NETWORK_CONFIG_ETH0_BC}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " gateway ${SIMPLE_NETWORK_CONFIG_ETH0_GW}" >> ${IDIR_BASE_FILES}/etc/network/interfaces +endif + # configure bridge +ifeq (${SIMPLE_NETWORK_CONFIG_ETH0_TYPE_BRIDGE},y) + echo -e "\nauto br0\niface br0 inet manual" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " bridge-ports ${SIMPLE_NETWORK_CONFIG_ETH0_BRIDGE}" >> ${IDIR_BASE_FILES}/etc/network/interfaces +endif + #configure bridge with ip +ifeq (${SIMPLE_NETWORK_CONFIG_ETH0_TYPE_BRIDGE_IP},y) + echo -e "\nauto br0\niface br0 inet static" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " address ${SIMPLE_NETWORK_CONFIG_ETH0_IP}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " netmask ${SIMPLE_NETWORK_CONFIG_ETH0_NM}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " broadcast ${SIMPLE_NETWORK_CONFIG_ETH0_BC}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " bridge-ports ${SIMPLE_NETWORK_CONFIG_ETH0_BRIDGE}" >> ${IDIR_BASE_FILES}/etc/network/interfaces +endif + + # network config eth1 + # configure nic with manual ip +ifeq (${SIMPLE_NETWORK_CONFIG_ETH1_TYPE_NIC},y) + echo -e "\nauto eth1\niface eth1 inet dhcp" >> ${IDIR_BASE_FILES}/etc/network/interfaces +endif + # configure nic with dhcp +ifeq (${SIMPLE_NETWORK_CONFIG_ETH1_TYPE_NIC_MANUAL},y) + echo -e "\nauto eth1\niface eth1 inet static" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " address ${SIMPLE_NETWORK_CONFIG_ETH1_IP}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " netmask ${SIMPLE_NETWORK_CONFIG_ETH1_NM}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " broadcast ${SIMPLE_NETWORK_CONFIG_ETH1_BC}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " gateway ${SIMPLE_NETWORK_CONFIG_ETH1_GW}" >> ${IDIR_BASE_FILES}/etc/network/interfaces +endif + # configure bridge +ifeq (${SIMPLE_NETWORK_CONFIG_ETH1_TYPE_BRIDGE},y) + echo -e "\nauto br0\niface br1 inet manual" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " bridge-ports ${SIMPLE_NETWORK_CONFIG_ETH1_BRIDGE}" >> ${IDIR_BASE_FILES}/etc/network/interfaces +endif + #configure bridge with ip +ifeq (${SIMPLE_NETWORK_CONFIG_ETH1_TYPE_BRIDGE_IP},y) + echo -e "\nauto br0\niface br1 inet static" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " address ${SIMPLE_NETWORK_CONFIG_ETH1_IP}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " netmask ${SIMPLE_NETWORK_CONFIG_ETH1_NM}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " broadcast ${SIMPLE_NETWORK_CONFIG_ETH1_BC}" >> ${IDIR_BASE_FILES}/etc/network/interfaces + echo -e " bridge-ports ${SIMPLE_NETWORK_CONFIG_ETH1_BRIDGE}" >> ${IDIR_BASE_FILES}/etc/network/interfaces +endif + + # newline at the end of interfaces file + echo -en "\n" >> ${IDIR_BASE_FILES}/etc/network/interfaces + + # resolver config + echo -e "nameserver ${SIMPLE_NETWORK_CONFIG_RESOLV}" > ${IDIR_BASE_FILES}/etc/resolv.conf +endif + + include ${TOPDIR}/mk/pkg-bottom.mk -- cgit v1.2.3 From ee4ae7d878da34b9f45df1c5704d31646e1e323b Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 29 Aug 2011 06:54:20 +0200 Subject: rename to be found by update-script --- target/x86/sys-available/qemu-i686 | 13 +++++++++++++ target/x86/sys-available/qemu-x86 | 13 ------------- 2 files changed, 13 insertions(+), 13 deletions(-) create mode 100644 target/x86/sys-available/qemu-i686 delete mode 100644 target/x86/sys-available/qemu-x86 diff --git a/target/x86/sys-available/qemu-i686 b/target/x86/sys-available/qemu-i686 new file mode 100644 index 000000000..d77d074e3 --- /dev/null +++ b/target/x86/sys-available/qemu-i686 @@ -0,0 +1,13 @@ +config ADK_TARGET_SYSTEM_QEMU_I686 + bool "Qemu Emulator" + select ADK_x86 + select ADK_qemu_i686 + select ADK_CPU_I686 + select ADK_HARDWARE_QEMU + select ADK_TARGET_WITH_VGA + select ADK_TARGET_WITH_INPUT + select ADK_TARGET_WITH_PCI + select ADK_TARGET_WITH_HDD + help + Support for Qemu Emulator (i686). + diff --git a/target/x86/sys-available/qemu-x86 b/target/x86/sys-available/qemu-x86 deleted file mode 100644 index 378d9fb8e..000000000 --- a/target/x86/sys-available/qemu-x86 +++ /dev/null @@ -1,13 +0,0 @@ -config ADK_TARGET_SYSTEM_QEMU_X86 - bool "Qemu Emulator" - select ADK_x86 - select ADK_qemu_x86 - select ADK_CPU_I686 - select ADK_HARDWARE_QEMU - select ADK_TARGET_WITH_VGA - select ADK_TARGET_WITH_INPUT - select ADK_TARGET_WITH_PCI - select ADK_TARGET_WITH_HDD - help - Support for Qemu Emulator. - -- cgit v1.2.3 From e8279f5164d38207f47c83223d8cc1d2068859d2 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 29 Aug 2011 11:49:56 +0200 Subject: fix segfault in java --- package/openjdk/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package/openjdk/Makefile b/package/openjdk/Makefile index 4bb68bb88..81e057978 100644 --- a/package/openjdk/Makefile +++ b/package/openjdk/Makefile @@ -59,7 +59,9 @@ include $(TOPDIR)/mk/package.mk $(eval $(call PKG_template,OPENJDK,openjdk,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) - +# segfaults with march=pentium-m/atom +TARGET_CFLAGS:= $(subst march=pentium-m,march=i686,$(TARGET_CFLAGS)) +TARGET_CFLAGS:= $(subst march=atom,march=i686,$(TARGET_CFLAGS)) TARGET_CFLAGS:= $(filter-out -fhonour-copts,$(TARGET_CFLAGS)) BOOTSTRAPJDK:= ${STAGING_JAVA_HOST_DIR}/bootstrap-jdk -- cgit v1.2.3 From 36197e445d0bde5785bb1a823b0e83c4f5b89ccb Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 29 Aug 2011 12:28:22 +0200 Subject: add runtime dependencies for AWT --- package/openjdk/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/openjdk/Makefile b/package/openjdk/Makefile index 81e057978..542d39ac4 100644 --- a/package/openjdk/Makefile +++ b/package/openjdk/Makefile @@ -17,7 +17,7 @@ PKG_DESCR:= OpenJDK Java VM PKG_SECTION:= lang PKG_BUILDDEP:= alsa-lib xproto jpeg zlib giflib libpng freetype cups PKG_BUILDDEP+= libX11 libXt libXp libXinerama libXrender libXtst libiconv -PKG_DEPENDS:= zlib libstdcxx libffi libpthread +PKG_DEPENDS:= zlib libstdcxx libffi libpthread libxtst libxi PKG_URL:= http://openjdk.org/ PKG_SITES:= http://download.java.net/openjdk/jdk6/promoted/b22/ \ http://mirror.netcologne.de/apache.org/xml/xalan-j/binaries/ \ -- cgit v1.2.3 From f4259455c2ad5c2f74290bfa710bf7689023d423 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 30 Aug 2011 07:05:34 +0200 Subject: finetune /etc/hosts It should look like: 127.0.0.1 localhost ::1 loaclhost 127.0.1.1 hostname --- package/base-files/Makefile | 6 ++++-- package/base-files/src/etc/hosts | 2 -- target/config/Config.in.runtime | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 package/base-files/src/etc/hosts diff --git a/package/base-files/Makefile b/package/base-files/Makefile index 974823904..28fb34348 100644 --- a/package/base-files/Makefile +++ b/package/base-files/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/mk/rootfs.mk PKG_NAME:= base-files PKG_VERSION:= 1.0 -PKG_RELEASE:= 45 +PKG_RELEASE:= 46 PKG_SECTION:= base PKG_DESCR:= basic files and scripts @@ -67,7 +67,9 @@ endif $(SED) 's#@SPEED@#$(ADK_RUNTIME_CONSOLE_SERIAL_SPEED)#' $(IDIR_BASE_FILES)/etc/inittab test -z $(ADK_RUNTIME_HOSTNAME) || \ echo $(ADK_RUNTIME_HOSTNAME) > $(IDIR_BASE_FILES)/etc/hostname; \ - echo "127.0.0.1 $(ADK_RUNTIME_HOSTNAME)" >> $(IDIR_BASE_FILES)/etc/hosts + echo "127.0.0.1 localhost" > $(IDIR_BASE_FILES)/etc/hosts + echo "::1 localhost" >> $(IDIR_BASE_FILES)/etc/hosts + echo "127.0.1.1 $(ADK_RUNTIME_HOSTNAME)" >> $(IDIR_BASE_FILES)/etc/hosts test -z $(ADK_RUNTIME_PASSWORD) || \ $(SED) 's,\*NP\*,'"$$(${TOPDIR}/bin/tools/mkcrypt \ ${ADK_RUNTIME_PASSWORD}),g" $(IDIR_BASE_FILES)/etc/shadow diff --git a/package/base-files/src/etc/hosts b/package/base-files/src/etc/hosts deleted file mode 100644 index 085363292..000000000 --- a/package/base-files/src/etc/hosts +++ /dev/null @@ -1,2 +0,0 @@ -::1 localhost -127.0.0.1 localhost diff --git a/target/config/Config.in.runtime b/target/config/Config.in.runtime index 0503eb8d9..2c1ccb1d1 100644 --- a/target/config/Config.in.runtime +++ b/target/config/Config.in.runtime @@ -3,7 +3,7 @@ config ADK_RUNTIME_HOSTNAME string "hostname for the embedded system" - default "localhost" + default "openadk" help Set your target hostname. -- cgit v1.2.3 From f3750e5770ec75eb8f9a62b72a278efc57da0341 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 30 Aug 2011 07:07:40 +0200 Subject: remove man pages --- package/openjdk/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/package/openjdk/Makefile b/package/openjdk/Makefile index 542d39ac4..ddc34cacb 100644 --- a/package/openjdk/Makefile +++ b/package/openjdk/Makefile @@ -146,5 +146,6 @@ pre-configure: openjdk-install: $(INSTALL_DIR) $(IDIR_OPENJDK)/usr $(CP) $(WRKBUILD)/openjdk.build/j2re-image/* $(IDIR_OPENJDK)/usr + rm -rf $(IDIR_OPENJDK)/usr/man include ${TOPDIR}/mk/pkg-bottom.mk -- cgit v1.2.3 From 37c6990e7618cd28cae08cc5f2498910d7a7f5da Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 30 Aug 2011 07:11:22 +0200 Subject: add infrastructure for qemu-cris (still broken) --- target/config/Config.in | 10 ++ target/cris/Makefile | 19 +++ target/cris/kernel.config | 211 ++++++++++++++++++++++- target/cris/sys-available/foxboard-lx | 1 + target/cris/sys-available/qemu-cris | 15 ++ target/cris/sys-available/toolchain-cris | 3 +- target/cris/target.mk | 4 +- target/cris/uclibc.config.v32 | 243 +++++++++++++++++++++++++++ target/linux/config/Config.in.flash | 3 + target/linux/config/Config.in.systems | 4 + target/linux/patches/2.6.39/cris-etrax.patch | 12 ++ toolchain/uClibc/Makefile | 3 + 12 files changed, 520 insertions(+), 8 deletions(-) create mode 100644 target/cris/sys-available/qemu-cris create mode 100644 target/cris/uclibc.config.v32 create mode 100644 target/linux/patches/2.6.39/cris-etrax.patch diff --git a/target/config/Config.in b/target/config/Config.in index ee2c5222d..382925436 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -235,6 +235,12 @@ config ADK_TARGET_CPU_WITH_3DNOWEXT boolean # cpu configuration +config ADK_CPU_CRIS_V10 + boolean + +config ADK_CPU_CRIS_V32 + boolean + config ADK_CPU_SPARC_V8 boolean @@ -294,6 +300,8 @@ config ADK_TARGET_CPU_ARCH default "arm" if ADK_LINUX_ARM && ADK_little default "armeb" if ADK_LINUX_ARM && ADK_big default "sparc" if ADK_LINUX_SPARC + default "cris" if ADK_CPU_CRIS_V10 + default "crisv32" if ADK_CPU_CRIS_V32 default "ppc" if ADK_CPU_PPC default "ppc64" if ADK_CPU_PPC64 @@ -324,6 +332,8 @@ config ADK_TARGET_CFLAGS default "-march=mips32" if ADK_CPU_MIPS32 default "-march=mips64" if ADK_CPU_MIPS64 default "-march=armv5te -mtune=arm926ej-s" if ADK_CPU_ARMV5 + default "-march=v32" if ADK_CPU_CRIS_V32 + default "-march=v10" if ADK_CPU_CRIS_V10 config ADK_TARGET_CMDLINE string diff --git a/target/cris/Makefile b/target/cris/Makefile index 52417225e..6b744a806 100644 --- a/target/cris/Makefile +++ b/target/cris/Makefile @@ -48,3 +48,22 @@ imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo "The RootFS tarball is: $(BIN_DIR)/$(ROOTFSTARBALL)" endif +ifeq ($(ADK_TARGET_FS),initramfs) +imageinstall: $(BIN_DIR)/$(INITRAMFS) + @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) + @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' + @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_CRIS),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-cris -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' +endif +endif +ifeq ($(ADK_TARGET_FS),initramfs-piggyback) +imageinstall: ${BUILD_DIR}/${INITRAMFS_PIGGYBACK} createinitramfs + @cp $(KERNEL) $(BIN_DIR)/${TARGET_KERNEL} + @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_CRIS),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-cris -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' +endif +endif diff --git a/target/cris/kernel.config b/target/cris/kernel.config index 8fbd0d9c7..c79daaefa 100644 --- a/target/cris/kernel.config +++ b/target/cris/kernel.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux/cris 2.6.39 Kernel Configuration -# Mon Aug 22 09:21:47 2011 +# Thu Aug 25 08:32:11 2011 # CONFIG_MMU=y CONFIG_ZONE_DMA=y @@ -157,8 +157,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set CONFIG_ETRAX_CMDLINE="" -CONFIG_ETRAX_WATCHDOG=y -# CONFIG_ETRAX_WATCHDOG_NICE_DOGGY is not set +# CONFIG_ETRAX_WATCHDOG is not set CONFIG_ETRAX_FAST_TIMER=y # CONFIG_ETRAX_KMALLOCED_MODULES is not set # CONFIG_OOM_REBOOT is not set @@ -264,7 +263,111 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IPV6 is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETWORK_PHY_TIMESTAMPING is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +CONFIG_NF_CONNTRACK=m +# CONFIG_NF_CONNTRACK_MARK is not set +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +# CONFIG_NF_CONNTRACK_FTP is not set +# CONFIG_NF_CONNTRACK_H323 is not set +# CONFIG_NF_CONNTRACK_IRC is not set +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +# CONFIG_NF_CONNTRACK_SNMP is not set +# CONFIG_NF_CONNTRACK_PPTP is not set +# CONFIG_NF_CONNTRACK_SANE is not set +# CONFIG_NF_CONNTRACK_SIP is not set +# CONFIG_NF_CONNTRACK_TFTP is not set +# CONFIG_NF_CT_NETLINK is not set +CONFIG_NETFILTER_XTABLES=m + +# +# Xtables combined modules +# +# CONFIG_NETFILTER_XT_MARK is not set +# CONFIG_NETFILTER_XT_CONNMARK is not set + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set + +# +# Xtables matches +# +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set +# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_HL is not set +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +# CONFIG_NETFILTER_XT_MATCH_STATE is not set +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_FILTER is not set +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +# CONFIG_NF_NAT is not set +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set # CONFIG_RDS is not set @@ -750,7 +853,105 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_SECURITYFS is not set CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" -# CONFIG_CRYPTO is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_CRYPTO_HASH2=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=m +CONFIG_CRYPTO_PCOMP2=m +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=m +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=m +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y # # OCF Configuration diff --git a/target/cris/sys-available/foxboard-lx b/target/cris/sys-available/foxboard-lx index 0b4c81c68..edef0ffc8 100644 --- a/target/cris/sys-available/foxboard-lx +++ b/target/cris/sys-available/foxboard-lx @@ -2,6 +2,7 @@ config ADK_TARGET_SYSTEM_FOXBOARD_LX bool "FOX Board LX" select ADK_cris select ADK_foxboard_lx + select ADK_CPU_CRIS_V10 select ADK_TARGET_WITH_MTD select ADK_TARGET_WITH_USB help diff --git a/target/cris/sys-available/qemu-cris b/target/cris/sys-available/qemu-cris new file mode 100644 index 000000000..050fa1ce0 --- /dev/null +++ b/target/cris/sys-available/qemu-cris @@ -0,0 +1,15 @@ +config ADK_TARGET_SYSTEM_QEMU_CRIS + bool "Qemu Emulator" + select ADK_cris + select ADK_qemu_cris + select ADK_CPU_CRIS_V32 + select ADK_KERNEL_ETRAXFS + select ADK_KERNEL_MTD_MTDRAM + select ADK_HARDWARE_QEMU + select ADK_TARGET_WITH_INPUT + select ADK_TARGET_WITH_PCI + select ADK_TARGET_WITH_HDD + select ADK_TARGET_WITH_MTD + help + Support for Qemu Emulator (CRIS). + diff --git a/target/cris/sys-available/toolchain-cris b/target/cris/sys-available/toolchain-cris index cef2d17c2..129619e72 100644 --- a/target/cris/sys-available/toolchain-cris +++ b/target/cris/sys-available/toolchain-cris @@ -2,7 +2,8 @@ config ADK_TARGET_SYSTEM_TOOLCHAIN_CRIS bool "Toolchain only" select ADK_cris select ADK_toolchain_cris + select ADK_CPU_CRIS_V10 select ADK_TOOLCHAIN help - Build a cris toolchain. + Build a cris toolchain (crisv10). diff --git a/target/cris/target.mk b/target/cris/target.mk index a0b68f06b..9f143ef11 100644 --- a/target/cris/target.mk +++ b/target/cris/target.mk @@ -1,5 +1,5 @@ include $(TOPDIR)/mk/kernel-ver.mk ARCH:= cris -CPU_ARCH:= cris +CPU_ARCH:= $(ADK_TARGET_CPU_ARCH) TARGET_OPTIMIZATION:= -Os -pipe -fno-auto-inc-dec -fno-peephole2 -TARGET_CFLAGS_ARCH:= -march=v10 +TARGET_CFLAGS_ARCH:= $(ADK_TARGET_CFLAGS) diff --git a/target/cris/uclibc.config.v32 b/target/cris/uclibc.config.v32 new file mode 100644 index 000000000..e2c710242 --- /dev/null +++ b/target/cris/uclibc.config.v32 @@ -0,0 +1,243 @@ +# +# Automatically generated make config: don't edit +# Version: 0.9.32 +# Wed Aug 24 20:05:46 2011 +# +# TARGET_alpha is not set +# TARGET_arm is not set +# TARGET_avr32 is not set +# TARGET_bfin is not set +TARGET_cris=y +# TARGET_e1 is not set +# TARGET_frv is not set +# TARGET_h8300 is not set +# TARGET_hppa is not set +# TARGET_i386 is not set +# TARGET_i960 is not set +# TARGET_ia64 is not set +# TARGET_m68k is not set +# TARGET_microblaze is not set +# TARGET_mips is not set +# TARGET_nios is not set +# TARGET_nios2 is not set +# TARGET_powerpc is not set +# TARGET_sh is not set +# TARGET_sh64 is not set +# TARGET_sparc is not set +# TARGET_v850 is not set +# TARGET_vax is not set +# TARGET_x86_64 is not set +# TARGET_xtensa is not set +# TARGET_c6x is not set + +# +# Target Architecture Features and Options +# +TARGET_ARCH="cris" +FORCE_OPTIONS_FOR_ARCH=y +# CONFIG_CRIS is not set +CONFIG_CRISV32=y +TARGET_SUBARCH="" + +# +# Using ELF file format +# +ARCH_LITTLE_ENDIAN=y + +# +# Using Little Endian +# +ARCH_HAS_MMU=y +ARCH_USE_MMU=y +UCLIBC_HAS_FLOATS=y +UCLIBC_HAS_FPU=y +DO_C99_MATH=y +# DO_XSI_MATH is not set +UCLIBC_HAS_FENV=y +KERNEL_HEADERS="" +HAVE_DOT_CONFIG=y + +# +# General Library Settings +# +# HAVE_NO_PIC is not set +DOPIC=y +# ARCH_HAS_NO_SHARED is not set +# ARCH_HAS_NO_LDSO is not set +HAVE_SHARED=y +# FORCE_SHAREABLE_TEXT_SEGMENTS is not set +LDSO_LDD_SUPPORT=y +LDSO_CACHE_SUPPORT=y +# LDSO_PRELOAD_ENV_SUPPORT is not set +# LDSO_PRELOAD_FILE_SUPPORT is not set +LDSO_BASE_FILENAME="ld.so" +# UCLIBC_STATIC_LDCONFIG is not set +LDSO_RUNPATH=y +LDSO_SEARCH_INTERP_PATH=y +UCLIBC_CTOR_DTOR=y +# LDSO_GNU_HASH_SUPPORT is not set +# HAS_NO_THREADS is not set +LINUXTHREADS_OLD=y +# LINUXTHREADS_NEW is not set +# UCLIBC_HAS_THREADS_NATIVE is not set +UCLIBC_HAS_THREADS=y +PTHREADS_DEBUG_SUPPORT=y +UCLIBC_HAS_SYSLOG=y +UCLIBC_HAS_LFS=y +# MALLOC is not set +# MALLOC_SIMPLE is not set +MALLOC_STANDARD=y +MALLOC_GLIBC_COMPAT=y +UCLIBC_DYNAMIC_ATEXIT=y +COMPAT_ATEXIT=y +UCLIBC_SUSV3_LEGACY=y +# UCLIBC_SUSV3_LEGACY_MACROS is not set +UCLIBC_SUSV4_LEGACY=y +# UCLIBC_STRICT_HEADERS is not set +# UCLIBC_HAS_STUBS is not set +UCLIBC_HAS_SHADOW=y +UCLIBC_HAS_PROGRAM_INVOCATION_NAME=y +UCLIBC_HAS___PROGNAME=y +UCLIBC_HAS_PTY=y +ASSUME_DEVPTS=y +UNIX98PTY_ONLY=y +UCLIBC_HAS_GETPT=y +UCLIBC_HAS_LIBUTIL=y +UCLIBC_HAS_TM_EXTENSIONS=y +UCLIBC_HAS_TZ_CACHING=y +UCLIBC_HAS_TZ_FILE=y +UCLIBC_HAS_TZ_FILE_READ_MANY=y +UCLIBC_TZ_FILE_PATH="/etc/TZ" +UCLIBC_FALLBACK_TO_ETC_LOCALTIME=y + +# +# Advanced Library Settings +# +UCLIBC_PWD_BUFFER_SIZE=256 +UCLIBC_GRP_BUFFER_SIZE=256 + +# +# Support various families of functions +# +# UCLIBC_LINUX_MODULE_24 is not set +UCLIBC_LINUX_SPECIFIC=y +UCLIBC_HAS_GNU_ERROR=y +UCLIBC_BSD_SPECIFIC=y +UCLIBC_HAS_BSD_ERR=y +# UCLIBC_HAS_OBSOLETE_BSD_SIGNAL is not set +# UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL is not set +# UCLIBC_NTP_LEGACY is not set +# UCLIBC_SV4_DEPRECATED is not set +UCLIBC_HAS_REALTIME=y +UCLIBC_HAS_ADVANCED_REALTIME=y +UCLIBC_HAS_EPOLL=y +# UCLIBC_HAS_XATTR is not set +# UCLIBC_HAS_PROFILING is not set +UCLIBC_HAS_CRYPT_IMPL=y +UCLIBC_HAS_CRYPT=y +UCLIBC_HAS_NETWORK_SUPPORT=y +UCLIBC_HAS_SOCKET=y +UCLIBC_HAS_IPV4=y +UCLIBC_HAS_IPV6=y +UCLIBC_HAS_RPC=y +UCLIBC_HAS_FULL_RPC=y +UCLIBC_HAS_REENTRANT_RPC=y +UCLIBC_USE_NETLINK=y +UCLIBC_SUPPORT_AI_ADDRCONFIG=y +UCLIBC_HAS_BSD_RES_CLOSE=y +UCLIBC_HAS_COMPAT_RES_STATE=y +# UCLIBC_HAS_EXTRA_COMPAT_RES_STATE is not set +UCLIBC_HAS_LIBRESOLV_STUB=y +UCLIBC_HAS_LIBNSL_STUB=y + +# +# String and Stdio Support +# +UCLIBC_HAS_STRING_GENERIC_OPT=y +UCLIBC_HAS_STRING_ARCH_OPT=y +UCLIBC_HAS_CTYPE_TABLES=y +UCLIBC_HAS_CTYPE_SIGNED=y +# UCLIBC_HAS_CTYPE_UNSAFE is not set +UCLIBC_HAS_CTYPE_CHECKED=y +# UCLIBC_HAS_CTYPE_ENFORCED is not set +UCLIBC_HAS_WCHAR=y +# UCLIBC_HAS_LOCALE is not set +UCLIBC_HAS_HEXADECIMAL_FLOATS=y +UCLIBC_HAS_GLIBC_CUSTOM_PRINTF=y +UCLIBC_PRINTF_SCANF_POSITIONAL_ARGS=9 +UCLIBC_HAS_SCANF_GLIBC_A_FLAG=y +# UCLIBC_HAS_STDIO_BUFSIZ_NONE is not set +# UCLIBC_HAS_STDIO_BUFSIZ_256 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_512 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_1024 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_2048 is not set +UCLIBC_HAS_STDIO_BUFSIZ_4096=y +# UCLIBC_HAS_STDIO_BUFSIZ_8192 is not set +UCLIBC_HAS_STDIO_BUILTIN_BUFFER_NONE=y +# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_4 is not set +# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_8 is not set +# UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT is not set +UCLIBC_HAS_STDIO_GETC_MACRO=y +UCLIBC_HAS_STDIO_PUTC_MACRO=y +UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION=y +# UCLIBC_HAS_FOPEN_LARGEFILE_MODE is not set +UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE=y +UCLIBC_HAS_GLIBC_CUSTOM_STREAMS=y +UCLIBC_HAS_PRINTF_M_SPEC=y +UCLIBC_HAS_ERRNO_MESSAGES=y +# UCLIBC_HAS_SYS_ERRLIST is not set +UCLIBC_HAS_SIGNUM_MESSAGES=y +# UCLIBC_HAS_SYS_SIGLIST is not set +UCLIBC_HAS_GNU_GETOPT=y +UCLIBC_HAS_GNU_GETSUBOPT=y + +# +# Big and Tall +# +UCLIBC_HAS_REGEX=y +# UCLIBC_HAS_REGEX_OLD is not set +UCLIBC_HAS_FNMATCH=y +# UCLIBC_HAS_FNMATCH_OLD is not set +UCLIBC_HAS_WORDEXP=y +UCLIBC_HAS_NFTW=y +UCLIBC_HAS_FTW=y +# UCLIBC_HAS_FTS is not set +UCLIBC_HAS_GLOB=y +UCLIBC_HAS_GNU_GLOB=y +# UCLIBC_HAS_UTMPX is not set + +# +# Library Installation Options +# +RUNTIME_PREFIX="/" +DEVEL_PREFIX="/usr/" +MULTILIB_DIR="lib" +HARDWIRED_ABSPATH=y + +# +# Security options +# +UCLIBC_HAS_ARC4RANDOM=y +# HAVE_NO_SSP is not set +# UCLIBC_HAS_SSP is not set +UCLIBC_BUILD_RELRO=y +# UCLIBC_BUILD_NOW is not set +UCLIBC_BUILD_NOEXECSTACK=y + +# +# uClibc development/debugging options +# +CROSS_COMPILER_PREFIX="" +UCLIBC_EXTRA_CFLAGS="" +# DODEBUG is not set +# DODEBUG_PT is not set +DOSTRIP=y +# DOASSERTS is not set +# SUPPORT_LD_DEBUG is not set +# SUPPORT_LD_DEBUG_EARLY is not set +# UCLIBC_MALLOC_DEBUGGING is not set +# UCLIBC_HAS_BACKTRACE is not set +WARNINGS="-Wall" +EXTRA_WARNINGS=y +# DOMULTI is not set +# UCLIBC_MJN3_ONLY is not set diff --git a/target/linux/config/Config.in.flash b/target/linux/config/Config.in.flash index 3e2898617..fb4f22221 100644 --- a/target/linux/config/Config.in.flash +++ b/target/linux/config/Config.in.flash @@ -1,5 +1,8 @@ config ADK_KERNEL_MTD boolean + +config ADK_KERNEL_MTD_MTDRAM + boolean config ADK_KERNEL_MTD_NAND boolean diff --git a/target/linux/config/Config.in.systems b/target/linux/config/Config.in.systems index 369727277..5c420eb2b 100644 --- a/target/linux/config/Config.in.systems +++ b/target/linux/config/Config.in.systems @@ -53,3 +53,7 @@ config ADK_KERNEL_CPU_BIG_ENDIAN config ADK_KERNEL_CPU_LITTLE_ENDIAN boolean + +# cris systems +config ADK_KERNEL_ETRAXFS + boolean diff --git a/target/linux/patches/2.6.39/cris-etrax.patch b/target/linux/patches/2.6.39/cris-etrax.patch new file mode 100644 index 000000000..a80d9a8b8 --- /dev/null +++ b/target/linux/patches/2.6.39/cris-etrax.patch @@ -0,0 +1,12 @@ +diff -Nur linux-2.6.39.orig/arch/cris/arch-v32/drivers/i2c.h linux-2.6.39/arch/cris/arch-v32/drivers/i2c.h +--- linux-2.6.39.orig/arch/cris/arch-v32/drivers/i2c.h 2011-05-19 06:06:34.000000000 +0200 ++++ linux-2.6.39/arch/cris/arch-v32/drivers/i2c.h 2011-08-24 19:15:05.000000000 +0200 +@@ -2,7 +2,7 @@ + #include + + /* High level I2C actions */ +-int __init i2c_init(void); ++static int __init i2c_init(void); + int i2c_write(unsigned char theSlave, void *data, size_t nbytes); + int i2c_read(unsigned char theSlave, void *data, size_t nbytes); + int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue); diff --git a/toolchain/uClibc/Makefile b/toolchain/uClibc/Makefile index bd1b6e8a3..d94bd982b 100644 --- a/toolchain/uClibc/Makefile +++ b/toolchain/uClibc/Makefile @@ -21,6 +21,9 @@ endif ifeq ($(ADK_TARGET_ENDIAN),big) UCLIBCCFG=uclibc.config.big endif +ifeq ($(ADK_TARGET_SYSTEM_QEMU_CRIS),y) +UCLIBCCFG=uclibc.config.v32 +endif $(WRKBUILD)/.headers: $(SED) 's,^CROSS=.*,CROSS=$(TARGET_CROSS),g' $(WRKBUILD)/Rules.mak -- cgit v1.2.3 From db16a43186aa78290e40c72c4673295ac7a9da9e Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 30 Aug 2011 07:30:31 +0200 Subject: fix network config for qemu-mips --- target/linux/config/Config.in.netdevice | 11 +++++++++++ target/mips/Makefile | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/target/linux/config/Config.in.netdevice b/target/linux/config/Config.in.netdevice index d9a8cd9dc..23ffd314c 100644 --- a/target/linux/config/Config.in.netdevice +++ b/target/linux/config/Config.in.netdevice @@ -42,6 +42,17 @@ config ADK_KERNEL_MACB default n help +config ADK_KERNEL_PCNET32 + boolean + select ADK_KERNEL_NETDEVICES + select ADK_KERNEL_NET_ETHERNET + select ADK_KERNEL_NET_PCI + select ADK_KERNEL_MII + default y if ADK_TARGET_SYSTEM_QEMU_MIPSEL + default y if ADK_TARGET_SYSTEM_QEMU_MIPS + default n + help + config ADK_KERNEL_NATSEMI boolean select ADK_KERNEL_NETDEVICES diff --git a/target/mips/Makefile b/target/mips/Makefile index 97533275a..648e28c02 100644 --- a/target/mips/Makefile +++ b/target/mips/Makefile @@ -105,7 +105,7 @@ ifneq ($(ADK_HARDWARE_QEMU),) @echo "Use following command to create a QEMU Image:" @echo "sudo ./scripts/create-image.sh -f $(ADK_TARGET_ROOTFS) qemu-${CPU_ARCH}.img $(BIN_DIR)/$(ROOTFSTARBALL)" @echo "Start qemu with following options:" - @echo 'qemu-system-${CPU_ARCH} -nographic -M malta -kernel $(BIN_DIR)/$(TARGET_KERNEL) qemu-${CPU_ARCH}.img' + @echo 'qemu-system-${CPU_ARCH} -nographic -M malta -net user,hostfwd=tcp::2222-:22 -net nic,model=pcnet -kernel $(BIN_DIR)/$(TARGET_KERNEL) qemu-${CPU_ARCH}.img' endif endif ifeq ($(ADK_TARGET_FS),initramfs) @@ -115,7 +115,7 @@ imageinstall: $(BIN_DIR)/$(INITRAMFS) @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' ifneq ($(ADK_HARDWARE_QEMU),) @echo "Start qemu with following command line:" - @echo 'qemu-system-${CPU_ARCH} -nographic -M malta -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' + @echo 'qemu-system-${CPU_ARCH} -nographic -M malta -net user,hostfwd=tcp::2222-:22 -net nic,model=pcnet -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' endif endif ifeq ($(ADK_TARGET_FS),initramfs-piggyback) @@ -124,7 +124,7 @@ imageinstall: ${BUILD_DIR}/${INITRAMFS_PIGGYBACK} createinitramfs @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' ifneq ($(ADK_HARDWARE_QEMU),) @echo "Start qemu with following command line:" - @echo 'qemu-system-${CPU_ARCH} -nographic -M malta -kernel $(BIN_DIR)/$(TARGET_KERNEL)' + @echo 'qemu-system-${CPU_ARCH} -nographic -M malta -net user,hostfwd=tcp::2222-:22 -net nic,model=pcnet -kernel $(BIN_DIR)/$(TARGET_KERNEL)' endif endif ifeq ($(ADK_TARGET_FS),usb) -- cgit v1.2.3 From 6c4dbdaddecb4397c2bda2f74569a968714815ee Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 31 Aug 2011 09:49:16 +0200 Subject: add TCP port configuration for typical Qemu setup --- mk/build.mk | 4 +++- target/config/Config.in.adk | 7 +++++++ tests/adk.exp.in | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mk/build.mk b/mk/build.mk index 854fdb19d..c8fa47387 100644 --- a/mk/build.mk +++ b/mk/build.mk @@ -590,8 +590,10 @@ include $(TOPDIR)/toolchain/gcc/Makefile.inc check: @-rm tests/adk.exp tests/master.exp @sed -e "s#@ADK_TARGET_IP@#$(ADK_TARGET_IP)#" tests/adk.exp.in > \ + tests/adk.exp.in.tmp + @sed -e "s#@ADK_TARGET_PORT@#$(ADK_TARGET_PORT)#" tests/adk.exp.in.tmp > \ tests/adk.exp @sed -e "s#@TOPDIR@#$(TOPDIR)#" tests/master.exp.in > \ tests/master.exp env DEJAGNU=$(TOPDIR)/tests/master.exp \ - $(MAKE) -C $(TOOLCHAIN_BUILD_DIR)/w-$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE)/$(PKG_NAME)-$(PKG_VERSION)-final/gcc check-gcc + $(MAKE) -C $(TOOLCHAIN_BUILD_DIR)/w-$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE)/$(PKG_NAME)-$(PKG_VERSION)-final/gcc check-gcc RUNTESTFLAGS="execute.exp" diff --git a/target/config/Config.in.adk b/target/config/Config.in.adk index 442094b85..5ff27a6a6 100644 --- a/target/config/Config.in.adk +++ b/target/config/Config.in.adk @@ -66,6 +66,13 @@ config ADK_TARGET_IP default "127.0.0.1" help +config ADK_TARGET_PORT + prompt "Set target port for make check" + string + default "2222" if ADK_HARDWARE_QEMU + default "22" + help + choice prompt "Hostsystem (do not change!)" config ADK_HOST_LINUX diff --git a/tests/adk.exp.in b/tests/adk.exp.in index 7b35b775d..c5a7b8948 100644 --- a/tests/adk.exp.in +++ b/tests/adk.exp.in @@ -1,5 +1,5 @@ load_generic_config "unix"; set_board_info hostname @ADK_TARGET_IP@ set_board_info username root -set_board_info rsh_prog /usr/bin/ssh -set_board_info rcp_prog /usr/bin/scp +set_board_info rsh_prog "/usr/bin/ssh -p @ADK_TARGET_PORT@" +set_board_info rcp_prog "/usr/bin/scp -P @ADK_TARGET_PORT@" -- cgit v1.2.3 From b17c7212a430d6abf4ded89493604e3292a2d141 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 31 Aug 2011 09:50:20 +0200 Subject: fix qemu-i686 network/block config --- .gitignore | 1 + target/linux/config/Config.in.block | 6 +++--- target/linux/config/Config.in.netdevice | 2 +- target/x86/Makefile | 6 +++--- tests/adk.exp | 5 ----- tests/master.exp | 4 ---- tests/master.exp.in | 1 + 7 files changed, 9 insertions(+), 16 deletions(-) delete mode 100644 tests/adk.exp delete mode 100644 tests/master.exp diff --git a/.gitignore b/.gitignore index 51956e85e..fba1c551e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ /config/zconf.tab.h /tests/master.exp /tests/adk.exp +/tests/adk.exp.in.tmp /prereq.mk /toolchain_build_*/ /.ADK_HAVE_DOT_CONFIG diff --git a/target/linux/config/Config.in.block b/target/linux/config/Config.in.block index 8f673438d..fdafb06b0 100644 --- a/target/linux/config/Config.in.block +++ b/target/linux/config/Config.in.block @@ -121,11 +121,11 @@ config ADK_KERNEL_ATA_PIIX select ADK_KERNEL_ATA_BMDMA select ADK_KERNEL_BLK_DEV select ADK_KERNEL_BLK_DEV_SD - default y if ADK_TARGET_SYSTEM_QEMU_MIPS64 - default y if ADK_TARGET_SYSTEM_QEMU_MIPS64EL + default y if ADK_TARGET_SYSTEM_QEMU_I686 default y if ADK_TARGET_SYSTEM_QEMU_MIPS default y if ADK_TARGET_SYSTEM_QEMU_MIPSEL - default y if ADK_TARGET_SYSTEM_QEMU_X86 + default y if ADK_TARGET_SYSTEM_QEMU_PPC + default y if ADK_TARGET_SYSTEM_QEMU_SPARC default y if ADK_TARGET_SYSTEM_QEMU_X86_64 default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 diff --git a/target/linux/config/Config.in.netdevice b/target/linux/config/Config.in.netdevice index c4df54f32..713c990f2 100644 --- a/target/linux/config/Config.in.netdevice +++ b/target/linux/config/Config.in.netdevice @@ -135,7 +135,7 @@ config ADK_KERNEL_E1000 select ADK_KERNEL_NETDEV_1000 default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 - default y if ADK_TARGET_SYSTEM_QEMU_X86 + default y if ADK_TARGET_SYSTEM_QEMU_I686 default y if ADK_TARGET_SYSTEM_QEMU_X86_64 default n help diff --git a/target/x86/Makefile b/target/x86/Makefile index 436ca25ce..dc17f0756 100644 --- a/target/x86/Makefile +++ b/target/x86/Makefile @@ -23,7 +23,7 @@ endif ifeq ($(ADK_TARGET_FS),archive) imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) @echo "The RootFS tarball is: $(BIN_DIR)/$(ROOTFSTARBALL)" -ifeq ($(ADK_TARGET_SYSTEM_QEMU_X86),y) +ifeq ($(ADK_HARDWARE_QEMU),y) @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) @echo "Use following command to create a QEMU Image:" @echo "sudo ./scripts/create-image.sh -f ${ADK_TARGET_ROOTFS} qemu-${CPU_ARCH}.img $(BIN_DIR)/$(ROOTFSTARBALL)" @@ -41,7 +41,7 @@ imageinstall: $(BIN_DIR)/$(INITRAMFS) @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' -ifeq ($(ADK_TARGET_SYSTEM_QEMU_X86),y) +ifeq ($(ADK_HARDWARE_QEMU),y) @echo "Start qemu with following command line:" @echo 'qemu -nographic -net user,hostfwd=tcp::2222-:22 -net nic,model=e1000 -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' endif @@ -50,7 +50,7 @@ ifeq ($(ADK_TARGET_FS),initramfs-piggyback) imageinstall: ${BUILD_DIR}/${INITRAMFS_PIGGYBACK} createinitramfs @cp $(KERNEL) $(BIN_DIR)/${TARGET_KERNEL} @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' -ifeq ($(ADK_TARGET_SYSTEM_QEMU_X86),y) +ifeq ($(ADK_HARDWARE_QEMU),y) @echo "Start qemu with following command line:" @echo 'qemu -nographic -net user,hostfwd=tcp::2222-:22 -net nic,model=e1000 -kernel $(BIN_DIR)/$(TARGET_KERNEL)' endif diff --git a/tests/adk.exp b/tests/adk.exp deleted file mode 100644 index 537173234..000000000 --- a/tests/adk.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_generic_config "unix"; -set_board_info hostname 192.168.1.24 -set_board_info username root -set_board_info rsh_prog /usr/bin/ssh -set_board_info rcp_prog /usr/bin/scp diff --git a/tests/master.exp b/tests/master.exp deleted file mode 100644 index 0617230d2..000000000 --- a/tests/master.exp +++ /dev/null @@ -1,4 +0,0 @@ -lappend boards_dir /home/wbx/openadk/tests -lappend boards_dir /usr/share/dejagnu -set myboard adk -set target_list adk diff --git a/tests/master.exp.in b/tests/master.exp.in index 297c0ce5d..72d8ab9e6 100644 --- a/tests/master.exp.in +++ b/tests/master.exp.in @@ -2,3 +2,4 @@ lappend boards_dir @TOPDIR@/tests lappend boards_dir /usr/share/dejagnu set myboard adk set target_list adk +set verbose 1 -- cgit v1.2.3 From 0d3d3eb227d0b0c26e40cbb08a8e57ef80e390c1 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 31 Aug 2011 18:17:07 +0200 Subject: add g++ checks, separate checks for gcc and g++ --- Makefile | 6 ++++++ mk/build.mk | 14 +++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index b143098c4..590c0dac2 100644 --- a/Makefile +++ b/Makefile @@ -155,6 +155,12 @@ bulkallmod: .prereq_done check: .prereq_done @${GMAKE_INV} check +check-gcc: .prereq_done + @${GMAKE_INV} check-gcc + +check-g++: .prereq_done + @${GMAKE_INV} check-g++ + menu: .prereq_done @${GMAKE_INV} menu diff --git a/mk/build.mk b/mk/build.mk index c8fa47387..6f52bb868 100644 --- a/mk/build.mk +++ b/mk/build.mk @@ -587,13 +587,21 @@ dep: $(TOPDIR)/bin/tools/depmaker include $(TOPDIR)/toolchain/gcc/Makefile.inc -check: - @-rm tests/adk.exp tests/master.exp +check-dejagnu: + @-rm tests/adk.exp tests/master.exp >/dev/null 2>&1 @sed -e "s#@ADK_TARGET_IP@#$(ADK_TARGET_IP)#" tests/adk.exp.in > \ tests/adk.exp.in.tmp @sed -e "s#@ADK_TARGET_PORT@#$(ADK_TARGET_PORT)#" tests/adk.exp.in.tmp > \ tests/adk.exp @sed -e "s#@TOPDIR@#$(TOPDIR)#" tests/master.exp.in > \ tests/master.exp + +check-gcc: check-dejagnu + env DEJAGNU=$(TOPDIR)/tests/master.exp \ + $(MAKE) -C $(TOOLCHAIN_BUILD_DIR)/w-$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE)/$(PKG_NAME)-$(PKG_VERSION)-final/gcc check-gcc + +check-g++: check-dejagnu env DEJAGNU=$(TOPDIR)/tests/master.exp \ - $(MAKE) -C $(TOOLCHAIN_BUILD_DIR)/w-$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE)/$(PKG_NAME)-$(PKG_VERSION)-final/gcc check-gcc RUNTESTFLAGS="execute.exp" + $(MAKE) -C $(TOOLCHAIN_BUILD_DIR)/w-$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE)/$(PKG_NAME)-$(PKG_VERSION)-final/gcc check-g++ + +check: check-gcc check-g++ -- cgit v1.2.3 From 27a08f622ebf54da86add4b041097c6ba79e4180 Mon Sep 17 00:00:00 2001 From: Joerg Seitter Date: Wed, 31 Aug 2011 11:14:27 +0200 Subject: added jack package --- package/jack/Makefile | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 package/jack/Makefile diff --git a/package/jack/Makefile b/package/jack/Makefile new file mode 100644 index 000000000..65776fd7f --- /dev/null +++ b/package/jack/Makefile @@ -0,0 +1,45 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(TOPDIR)/rules.mk + +# always use tab spaces as separator, no spaces +PKG_NAME:= jack +PKG_VERSION:= 1.9.7 +PKG_RELEASE:= 1 +PKG_MD5SUM:= 9759670feecbd43eeccf1c0f743ec199 +PKG_DESCR:= JACK Audio Connection Kit +PKG_SECTION:= multimedia +PKG_DEPENDS:= alsa-lib +PKG_BUILDDEP:= python2 alsa-lib +PKG_URL:= http://jackaudio.org +PKG_SITES:= http://www.grame.fr/~letz/ + +DISTFILES:= ${PKG_NAME}-${PKG_VERSION}.tar.bz2 + +include $(TOPDIR)/mk/package.mk + +$(eval $(call PKG_template,JACK,jack,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) + +CONFIG_STYLE:= manual +BUILD_STYLE:= manual +INSTALL_STYLE:= manual + +do-configure: + $(WRKSRC)/waf configure --alsa --prefix=$(WRKINST)/usr + +do-build: + cd $(WRKSRC) && $(WRKSRC)/waf build + +do-install: + cd $(WRKSRC) && $(WRKSRC)/waf install + +jack-install: + $(INSTALL_DIR) $(IDIR_JACK)/usr/bin + $(INSTALL_BIN) $(WRKINST)/usr/bin/jack* \ + $(IDIR_JACK)/usr/bin + $(INSTALL_DIR) $(IDIR_JACK)/usr/lib + $(INSTALL_BIN) $(WRKINST)/usr/lib/lib* \ + $(IDIR_JACK)/usr/lib + +include ${TOPDIR}/mk/pkg-bottom.mk -- cgit v1.2.3 From c98300f10374e5069c473a3a0387e674d939e8e0 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Thu, 1 Sep 2011 12:39:33 +0200 Subject: not for Darwin compiles --- package/jack/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package/jack/Makefile b/package/jack/Makefile index 65776fd7f..1c5c0268e 100644 --- a/package/jack/Makefile +++ b/package/jack/Makefile @@ -3,7 +3,6 @@ include $(TOPDIR)/rules.mk -# always use tab spaces as separator, no spaces PKG_NAME:= jack PKG_VERSION:= 1.9.7 PKG_RELEASE:= 1 @@ -15,6 +14,8 @@ PKG_BUILDDEP:= python2 alsa-lib PKG_URL:= http://jackaudio.org PKG_SITES:= http://www.grame.fr/~letz/ +PKG_HOST_DEPENDS:= !darwin + DISTFILES:= ${PKG_NAME}-${PKG_VERSION}.tar.bz2 include $(TOPDIR)/mk/package.mk -- cgit v1.2.3 From 06ce168a42a0834f2ab1b17a493c6e339906404a Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Fri, 2 Sep 2011 16:07:27 +0200 Subject: add basic support for qemu-system-sh4 --- Config.in | 1 + package/libgcc/Makefile | 2 + target/arch.lst | 1 + target/config/Config.in | 6 + target/config/Config.in.arch.choice | 6 + target/config/Config.in.arch.default | 4 + target/config/Config.in.system.choice | 1 + target/sh/Config.in | 9 + target/sh/Makefile | 36 + target/sh/kernel.config | 1817 ++++++++++++++++++++ target/sh/sys-available/qemu-sh | 10 + target/sh/sys-available/toolchain-sh | 9 + target/sh/target.mk | 5 + target/sh/uclibc.config | 247 +++ .../uClibc-0.9.32-use-arch-pt-initfini_c.patch | 39 + 15 files changed, 2193 insertions(+) create mode 100644 target/sh/Config.in create mode 100644 target/sh/Makefile create mode 100644 target/sh/kernel.config create mode 100644 target/sh/sys-available/qemu-sh create mode 100644 target/sh/sys-available/toolchain-sh create mode 100644 target/sh/target.mk create mode 100644 target/sh/uclibc.config create mode 100644 toolchain/uClibc/patches/uClibc-0.9.32-use-arch-pt-initfini_c.patch diff --git a/Config.in b/Config.in index ebbd05dc3..241f7b850 100644 --- a/Config.in +++ b/Config.in @@ -24,6 +24,7 @@ config ADK_CHOOSE_TARGET_SYSTEM default y if ADK_CHOOSE_TARGET_SYSTEM_PPC64 default y if ADK_CHOOSE_TARGET_SYSTEM_SPARC default y if ADK_CHOOSE_TARGET_SYSTEM_SPARC64 + default y if ADK_CHOOSE_TARGET_SYSTEM_SH default y if ADK_CHOOSE_TARGET_SYSTEM_X86 default y if ADK_CHOOSE_TARGET_SYSTEM_X86_64 default n diff --git a/package/libgcc/Makefile b/package/libgcc/Makefile index 55f9e5b90..353c5cc32 100644 --- a/package/libgcc/Makefile +++ b/package/libgcc/Makefile @@ -11,6 +11,8 @@ PKG_DFLT_LIBGCC:= y if !ADK_TOOLCHAIN_ONLY NO_DISTFILES:= 1 +PKG_ARCH_DEPENDS:= !sh + include ${TOPDIR}/mk/package.mk $(eval $(call PKG_template,LIBGCC,libgcc,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION},${PKG_OPTS})) diff --git a/target/arch.lst b/target/arch.lst index a5c2da7ec..b4eca2828 100644 --- a/target/arch.lst +++ b/target/arch.lst @@ -5,5 +5,6 @@ ppc ppc64 sparc sparc64 +sh x86 x86_64 diff --git a/target/config/Config.in b/target/config/Config.in index 382925436..adc499752 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -241,6 +241,9 @@ config ADK_CPU_CRIS_V10 config ADK_CPU_CRIS_V32 boolean +config ADK_CPU_SH4 + boolean + config ADK_CPU_SPARC_V8 boolean @@ -300,6 +303,7 @@ config ADK_TARGET_CPU_ARCH default "arm" if ADK_LINUX_ARM && ADK_little default "armeb" if ADK_LINUX_ARM && ADK_big default "sparc" if ADK_LINUX_SPARC + default "sh" if ADK_LINUX_SH default "cris" if ADK_CPU_CRIS_V10 default "crisv32" if ADK_CPU_CRIS_V32 default "ppc" if ADK_CPU_PPC @@ -344,6 +348,7 @@ config ADK_TARGET_CMDLINE default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_IBM_X40 default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_INTEL_ATOM default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_QEMU_X86 + default "console=tty0" if ADK_TARGET_SYSTEM_QEMU_SH default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_FOXBOARD_LX @@ -501,6 +506,7 @@ config ADK_TARGET_ROOTFS_NFSROOT select ADK_KERNEL_NFS_COMMON select ADK_KERNEL_IP_PNP select ADK_KERNEL_IP_PNP_DHCP + depends on !ADK_HARDWARE_QEMU help Root filesystem mounted via NFS. (DHCP) diff --git a/target/config/Config.in.arch.choice b/target/config/Config.in.arch.choice index 092a0297d..380f84b5d 100644 --- a/target/config/Config.in.arch.choice +++ b/target/config/Config.in.arch.choice @@ -56,6 +56,12 @@ config ADK_LINUX_SPARC64 help Support for sparc64 systems. +config ADK_LINUX_SH + bool "superh system" + select ADK_sh + help + Support for superh systems. + config ADK_LINUX_X86 bool "x86 system" select ADK_x86 diff --git a/target/config/Config.in.arch.default b/target/config/Config.in.arch.default index cbe8b6ddc..5590b2bbd 100644 --- a/target/config/Config.in.arch.default +++ b/target/config/Config.in.arch.default @@ -35,6 +35,9 @@ config ADK_sparc config ADK_sparc64 bool +config ADK_sh + bool + config ADK_x86_64 bool @@ -54,6 +57,7 @@ config ADK_TARGET_ARCH default "ppc64" if ADK_ppc64 default "sparc" if ADK_sparc default "sparc64" if ADK_sparc64 + default "sh" if ADK_sh default "x86" if ADK_x86 default "x86_64" if ADK_x86_64 default "native" if ADK_native diff --git a/target/config/Config.in.system.choice b/target/config/Config.in.system.choice index 597d8054a..222b28aba 100644 --- a/target/config/Config.in.system.choice +++ b/target/config/Config.in.system.choice @@ -5,5 +5,6 @@ source "target/ppc/Config.in" source "target/ppc64/Config.in" source "target/sparc/Config.in" source "target/sparc64/Config.in" +source "target/sh/Config.in" source "target/x86/Config.in" source "target/x86_64/Config.in" diff --git a/target/sh/Config.in b/target/sh/Config.in new file mode 100644 index 000000000..4dfe7ba09 --- /dev/null +++ b/target/sh/Config.in @@ -0,0 +1,9 @@ +choice +depends on ADK_LINUX_SH && !ADK_CHOOSE_TARGET_ARCH +prompt "Target system" + +config ADK_CHOOSE_TARGET_SYSTEM_SH + boolean "Choose target system" + +source "target/sh/Config.in.systems" +endchoice diff --git a/target/sh/Makefile b/target/sh/Makefile new file mode 100644 index 000000000..63a237839 --- /dev/null +++ b/target/sh/Makefile @@ -0,0 +1,36 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(TOPDIR)/rules.mk +include $(TOPDIR)/mk/kernel.mk +include $(TOPDIR)/mk/modules.mk +include $(TOPDIR)/mk/kernel-build.mk +include $(TOPDIR)/mk/image.mk + +KERNEL:=$(LINUX_DIR)/arch/sh/boot/zImage + +ifeq ($(ADK_TARGET_FS),archive) +imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) + @cp $(KERNEL) $(BIN_DIR)/${TARGET_KERNEL} + @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' + @echo "The RootFS tarball is: $(BIN_DIR)/$(ROOTFSTARBALL)" +endif +ifeq ($(ADK_TARGET_FS),initramfs) +imageinstall: $(BIN_DIR)/$(INITRAMFS) + @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) + @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' + @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_SH),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-sh4 -M r2d -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' +endif +endif +ifeq ($(ADK_TARGET_FS),initramfs-piggyback) +imageinstall: ${BUILD_DIR}/${INITRAMFS_PIGGYBACK} createinitramfs + @cp $(KERNEL) $(BIN_DIR)/${TARGET_KERNEL} + @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_SH),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-sh4 -M r2d -kernel $(BIN_DIR)/$(TARGET_KERNEL)' +endif +endif diff --git a/target/sh/kernel.config b/target/sh/kernel.config new file mode 100644 index 000000000..a1578e62b --- /dev/null +++ b/target/sh/kernel.config @@ -0,0 +1,1817 @@ +# +# Automatically generated make config: don't edit +# Linux/sh 2.6.39 Kernel Configuration +# Fri Sep 2 16:00:15 2011 +# +CONFIG_SUPERH=y +CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set +CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_FIND_BIT_LE=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_IRQ_PER_CPU=y +# CONFIG_GENERIC_GPIO is not set +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_ARCH_SUSPEND_POSSIBLE is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_SYS_SUPPORTS_PCI=y +CONFIG_SYS_SUPPORTS_TMU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +# CONFIG_NO_IOPORT is not set +CONFIG_IO_TRAPPED=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y +CONFIG_HAVE_IRQ_WORK=y +CONFIG_IRQ_WORK=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_FHANDLE is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_HAVE_SPARSE_IRQ=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_SPARSE_IRQ=y + +# +# RCU Subsystem +# +CONFIG_TINY_RCU=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EXPERT=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +# CONFIG_MODULE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# System type +# +CONFIG_CPU_SH4=y +CONFIG_CPU_HAS_PMU=y +# CONFIG_CPU_SUBTYPE_SH7619 is not set +# CONFIG_CPU_SUBTYPE_SH7201 is not set +# CONFIG_CPU_SUBTYPE_SH7203 is not set +# CONFIG_CPU_SUBTYPE_SH7206 is not set +# CONFIG_CPU_SUBTYPE_SH7263 is not set +# CONFIG_CPU_SUBTYPE_MXG is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set +# CONFIG_CPU_SUBTYPE_SH7712 is not set +# CONFIG_CPU_SUBTYPE_SH7720 is not set +# CONFIG_CPU_SUBTYPE_SH7721 is not set +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +CONFIG_CPU_SUBTYPE_SH7751R=y +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set +# CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set +# CONFIG_CPU_SUBTYPE_SH7757 is not set +# CONFIG_CPU_SUBTYPE_SH7763 is not set +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set +# CONFIG_CPU_SUBTYPE_SH7786 is not set +# CONFIG_CPU_SUBTYPE_SHX3 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set +# CONFIG_CPU_SUBTYPE_SH7366 is not set + +# +# Memory management options +# +CONFIG_QUICKLIST=y +CONFIG_MMU=y +CONFIG_PAGE_OFFSET=0x80000000 +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x04000000 +CONFIG_29BIT=y +CONFIG_VSYSCALL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_MAX_ACTIVE_REGIONS=1 +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_STATIC=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=1 +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NEED_PER_CPU_KM=y + +# +# Cache configuration +# +CONFIG_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_SH_FPU=y +# CONFIG_SH_STORE_QUEUES is not set +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_FPU=y + +# +# Board support +# +# CONFIG_SH_SECUREEDGE5410 is not set +CONFIG_SH_RTS7751R2D=y +# CONFIG_SH_LANDISK is not set +# CONFIG_SH_TITAN is not set +# CONFIG_SH_LBOX_RE2 is not set + +# +# RTS7751R2D Board Revision +# +CONFIG_RTS7751R2D_PLUS=y +# CONFIG_RTS7751R2D_1 is not set + +# +# Timer and clock configuration +# +CONFIG_SH_TIMER_TMU=y +CONFIG_SH_PCLK_FREQ=60000000 +CONFIG_SH_CLK_CPG=y +CONFIG_SH_CLK_CPG_LEGACY=y +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# + +# +# Additional SuperH Device Drivers +# +CONFIG_HEARTBEAT=y +# CONFIG_PUSH_SWITCH is not set + +# +# Kernel features +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_SECCOMP is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_GUSA=y +# CONFIG_GUSA_RB is not set +CONFIG_HW_PERF_EVENTS=y + +# +# SuperH / SH-Mobile Driver Options +# + +# +# Interrupt controller options +# +# CONFIG_INTC_MAPPING_DEBUG is not set + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00010000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +CONFIG_ENTRY_OFFSET=0x00001000 +CONFIG_CMDLINE_OVERWRITE=y +# CONFIG_CMDLINE_EXTEND is not set +CONFIG_CMDLINE="console=tty0" + +# +# Bus options +# +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +# CONFIG_PCCARD is not set +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options (EXPERIMENTAL) +# +# CONFIG_HIBERNATION is not set +# CONFIG_PM_RUNTIME is not set +# CONFIG_CPU_IDLE is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +# CONFIG_BATMAN_ADV is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_ARCH_NO_SYSDEV_OPS=y +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_SENSORS_LIS3LV02D is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_PCH_PHUB is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_CB710_CORE is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_SENSORS_LIS3_SPI is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_SCSI_BNX2X_FCOE is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_FCOE is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_AHCI_PLATFORM is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_ACARD_AHCI is not set +# CONFIG_SATA_SIL24 is not set +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_SX4 is not set +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set + +# +# PATA SFF controllers with BMDMA +# +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARASAN_CF is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_ATP867X is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5536 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RDC is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SCH is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set + +# +# PIO-only SFF controllers +# +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +CONFIG_PATA_PLATFORM=y +# CONFIG_PATA_RZ1000 is not set + +# +# Generic fallback / legacy drivers +# +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_LEGACY is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +CONFIG_MII=y +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_AX88796 is not set +# CONFIG_STNIC is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +CONFIG_8139CP=y +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +# CONFIG_ATL2 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_JME is not set +# CONFIG_STMMAC_ETH is not set +# CONFIG_PCH_GBE is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +# CONFIG_ENIC is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_EN is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_BNA is not set +# CONFIG_SFC is not set +# CONFIG_BE2NET is not set +# CONFIG_TR is not set +CONFIG_WLAN=y +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WAN is not set + +# +# CAIF transport drivers +# +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set +# CONFIG_N_GSM is not set +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_CONSOLE is not set +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +# CONFIG_SERIAL_MFD_HSU is not set +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=1 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_PCH_UART is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_RAMOOPS is not set +# CONFIG_I2C is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_SH_MSIOF is not set +# CONFIG_SPI_SH is not set +CONFIG_SPI_SH_SCI=y +# CONFIG_SPI_TOPCLIFF_PCH is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_MFD_SUPPORT=y +# CONFIG_MFD_CORE is not set +CONFIG_MFD_SM501=y +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_MC13XXX is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_LPC_SCH is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_VX855 is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +# CONFIG_DRM is not set +# CONFIG_STUB_POULSBO is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_IMAGEBLIT=m +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=m +# CONFIG_FB_WMT_GE_ROPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +CONFIG_FB_BACKLIGHT=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +CONFIG_FB_SH_MOBILE_LCDC=m +# CONFIG_FB_SH_MOBILE_HDMI is not set +CONFIG_FB_SM501=y +# CONFIG_FB_UDL is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_LTV350QV is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +# CONFIG_LCD_PLATFORM is not set +# CONFIG_LCD_S6E63M0 is not set +# CONFIG_LCD_LD9040 is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +# CONFIG_LOGO_SUPERH_MONO is not set +# CONFIG_LOGO_SUPERH_VGA16 is not set +CONFIG_LOGO_SUPERH_CLUT224=y +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_AC97_POWER_SAVE is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LX6464ES is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +CONFIG_SND_YMFPCI=m +CONFIG_SND_SPI=y +CONFIG_SND_SUPERH=y +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +# CONFIG_SND_SOC is not set +CONFIG_SOUND_PRIME=m +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +# CONFIG_HID_3M_PCT is not set +CONFIG_HID_A4TECH=y +# CONFIG_HID_ACRUX is not set +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +# CONFIG_HID_CANDO is not set +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +# CONFIG_HID_PRODIKEYS is not set +CONFIG_HID_CYPRESS=y +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +CONFIG_HID_EZKEY=y +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +CONFIG_HID_GYRATION=y +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LCPOWER is not set +CONFIG_HID_LOGITECH=y +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set +# CONFIG_LOGIWII_FF is not set +CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MOSART is not set +CONFIG_HID_MONTEREY=y +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_ROCCAT_ARVO is not set +# CONFIG_HID_ROCCAT_KONE is not set +# CONFIG_HID_ROCCAT_KONEPLUS is not set +# CONFIG_HID_ROCCAT_KOVAPLUS is not set +# CONFIG_HID_ROCCAT_PYRA is not set +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +# CONFIG_HID_STANTUM is not set +CONFIG_HID_SUNPLUS=y +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_SH is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_UAS is not set +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_NFC_DEVICES is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +CONFIG_RTC_DRV_R9701=y +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_SH is not set +# CONFIG_RTC_DRV_GENERIC is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set +CONFIG_CLKDEV_LOOKUP=y + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +CONFIG_MINIX_FS=y +CONFIG_MINIX_FS_NATIVE_ENDIAN=y +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_CODEPAGE_932=y +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_HARDLOCKUP_DETECTOR is not set +# CONFIG_SPARSE_RCU_POINTER is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_LKDTM is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_RING_BUFFER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_SH_STANDARD_BIOS is not set +# CONFIG_DWARF_UNWINDER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set + +# +# OCF Configuration +# +# CONFIG_OCF_OCF is not set +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC_T10DIF=y +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y +# CONFIG_AVERAGE is not set diff --git a/target/sh/sys-available/qemu-sh b/target/sh/sys-available/qemu-sh new file mode 100644 index 000000000..70d5a4163 --- /dev/null +++ b/target/sh/sys-available/qemu-sh @@ -0,0 +1,10 @@ +config ADK_TARGET_SYSTEM_QEMU_SH + bool "Qemu Emulator" + select ADK_sh + select ADK_qemu_sh + select ADK_CPU_SH4 + select ADK_HARDWARE_QEMU + select ADK_TARGET_WITH_VGA + help + Support for Qemu Emulator (superh). + diff --git a/target/sh/sys-available/toolchain-sh b/target/sh/sys-available/toolchain-sh new file mode 100644 index 000000000..33fdfa446 --- /dev/null +++ b/target/sh/sys-available/toolchain-sh @@ -0,0 +1,9 @@ +config ADK_TARGET_SYSTEM_TOOLCHAIN_SH + bool "Toolchain only" + select ADK_sh + select ADK_toolchain_sh + select ADK_CPU_SH4 + select ADK_TOOLCHAIN + help + Build a superh toolchain (sh4). + diff --git a/target/sh/target.mk b/target/sh/target.mk new file mode 100644 index 000000000..b5630cced --- /dev/null +++ b/target/sh/target.mk @@ -0,0 +1,5 @@ +include $(TOPDIR)/mk/kernel-ver.mk +ARCH:= sh +CPU_ARCH:= $(ADK_TARGET_CPU_ARCH) +TARGET_OPTIMIZATION:= -Os -pipe +TARGET_CFLAGS_ARCH:= $(ADK_TARGET_CFLAGS) diff --git a/target/sh/uclibc.config b/target/sh/uclibc.config new file mode 100644 index 000000000..b7886124a --- /dev/null +++ b/target/sh/uclibc.config @@ -0,0 +1,247 @@ +# +# Automatically generated make config: don't edit +# Version: 0.9.32 +# Fri Sep 2 08:44:18 2011 +# +# TARGET_alpha is not set +# TARGET_arm is not set +# TARGET_avr32 is not set +# TARGET_bfin is not set +# TARGET_cris is not set +# TARGET_e1 is not set +# TARGET_frv is not set +# TARGET_h8300 is not set +# TARGET_hppa is not set +# TARGET_i386 is not set +# TARGET_i960 is not set +# TARGET_ia64 is not set +# TARGET_m68k is not set +# TARGET_microblaze is not set +# TARGET_mips is not set +# TARGET_nios is not set +# TARGET_nios2 is not set +# TARGET_powerpc is not set +TARGET_sh=y +# TARGET_sh64 is not set +# TARGET_sparc is not set +# TARGET_v850 is not set +# TARGET_vax is not set +# TARGET_x86_64 is not set +# TARGET_xtensa is not set +# TARGET_c6x is not set + +# +# Target Architecture Features and Options +# +TARGET_ARCH="sh" +FORCE_OPTIONS_FOR_ARCH=y +# CONFIG_SH2A is not set +# CONFIG_SH2 is not set +# CONFIG_SH3 is not set +CONFIG_SH4=y +ARCH_HAS_BWD_MEMCPY=y +TARGET_SUBARCH="sh4" + +# +# Using ELF file format +# +ARCH_ANY_ENDIAN=y +ARCH_LITTLE_ENDIAN=y +# ARCH_WANTS_BIG_ENDIAN is not set +ARCH_WANTS_LITTLE_ENDIAN=y +ARCH_HAS_MMU=y +ARCH_USE_MMU=y +UCLIBC_HAS_FLOATS=y +UCLIBC_HAS_FPU=y +DO_C99_MATH=y +# DO_XSI_MATH is not set +UCLIBC_HAS_FENV=y +UCLIBC_HAS_LONG_DOUBLE_MATH=y +KERNEL_HEADERS="" +HAVE_DOT_CONFIG=y + +# +# General Library Settings +# +# HAVE_NO_PIC is not set +DOPIC=y +# ARCH_HAS_NO_SHARED is not set +# ARCH_HAS_NO_LDSO is not set +HAVE_SHARED=y +# FORCE_SHAREABLE_TEXT_SEGMENTS is not set +LDSO_LDD_SUPPORT=y +LDSO_CACHE_SUPPORT=y +# LDSO_PRELOAD_ENV_SUPPORT is not set +# LDSO_PRELOAD_FILE_SUPPORT is not set +LDSO_BASE_FILENAME="ld.so" +# UCLIBC_STATIC_LDCONFIG is not set +LDSO_RUNPATH=y +LDSO_SEARCH_INTERP_PATH=y +UCLIBC_CTOR_DTOR=y +# LDSO_GNU_HASH_SUPPORT is not set +# HAS_NO_THREADS is not set +# LINUXTHREADS_OLD is not set +# LINUXTHREADS_NEW is not set +UCLIBC_HAS_THREADS_NATIVE=y +UCLIBC_HAS_THREADS=y +UCLIBC_HAS_TLS=y +PTHREADS_DEBUG_SUPPORT=y +UCLIBC_HAS_SYSLOG=y +UCLIBC_HAS_LFS=y +# MALLOC is not set +# MALLOC_SIMPLE is not set +MALLOC_STANDARD=y +MALLOC_GLIBC_COMPAT=y +UCLIBC_DYNAMIC_ATEXIT=y +COMPAT_ATEXIT=y +UCLIBC_SUSV3_LEGACY=y +# UCLIBC_SUSV3_LEGACY_MACROS is not set +UCLIBC_SUSV4_LEGACY=y +# UCLIBC_STRICT_HEADERS is not set +# UCLIBC_HAS_STUBS is not set +UCLIBC_HAS_SHADOW=y +UCLIBC_HAS_PROGRAM_INVOCATION_NAME=y +UCLIBC_HAS___PROGNAME=y +UCLIBC_HAS_PTY=y +ASSUME_DEVPTS=y +UNIX98PTY_ONLY=y +UCLIBC_HAS_GETPT=y +UCLIBC_HAS_LIBUTIL=y +UCLIBC_HAS_TM_EXTENSIONS=y +UCLIBC_HAS_TZ_CACHING=y +UCLIBC_HAS_TZ_FILE=y +UCLIBC_HAS_TZ_FILE_READ_MANY=y +UCLIBC_TZ_FILE_PATH="/etc/TZ" +UCLIBC_FALLBACK_TO_ETC_LOCALTIME=y + +# +# Advanced Library Settings +# +UCLIBC_PWD_BUFFER_SIZE=256 +UCLIBC_GRP_BUFFER_SIZE=256 + +# +# Support various families of functions +# +# UCLIBC_LINUX_MODULE_24 is not set +UCLIBC_LINUX_SPECIFIC=y +UCLIBC_HAS_GNU_ERROR=y +UCLIBC_BSD_SPECIFIC=y +UCLIBC_HAS_BSD_ERR=y +# UCLIBC_HAS_OBSOLETE_BSD_SIGNAL is not set +# UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL is not set +# UCLIBC_NTP_LEGACY is not set +# UCLIBC_SV4_DEPRECATED is not set +UCLIBC_HAS_REALTIME=y +UCLIBC_HAS_ADVANCED_REALTIME=y +UCLIBC_HAS_EPOLL=y +# UCLIBC_HAS_XATTR is not set +# UCLIBC_HAS_PROFILING is not set +UCLIBC_HAS_CRYPT_IMPL=y +UCLIBC_HAS_CRYPT=y +UCLIBC_HAS_NETWORK_SUPPORT=y +UCLIBC_HAS_SOCKET=y +UCLIBC_HAS_IPV4=y +UCLIBC_HAS_IPV6=y +UCLIBC_HAS_RPC=y +UCLIBC_HAS_FULL_RPC=y +UCLIBC_HAS_REENTRANT_RPC=y +UCLIBC_USE_NETLINK=y +UCLIBC_SUPPORT_AI_ADDRCONFIG=y +UCLIBC_HAS_BSD_RES_CLOSE=y +UCLIBC_HAS_COMPAT_RES_STATE=y +# UCLIBC_HAS_EXTRA_COMPAT_RES_STATE is not set +UCLIBC_HAS_LIBRESOLV_STUB=y +UCLIBC_HAS_LIBNSL_STUB=y + +# +# String and Stdio Support +# +UCLIBC_HAS_STRING_GENERIC_OPT=y +UCLIBC_HAS_STRING_ARCH_OPT=y +UCLIBC_HAS_CTYPE_TABLES=y +UCLIBC_HAS_CTYPE_SIGNED=y +# UCLIBC_HAS_CTYPE_UNSAFE is not set +UCLIBC_HAS_CTYPE_CHECKED=y +# UCLIBC_HAS_CTYPE_ENFORCED is not set +UCLIBC_HAS_WCHAR=y +# UCLIBC_HAS_LOCALE is not set +UCLIBC_HAS_HEXADECIMAL_FLOATS=y +UCLIBC_HAS_GLIBC_CUSTOM_PRINTF=y +UCLIBC_PRINTF_SCANF_POSITIONAL_ARGS=9 +UCLIBC_HAS_SCANF_GLIBC_A_FLAG=y +# UCLIBC_HAS_STDIO_BUFSIZ_NONE is not set +# UCLIBC_HAS_STDIO_BUFSIZ_256 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_512 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_1024 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_2048 is not set +UCLIBC_HAS_STDIO_BUFSIZ_4096=y +# UCLIBC_HAS_STDIO_BUFSIZ_8192 is not set +UCLIBC_HAS_STDIO_BUILTIN_BUFFER_NONE=y +# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_4 is not set +# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_8 is not set +# UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT is not set +UCLIBC_HAS_STDIO_GETC_MACRO=y +UCLIBC_HAS_STDIO_PUTC_MACRO=y +UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION=y +# UCLIBC_HAS_FOPEN_LARGEFILE_MODE is not set +UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE=y +UCLIBC_HAS_GLIBC_CUSTOM_STREAMS=y +UCLIBC_HAS_PRINTF_M_SPEC=y +UCLIBC_HAS_ERRNO_MESSAGES=y +# UCLIBC_HAS_SYS_ERRLIST is not set +UCLIBC_HAS_SIGNUM_MESSAGES=y +# UCLIBC_HAS_SYS_SIGLIST is not set +UCLIBC_HAS_GNU_GETOPT=y +UCLIBC_HAS_STDIO_FUTEXES=y +UCLIBC_HAS_GNU_GETSUBOPT=y + +# +# Big and Tall +# +UCLIBC_HAS_REGEX=y +# UCLIBC_HAS_REGEX_OLD is not set +UCLIBC_HAS_FNMATCH=y +# UCLIBC_HAS_FNMATCH_OLD is not set +UCLIBC_HAS_WORDEXP=y +UCLIBC_HAS_NFTW=y +UCLIBC_HAS_FTW=y +# UCLIBC_HAS_FTS is not set +UCLIBC_HAS_GLOB=y +UCLIBC_HAS_GNU_GLOB=y +# UCLIBC_HAS_UTMPX is not set + +# +# Library Installation Options +# +RUNTIME_PREFIX="/" +DEVEL_PREFIX="/usr/" +MULTILIB_DIR="lib" +HARDWIRED_ABSPATH=y + +# +# Security options +# +UCLIBC_HAS_ARC4RANDOM=y +# HAVE_NO_SSP is not set +# UCLIBC_HAS_SSP is not set +UCLIBC_BUILD_RELRO=y +# UCLIBC_BUILD_NOW is not set +UCLIBC_BUILD_NOEXECSTACK=y + +# +# uClibc development/debugging options +# +CROSS_COMPILER_PREFIX="" +UCLIBC_EXTRA_CFLAGS="" +# DODEBUG is not set +DOSTRIP=y +# DOASSERTS is not set +# SUPPORT_LD_DEBUG is not set +# SUPPORT_LD_DEBUG_EARLY is not set +# UCLIBC_MALLOC_DEBUGGING is not set +# UCLIBC_HAS_BACKTRACE is not set +WARNINGS="-Wall" +EXTRA_WARNINGS=y +# DOMULTI is not set +# UCLIBC_MJN3_ONLY is not set diff --git a/toolchain/uClibc/patches/uClibc-0.9.32-use-arch-pt-initfini_c.patch b/toolchain/uClibc/patches/uClibc-0.9.32-use-arch-pt-initfini_c.patch new file mode 100644 index 000000000..3eb5b15c2 --- /dev/null +++ b/toolchain/uClibc/patches/uClibc-0.9.32-use-arch-pt-initfini_c.patch @@ -0,0 +1,39 @@ +SH provides a pt-initfini.c, so use that instead of +libpthread/nptl/sysdeps/pthread/pt-initfini.c + +This prevents: + libpthread/nptl/sysdeps/pthread/crti.S: Assembler messages: + libpthread/nptl/sysdeps/pthread/crti.S:25: Error: pcrel too far + libpthread/nptl/sysdeps/pthread/crti.S:26: Error: pcrel too far + libpthread/nptl/sysdeps/pthread/crti.S:28: Error: pcrel too far + libpthread/nptl/sysdeps/pthread/crti.S:53: Error: pcrel too far + libpthread/nptl/sysdeps/pthread/crti.S:56: Error: pcrel too far + make[1]: *** [libpthread/nptl/sysdeps/pthread/crti.o] Error 1 + +There is probably a better way to handle this... but since 9381d622e2411a35a5fd7 +I do not want to even try. + +--- uClibc-0.9.32/libpthread/nptl/sysdeps/pthread/Makefile.in 2011-06-11 00:58:59.539341382 -0400 ++++ uClibc-0.9.32/libpthread/nptl/sysdeps/pthread/Makefile.in 2011-06-11 00:57:52.848172407 -0400 +@@ -76,12 +76,21 @@ + ASFLAGS-crti.S = -g0 + ASFLAGS-crtn.S = -g0 + ++ifneq ($(wildcard $(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/$(TARGET_ARCH)/pt-initfini.c),) ++$(libpthread_pthread_OUT)/pt-initfini.s: $(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/$(TARGET_ARCH)/pt-initfini.c ++ $(compile.c) ++$(libpthread_pthread_OUT)/defs.h: $(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/$(TARGET_ARCH)/pt-initfini.c ++ $(do_sed) -n -e '/@TESTS_BEGIN/,/@TESTS_END/p' $< | \ ++ $(AWK) -f $(top_srcdir)extra/scripts/defs.awk > $@.tmp ++ $(Q)mv $@.tmp $@ ++else + $(libpthread_pthread_OUT)/pt-initfini.s: $(libpthread_pthread_DIR)/pt-initfini.c + $(compile.c) + $(libpthread_pthread_OUT)/defs.h: $(libpthread_pthread_DIR)/pt-initfini.c + $(do_sed) -n -e '/@TESTS_BEGIN/,/@TESTS_END/p' $< | \ + $(AWK) -f $(top_srcdir)extra/scripts/defs.awk > $@.tmp + $(Q)mv $@.tmp $@ ++endif + + $(libpthread_pthread_OUT)/crti.S: $(libpthread_pthread_OUT)/pt-initfini.s $(libpthread_pthread_OUT)/defs.h + $(do_sed) -n -e '/[ ]*\.file/d' \ -- cgit v1.2.3 From 64d1148c48e3cd428da42a5eb9bcda50f08171fb Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Fri, 2 Sep 2011 19:11:35 +0200 Subject: add support for qemu-arm, fix usage of xz compressed initramfs, which is now the default here --- mk/image.mk | 2 +- target/arm/Makefile | 26 +++++++++++++++++++++++--- target/arm/sys-available/qemu-arm | 15 +++++++++++++++ target/config/Config.in | 2 ++ target/linux/Config.in | 1 + target/linux/config/Config.in.serial | 8 ++++++++ target/linux/config/Config.in.spi | 4 ++++ target/linux/config/Config.in.systems | 9 +++++++++ 8 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 target/arm/sys-available/qemu-arm create mode 100644 target/linux/config/Config.in.serial diff --git a/mk/image.mk b/mk/image.mk index 185164c22..78b18e716 100644 --- a/mk/image.mk +++ b/mk/image.mk @@ -95,7 +95,7 @@ ${BIN_DIR}/${INITRAMFS}: ${TARGET_DIR} cd ${TARGET_DIR}; find . | sed -n '/^\.\//s///p' | \ sed "s#\(.*\)#:0:0::::::\1#" | sort | \ ${TOOLS_DIR}/cpio -o -C512 -Hnewc -P | \ - lzma -9 >$@ 2>/dev/null + xz -C crc32 >$@ 2>/dev/null ${BUILD_DIR}/${INITRAMFS_PIGGYBACK}: ${TARGET_DIR} ${SED} 's/.*CONFIG_(BLK_DEV_INITRD|INITRAMFS_SOURCE).*//' \ diff --git a/target/arm/Makefile b/target/arm/Makefile index dbf955a81..8e6ab0df7 100644 --- a/target/arm/Makefile +++ b/target/arm/Makefile @@ -7,6 +7,7 @@ include $(TOPDIR)/mk/modules.mk include $(TOPDIR)/mk/kernel-build.mk include $(TOPDIR)/mk/image.mk +ZKERNEL:=$(LINUX_DIR)/arch/arm/boot/zImage KERNEL:=$(LINUX_DIR)/vmlinux LOADADDR:=0x20008000 @@ -38,25 +39,44 @@ imageinstall: kernel-install $(BIN_DIR)/$(ROOTFSTARBALL) endif ifeq ($(ADK_TARGET_FS),archive) imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) +ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) + @cp $(ZKERNEL) $(BIN_DIR)/$(TARGET_KERNEL) +else @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) +endif @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo "The RootFS tarball is: $(BIN_DIR)/$(ROOTFSTARBALL)" +ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) @echo "Use following command to create a QEMU Image:" @echo "sudo ./scripts/create-image.sh -f $(ADK_TARGET_ROOTFS) qemu-${CPU_ARCH}.img $(BIN_DIR)/$(ROOTFSTARBALL)" @echo "Start qemu with following options:" - @echo 'qemu-system-arm -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -hda qemu-${CPU_ARCH}.img -append "root=/dev/hda1"' + @echo 'qemu-system-arm -M spitz -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -hda qemu-${CPU_ARCH}.img -append "root=/dev/hda1"' +endif endif ifeq ($(ADK_TARGET_FS),initramfs) imageinstall: $(BIN_DIR)/$(INITRAMFS) +ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) + @cp $(ZKERNEL) $(BIN_DIR)/$(TARGET_KERNEL) +else @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) +endif @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' - @echo 'qemu-system-arm -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) + @echo "Start qemu with following command line:" + @echo 'qemu-system-arm -M spitz -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' +endif endif ifeq ($(ADK_TARGET_FS),initramfs-piggyback) imageinstall: ${BUILD_DIR}/${INITRAMFS_PIGGYBACK} createinitramfs +ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) + @cp $(ZKERNEL) $(BIN_DIR)/$(TARGET_KERNEL) +else @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) +endif @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) @echo "Start qemu with following command line:" - @echo 'qemu-system-arm -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' + @echo 'qemu-system-arm -M spitz -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' +endif endif diff --git a/target/arm/sys-available/qemu-arm b/target/arm/sys-available/qemu-arm new file mode 100644 index 000000000..beb1e2ee4 --- /dev/null +++ b/target/arm/sys-available/qemu-arm @@ -0,0 +1,15 @@ +config ADK_TARGET_SYSTEM_QEMU_ARM + bool "Qemu Emulator" + select ADK_arm + select ADK_qemu_arm + select ADK_little + select ADK_EABI + select ADK_KERNEL_ARCH_PXA + select ADK_KERNEL_PXA_SHARPSL + select ADK_KERNEL_MACH_SPITZ + select ADK_KERNEL_SPI_PXA2XX + select ADK_TARGET_NO_FPU + select ADK_HARDWARE_QEMU + help + Support for Qemu Emulator (arm). + Optimized for PXA270 Spitz. diff --git a/target/config/Config.in b/target/config/Config.in index adc499752..58a27cbbd 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -348,6 +348,7 @@ config ADK_TARGET_CMDLINE default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_IBM_X40 default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_INTEL_ATOM default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_QEMU_X86 + default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_QEMU_ARM default "console=tty0" if ADK_TARGET_SYSTEM_QEMU_SH default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 @@ -462,6 +463,7 @@ config ADK_TARGET_ROOTFS_INITRAMFS ADK_LINUX_X86_64 || \ ADK_LINUX_NATIVE select ADK_KERNEL_BLK_DEV_INITRD + select ADK_KERNEL_RD_XZ help create an read-only initramfs system. diff --git a/target/linux/Config.in b/target/linux/Config.in index 7b52a3003..1b78cecb5 100644 --- a/target/linux/Config.in +++ b/target/linux/Config.in @@ -20,6 +20,7 @@ source target/linux/config/Config.in.misc source target/linux/config/Config.in.mips source target/linux/config/Config.in.lib source target/linux/config/Config.in.pm +source target/linux/config/Config.in.serial source target/linux/config/Config.in.spi source target/linux/config/Config.in.kvm source target/linux/config/Config.in.debug diff --git a/target/linux/config/Config.in.serial b/target/linux/config/Config.in.serial new file mode 100644 index 000000000..3451046de --- /dev/null +++ b/target/linux/config/Config.in.serial @@ -0,0 +1,8 @@ +config ADK_KERNEL_SERIAL_PXA + boolean + default y if ADK_TARGET_SYSTEM_QEMU_ARM + +config ADK_KERNEL_SERIAL_PXA_CONSOLE + boolean + default y if ADK_TARGET_SYSTEM_QEMU_ARM + diff --git a/target/linux/config/Config.in.spi b/target/linux/config/Config.in.spi index a141f8231..73db5e86d 100644 --- a/target/linux/config/Config.in.spi +++ b/target/linux/config/Config.in.spi @@ -12,3 +12,7 @@ config ADK_KERNEL_SPI_RB4XX config ADK_KERNEL_SPI_RB4XX_CPLD select ADK_KERNEL_SPI boolean + +config ADK_KERNEL_SPI_PXA2XX + select ADK_KERNEL_SPI + boolean diff --git a/target/linux/config/Config.in.systems b/target/linux/config/Config.in.systems index 5c420eb2b..24baa864e 100644 --- a/target/linux/config/Config.in.systems +++ b/target/linux/config/Config.in.systems @@ -35,6 +35,15 @@ config ADK_KERNEL_LEMOTE_MACH2F boolean # arm systems +config ADK_KERNEL_ARCH_PXA + boolean + +config ADK_KERNEL_PXA_SHARPSL + boolean + +config ADK_KERNEL_MACH_SPITZ + boolean + config ADK_KERNEL_ARCH_AT91 boolean -- cgit v1.2.3 From 52577cbeee1714c28e3bbd887e0d90d3590c858c Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Fri, 2 Sep 2011 19:48:59 +0200 Subject: fix image creation --- scripts/create-image.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/create-image.sh b/scripts/create-image.sh index f3e03eced..2b5b34bc9 100755 --- a/scripts/create-image.sh +++ b/scripts/create-image.sh @@ -79,11 +79,13 @@ printf "Creating filesystem $filesystem\n" printf "Create partition and filesystem\n" $parted -s $1 mklabel msdos -$parted -s $1 mkpart primary ext2 0 98% +$parted -s $1 -- mkpart primary ext2 0 -0 $parted -s $1 set 1 boot on -dd if=$1 of=mbr bs=16384 count=1 2>/dev/null -dd if=$1 skip=16384 of=$1.new 2>/dev/null +offset=$(parted $1 unit b print | tail -2 | head -1 | cut -f 1 --delimit="B" | cut -c 9-) + +dd if=$1 of=mbr bs=$offset count=1 2>/dev/null +dd if=$1 skip=$offset of=$1.new 2>/dev/null if [ "$filesystem" = "ext2" -o "$filesystem" = "ext3" -o "$filesystem" = "ext4" ];then mkfsopts=-F @@ -105,7 +107,7 @@ rm mbr tmp=$(mktemp -d) -mount -o loop,offset=16384 -t $filesystem $1 $tmp +mount -o loop,offset=$offset -t $filesystem $1 $tmp if [ -z $initramfs ];then printf "Extracting install archive\n" -- cgit v1.2.3 From b7bbd7b3cf2d9f774464953fd2c42be9cabe790c Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Fri, 2 Sep 2011 19:49:33 +0200 Subject: fix serial output for qemu-i686 --- target/config/Config.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/config/Config.in b/target/config/Config.in index adc499752..89d207e61 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -347,8 +347,8 @@ config ADK_TARGET_CMDLINE default "console=ttyS0,115200 console=tty0 geodewdt.nowayout=1" if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_IBM_X40 default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_INTEL_ATOM - default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_QEMU_X86 - default "console=tty0" if ADK_TARGET_SYSTEM_QEMU_SH + default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_QEMU_I686 + default "console=tty0" if ADK_TARGET_SYSTEM_QEMU_SH # sh serial is broken default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_FOXBOARD_LX -- cgit v1.2.3 From f3431e3a6f89b384517885e7805c8706b2c6ae5d Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 4 Sep 2011 17:32:47 +0200 Subject: add support for Qemu Versatile with network emulation --- package/base-files/Makefile | 3 +++ target/arm/Makefile | 13 ++++++++++--- target/arm/sys-available/qemu-arm | 5 ----- target/config/Config.in | 21 ++++++++++++++++++++- target/linux/config/Config.in.netdevice | 10 ++++++++++ target/linux/config/Config.in.serial | 11 +++++++++-- target/linux/config/Config.in.systems | 3 +++ 7 files changed, 55 insertions(+), 11 deletions(-) diff --git a/package/base-files/Makefile b/package/base-files/Makefile index 28fb34348..4cc7e970a 100644 --- a/package/base-files/Makefile +++ b/package/base-files/Makefile @@ -64,6 +64,9 @@ endif cat ./files/inittab.serial >> $(IDIR_BASE_FILES)/etc/inittab test -z $(ADK_RUNTIME_CONSOLE_BOTH) || \ cat ./files/inittab.vga >> $(IDIR_BASE_FILES)/etc/inittab +ifeq ($(ADK_TARGET_QEMU_ARM_MODEL_VERSATILE),y) + $(SED) 's#ttyS#ttyAMA#g' $(IDIR_BASE_FILES)/etc/inittab +endif $(SED) 's#@SPEED@#$(ADK_RUNTIME_CONSOLE_SERIAL_SPEED)#' $(IDIR_BASE_FILES)/etc/inittab test -z $(ADK_RUNTIME_HOSTNAME) || \ echo $(ADK_RUNTIME_HOSTNAME) > $(IDIR_BASE_FILES)/etc/hostname; \ diff --git a/target/arm/Makefile b/target/arm/Makefile index 8e6ab0df7..c62a6fb6f 100644 --- a/target/arm/Makefile +++ b/target/arm/Makefile @@ -11,6 +11,13 @@ ZKERNEL:=$(LINUX_DIR)/arch/arm/boot/zImage KERNEL:=$(LINUX_DIR)/vmlinux LOADADDR:=0x20008000 +ifeq ($(ADK_TARGET_QEMU_ARM_MODEL_SPITZ),y) +MACH:=spitz +endif +ifeq ($(ADK_TARGET_QEMU_ARM_MODEL_VERSATILE),y) +MACH:=versatilepb +endif + tools-compile: $(MAKE) -C ../tools/uboot-mkimage @@ -50,7 +57,7 @@ ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) @echo "Use following command to create a QEMU Image:" @echo "sudo ./scripts/create-image.sh -f $(ADK_TARGET_ROOTFS) qemu-${CPU_ARCH}.img $(BIN_DIR)/$(ROOTFSTARBALL)" @echo "Start qemu with following options:" - @echo 'qemu-system-arm -M spitz -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -hda qemu-${CPU_ARCH}.img -append "root=/dev/hda1"' + @echo 'qemu-system-arm -M $(MACH) -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -hda qemu-${CPU_ARCH}.img -append "root=/dev/hda1"' endif endif ifeq ($(ADK_TARGET_FS),initramfs) @@ -64,7 +71,7 @@ endif @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) @echo "Start qemu with following command line:" - @echo 'qemu-system-arm -M spitz -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' + @echo 'qemu-system-arm -M $(MACH) -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' endif endif ifeq ($(ADK_TARGET_FS),initramfs-piggyback) @@ -77,6 +84,6 @@ endif @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) @echo "Start qemu with following command line:" - @echo 'qemu-system-arm -M spitz -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' + @echo 'qemu-system-arm -M $(MACH) -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' endif endif diff --git a/target/arm/sys-available/qemu-arm b/target/arm/sys-available/qemu-arm index beb1e2ee4..1e62f2abb 100644 --- a/target/arm/sys-available/qemu-arm +++ b/target/arm/sys-available/qemu-arm @@ -4,12 +4,7 @@ config ADK_TARGET_SYSTEM_QEMU_ARM select ADK_qemu_arm select ADK_little select ADK_EABI - select ADK_KERNEL_ARCH_PXA - select ADK_KERNEL_PXA_SHARPSL - select ADK_KERNEL_MACH_SPITZ - select ADK_KERNEL_SPI_PXA2XX select ADK_TARGET_NO_FPU select ADK_HARDWARE_QEMU help Support for Qemu Emulator (arm). - Optimized for PXA270 Spitz. diff --git a/target/config/Config.in b/target/config/Config.in index 58a27cbbd..e97ce5443 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -74,6 +74,24 @@ config ADK_TARGET_ABI_N64 endchoice # submodel support +# +choice +prompt "Qemu ARM Emulation" +depends on ADK_TARGET_SYSTEM_QEMU_ARM + +config ADK_TARGET_QEMU_ARM_MODEL_SPITZ + boolean "Xscale PXA270 Spitz PDA" + select ADK_KERNEL_ARCH_PXA + select ADK_KERNEL_PXA_SHARPSL + select ADK_KERNEL_MACH_SPITZ + select ADK_KERNEL_SPI_PXA2XX + +config ADK_TARGET_QEMU_ARM_MODEL_VERSATILE + boolean "ARM Ltd. Versatile" + select ADK_KERNEL_ARCH_VERSATILE + +endchoice + choice prompt "Foxboard LX Model" depends on ADK_TARGET_SYSTEM_FOXBOARD_LX @@ -348,7 +366,8 @@ config ADK_TARGET_CMDLINE default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_IBM_X40 default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_INTEL_ATOM default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_QEMU_X86 - default "console=ttyS0,115200 console=tty0" if ADK_TARGET_SYSTEM_QEMU_ARM + default "console=ttyS0,115200 console=tty0" if ADK_TARGET_QEMU_ARM_MODEL_SPITZ + default "console=ttyAMA0 console=tty0" if ADK_TARGET_QEMU_ARM_MODEL_VERSATILE default "console=tty0" if ADK_TARGET_SYSTEM_QEMU_SH default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D13 default "console=ttyS0,115200" if ADK_TARGET_SYSTEM_PCENGINES_ALIX2D2 diff --git a/target/linux/config/Config.in.netdevice b/target/linux/config/Config.in.netdevice index 2f9b87200..b615156f9 100644 --- a/target/linux/config/Config.in.netdevice +++ b/target/linux/config/Config.in.netdevice @@ -22,6 +22,16 @@ config ADK_KERNEL_NETDEV_1000 config ADK_KERNEL_VIA_RHINE_MMIO boolean +config ADK_KERNEL_SMC91X + boolean + select ADK_KERNEL_NETDEVICES + select ADK_KERNEL_NET_ETHERNET + select ADK_KERNEL_NET_PCI + select ADK_KERNEL_MII + default y if ADK_TARGET_QEMU_ARM_MODEL_VERSATILE + default n + help + config ADK_KERNEL_CPMAC boolean select ADK_KERNEL_NETDEVICES diff --git a/target/linux/config/Config.in.serial b/target/linux/config/Config.in.serial index 3451046de..adc25312d 100644 --- a/target/linux/config/Config.in.serial +++ b/target/linux/config/Config.in.serial @@ -1,8 +1,15 @@ config ADK_KERNEL_SERIAL_PXA boolean - default y if ADK_TARGET_SYSTEM_QEMU_ARM + default y if ADK_TARGET_QEMU_ARM_MODEL_SPITZ config ADK_KERNEL_SERIAL_PXA_CONSOLE boolean - default y if ADK_TARGET_SYSTEM_QEMU_ARM + default y if ADK_TARGET_QEMU_ARM_MODEL_SPITZ +config ADK_KERNEL_SERIAL_AMBA_PL011 + boolean + default y if ADK_TARGET_QEMU_ARM_MODEL_VERSATILE + +config ADK_KERNEL_SERIAL_AMBA_PL011_CONSOLE + boolean + default y if ADK_TARGET_QEMU_ARM_MODEL_VERSATILE diff --git a/target/linux/config/Config.in.systems b/target/linux/config/Config.in.systems index 24baa864e..3e64caddc 100644 --- a/target/linux/config/Config.in.systems +++ b/target/linux/config/Config.in.systems @@ -35,6 +35,9 @@ config ADK_KERNEL_LEMOTE_MACH2F boolean # arm systems +config ADK_KERNEL_ARCH_VERSATILE + boolean + config ADK_KERNEL_ARCH_PXA boolean -- cgit v1.2.3 From d12998a35c19652dda0743dd9fc19eafad7250d8 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 4 Sep 2011 17:43:54 +0200 Subject: add help for host-only networking --- target/arm/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/target/arm/Makefile b/target/arm/Makefile index c62a6fb6f..a903166f9 100644 --- a/target/arm/Makefile +++ b/target/arm/Makefile @@ -16,6 +16,7 @@ MACH:=spitz endif ifeq ($(ADK_TARGET_QEMU_ARM_MODEL_VERSATILE),y) MACH:=versatilepb +NET:=-net user,hostfwd=tcp::2222-:22 -net nic,model=smc91c111 endif tools-compile: @@ -57,7 +58,7 @@ ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) @echo "Use following command to create a QEMU Image:" @echo "sudo ./scripts/create-image.sh -f $(ADK_TARGET_ROOTFS) qemu-${CPU_ARCH}.img $(BIN_DIR)/$(ROOTFSTARBALL)" @echo "Start qemu with following options:" - @echo 'qemu-system-arm -M $(MACH) -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -hda qemu-${CPU_ARCH}.img -append "root=/dev/hda1"' + @echo 'qemu-system-arm -M $(MACH) -nographic $(NET) -kernel $(BIN_DIR)/$(TARGET_KERNEL) -hda qemu-${CPU_ARCH}.img -append "root=/dev/hda1"' endif endif ifeq ($(ADK_TARGET_FS),initramfs) @@ -71,7 +72,7 @@ endif @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) @echo "Start qemu with following command line:" - @echo 'qemu-system-arm -M $(MACH) -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' + @echo 'qemu-system-arm -M $(MACH) -nographic $(NET) -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' endif endif ifeq ($(ADK_TARGET_FS),initramfs-piggyback) @@ -84,6 +85,6 @@ endif @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) @echo "Start qemu with following command line:" - @echo 'qemu-system-arm -M $(MACH) -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' + @echo 'qemu-system-arm -M $(MACH) -nographic $(NET) -kernel $(BIN_DIR)/$(TARGET_KERNEL)' endif endif -- cgit v1.2.3 From 33f5911f08c585039888d7372481352e2aa9811e Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 4 Sep 2011 19:00:28 +0200 Subject: enable disk support for qemu arm versatile --- target/arm/Makefile | 2 +- target/config/Config.in | 5 +++++ target/linux/config/Config.in.block | 3 +++ target/linux/config/Config.in.kernel | 3 +++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/target/arm/Makefile b/target/arm/Makefile index a903166f9..50ea0b85a 100644 --- a/target/arm/Makefile +++ b/target/arm/Makefile @@ -58,7 +58,7 @@ ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) @echo "Use following command to create a QEMU Image:" @echo "sudo ./scripts/create-image.sh -f $(ADK_TARGET_ROOTFS) qemu-${CPU_ARCH}.img $(BIN_DIR)/$(ROOTFSTARBALL)" @echo "Start qemu with following options:" - @echo 'qemu-system-arm -M $(MACH) -nographic $(NET) -kernel $(BIN_DIR)/$(TARGET_KERNEL) -hda qemu-${CPU_ARCH}.img -append "root=/dev/hda1"' + @echo 'qemu-system-arm -M $(MACH) -nographic $(NET) -kernel $(BIN_DIR)/$(TARGET_KERNEL) -hda qemu-${CPU_ARCH}.img' endif endif ifeq ($(ADK_TARGET_FS),initramfs) diff --git a/target/config/Config.in b/target/config/Config.in index 787b347ea..a6719eb52 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -89,6 +89,11 @@ config ADK_TARGET_QEMU_ARM_MODEL_SPITZ config ADK_TARGET_QEMU_ARM_MODEL_VERSATILE boolean "ARM Ltd. Versatile" select ADK_KERNEL_ARCH_VERSATILE + select ADK_KERNEL_PCI + select ADK_KERNEL_BLOCK + select ADK_KERNEL_SCSI + select ADK_KERNEL_BLK_DEV_SD + select ADK_KERNEL_SCSI_SYM53C8XX_2 endchoice diff --git a/target/linux/config/Config.in.block b/target/linux/config/Config.in.block index fdafb06b0..fe4c0a9c8 100644 --- a/target/linux/config/Config.in.block +++ b/target/linux/config/Config.in.block @@ -62,6 +62,9 @@ config ADK_KERNEL_MMC config ADK_KERNEL_MMC_BLOCK boolean +config ADK_KERNEL_SCSI_SYM53C8XX_2 + boolean + config ADK_KERNEL_MMC_AT91 boolean select ADK_KERNEL_BLOCK diff --git a/target/linux/config/Config.in.kernel b/target/linux/config/Config.in.kernel index 696f7afc9..1791a624a 100644 --- a/target/linux/config/Config.in.kernel +++ b/target/linux/config/Config.in.kernel @@ -85,3 +85,6 @@ config ADK_KERNEL_NFS_COMMON config ADK_KERNEL_SUNRPC boolean + +config ADK_KERNEL_PCI + boolean -- cgit v1.2.3 From b5b6c80366e4d2604278f7359cde759059fe2a8f Mon Sep 17 00:00:00 2001 From: Tobias Breckle Date: Mon, 5 Sep 2011 00:21:37 +0200 Subject: added boost c++ library package --- package/boost/Makefile | 163 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 package/boost/Makefile diff --git a/package/boost/Makefile b/package/boost/Makefile new file mode 100644 index 000000000..c5e15cb31 --- /dev/null +++ b/package/boost/Makefile @@ -0,0 +1,163 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include ${TOPDIR}/rules.mk + +PKG_NAME:= boost +PKG_VERSION:= 1_47_0 +PKG_RELEASE:= 1 +PKG_MD5SUM:= ff180a5276bec773a7625cac7e2288e8 +PKG_DESCR:= boost C++ library +PKG_SECTION:= libs +PKG_URL:= http://www.boost.org/ +PKG_SITES:= ${MASTER_SITE_SOURCEFORGE:=boost/} +DISTFILES:= boost_1_47_0.tar.gz +WRKDIST= ${WRKDIR}/${PKG_NAME}_${PKG_VERSION} + +PKG_SUBPKGS:= BOOST BOOST_DEV +PKG_CHOICES_BOOST:= STATIC SHARED BOTH +PKGCD_STATIC:= install static libs +PKGCD_SHARED:= install shared libs +PKGCD_BOTH:= install static and shared libs +PKGSD_BOOST_DEV:= boost header files +PKGSC_BOOST_DEV:= devel + +PKG_FLAVOURS_BOOST:= date_time graph graph_parallel iostreams math program_options python regex serialization signals system test thread wave + +PKGFD_date_time:= with date-time +PKGFD_python:= with Python +PKGFB_python:= python +PKGFS_python:= python +PKGFD_iostreams:= with iostreams +PKGFD_graph:= with graph +PKGFD_graph_parallel:= with graph_parallel +PKGFD_math:= with math +PKGFD_program_options:= with program_options +PKGFD_regex:= with regex +PKGFD_serialization:= with serialization +PKGFD_signals:= with signals +PKGFD_system:= with system +PKGFD_test:= with test +PKGFD_thread:= with thread +PKGFD_wave:= with wave + +include ${TOPDIR}/mk/package.mk + +$(eval $(call PKG_template,BOOST,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) + +CONFIG_STYLE:= manual +BUILD_STYLE:= manual +INSTALL_STYLE:= manual + +CONFIGURE_ARGS += \ + --target=$(GNU_TARGET_NAME) \ + --host=$(GNU_TARGET_NAME) \ + --build=$(GNU_HOST_NAME) \ + --prefix=${WRKINST}/usr \ + +ifneq (${ADK_PACKAGE_BOOST_IOSTREAMS},) + CONFIGURE_ARGS += -sNO_BZIP2=1 -sZLIB_INCLUDE=${STAGING_DIR}/usr/include -sZLIB_LIBPATH=${STAGING_DIR}/usr/lib +else + CONFIGURE_ARGS += --without-iostreams +endif +ifeq (${ADK_PACKAGE_BOOST_DATE_TIME},) + CONFIGURE_ARGS+=--without-date_time +endif +ifeq (${ADK_PACKAGE_BOOST_PYTHON},) + CONFIGURE_ARGS+=--without-python +endif +ifeq (${ADK_PACKAGE_BOOST_GRAPH},) + CONFIGURE_ARGS+=--without-graph +endif +ifeq (${ADK_PACKAGE_BOOST_math},) + CONFIGURE_ARGS+=--without-math +endif +ifeq (${ADK_PACKAGE_BOOST_PROGRAM_OPTIONS},) + CONFIGURE_ARGS+=--without-program_options +endif +ifeq (${ADK_PACKAGE_BOOST_REGEX},) + CONFIGURE_ARGS+=--without-regex +endif +ifeq (${ADK_PACKAGE_BOOST_SERIALIZATION},) + CONFIGURE_ARGS+=--without-serialization +endif +ifeq (${ADK_PACKAGE_BOOST_SIGNALS},) + CONFIGURE_ARGS+=--without-signals +endif +ifeq (${ADK_PACKAGE_BOOST_SYSTEM},) + CONFIGURE_ARGS+=--without-system +endif +ifeq (${ADK_PACKAGE_BOOST_TEST},) + CONFIGURE_ARGS+=--without-test +endif +ifeq (${ADK_PACKAGE_BOOST_THREAD},) + CONFIGURE_ARGS+=--without-thread +endif +ifeq (${ADK_PACKAGE_BOOST_WAVE},) + CONFIGURE_ARGS+=--without-wave +endif + +# some variables for build +GPP_PATH:= ${STAGING_HOST_DIR}/bin/${GNU_TARGET_NAME}-g++ +GPP_VERSION:= "`${GPP_PATH} -v 2>&1 | tail -1 | awk '{print $$3}'`" +BJAM_PATH:= "`find ${WRKBUILD} -type f -name "bjam"`" +PYTHON_PATH:= ${STAGING_TARGET_DIR}/usr/bin/python +PYTHON_INCLUDE:= "`find ${STAGING_TARGET_DIR}/usr/include/ -maxdepth 1 -type d -name "python*" | head -1`" +PYTHON_LIB:= "`find ${STAGING_TARGET_DIR}/usr/lib/ -maxdepth 1 -type d -name "python*" | head -1`" +USER_JAM:= ${WRKBUILD}/tools/build/v2/user-config.jam + +pre-build: + @echo "build bjam..." + cd $(WRKBUILD)/tools/build/v2/engine; ./build.sh gcc + +do-build: + @echo "build boost library..." +# remove exisiting using gcc line from user.jam +ifeq (`grep "^using gcc" ${USER_JAM} | wc -l`, 0) + ${SED} "/^using gcc/d" ${USER_JAM} +endif +# add using gcc line with determined options to user.jam + echo "using gcc : ${GPP_VERSION} : ${GPP_PATH} ;" >> ${USER_JAM}; + +# remove exisiting using python line from user.jam +ifeq (`grep "^using python" ${USER_JAM} | wc -l`, 0) + ${SED} "/^using python/d" ${USER_JAM} +endif +ifneq (${ADK_PACKAGE_BOOST_PYTHON},) +# add using python line with determined options to user.jam + echo "using python : ${PYTHON_VERSION} : ${PYTHON_PATH} : ${PYTHON_INCLUDE} : ${PYTHON_LIB} ;" >> ${USER_JAM}; +endif + +# run bjam to build boost + ( cd ${WRKBUILD}; \ + ${BJAM_PATH} \ + -sBUILD=release \ + --toolset=gcc-${GPP_VERSION} \ + --build-type=minimal \ + --layout=versioned \ + --disable-long-double \ + --without-mpi \ + ${CONFIGURE_ARGS} \ + install \ + ) + +do-install: +ifneq (${ADK_PACKAGE_BOOST_SHARED},) + ${INSTALL_DIR} ${IDIR_BOOST}/usr/include + ${CP} ${WRKINST}/usr/include/* ${IDIR_BOOST}/usr/include +endif +ifneq (${ADK_PACKAGE_BOOST_SHARED},) + ${INSTALL_DIR} ${IDIR_BOOST}/usr/lib + ${CP} ${WRKINST}/usr/lib/*.so* ${IDIR_BOOST}/usr/lib +endif +ifneq (${ADK_PACKAGE_BOOST_STATIC},) + ${INSTALL_DIR} ${IDIR_BOOST}/usr/lib + ${CP} ${WRKINST}/usr/lib/*.a ${IDIR_BOOST}/usr/lib +endif +ifneq (${ADK_PACKAGE_BOOST_BOTH},) + ${INSTALL_DIR} ${IDIR_BOOST}/usr/lib + ${CP} ${WRKINST}/usr/lib/*.a ${IDIR_BOOST}/usr/lib + ${CP} ${WRKINST}/usr/lib/*.so* ${IDIR_BOOST}/usr/lib +endif + +include ${TOPDIR}/mk/pkg-bottom.mk -- cgit v1.2.3 From 92f89eb60d3a448a1a71243b7f0c8f5b8b2322cd Mon Sep 17 00:00:00 2001 From: Tobias Breckle Date: Mon, 5 Sep 2011 00:22:16 +0200 Subject: polished boost --- package/boost/Makefile | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/package/boost/Makefile b/package/boost/Makefile index c5e15cb31..65868dd9f 100644 --- a/package/boost/Makefile +++ b/package/boost/Makefile @@ -15,12 +15,13 @@ DISTFILES:= boost_1_47_0.tar.gz WRKDIST= ${WRKDIR}/${PKG_NAME}_${PKG_VERSION} PKG_SUBPKGS:= BOOST BOOST_DEV +PKGSD_BOOST_DEV:= boost header files +PKGSC_BOOST_DEV:= devel + PKG_CHOICES_BOOST:= STATIC SHARED BOTH PKGCD_STATIC:= install static libs PKGCD_SHARED:= install shared libs PKGCD_BOTH:= install static and shared libs -PKGSD_BOOST_DEV:= boost header files -PKGSC_BOOST_DEV:= devel PKG_FLAVOURS_BOOST:= date_time graph graph_parallel iostreams math program_options python regex serialization signals system test thread wave @@ -44,6 +45,7 @@ PKGFD_wave:= with wave include ${TOPDIR}/mk/package.mk $(eval $(call PKG_template,BOOST,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) +$(eval $(call PKG_template,BOOST_DEV,boost-dev,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKGSD_BOOST_DEV},${PKGSC_BOOST_DEV})) CONFIG_STYLE:= manual BUILD_STYLE:= manual @@ -141,23 +143,24 @@ endif install \ ) -do-install: -ifneq (${ADK_PACKAGE_BOOST_SHARED},) - ${INSTALL_DIR} ${IDIR_BOOST}/usr/include - ${CP} ${WRKINST}/usr/include/* ${IDIR_BOOST}/usr/include -endif -ifneq (${ADK_PACKAGE_BOOST_SHARED},) + +boost-install: ${INSTALL_DIR} ${IDIR_BOOST}/usr/lib +ifneq (${ADK_PACKAGE_BOOST_SHARED},) ${CP} ${WRKINST}/usr/lib/*.so* ${IDIR_BOOST}/usr/lib endif ifneq (${ADK_PACKAGE_BOOST_STATIC},) - ${INSTALL_DIR} ${IDIR_BOOST}/usr/lib ${CP} ${WRKINST}/usr/lib/*.a ${IDIR_BOOST}/usr/lib endif ifneq (${ADK_PACKAGE_BOOST_BOTH},) - ${INSTALL_DIR} ${IDIR_BOOST}/usr/lib ${CP} ${WRKINST}/usr/lib/*.a ${IDIR_BOOST}/usr/lib ${CP} ${WRKINST}/usr/lib/*.so* ${IDIR_BOOST}/usr/lib endif + +boost-dev-install: + ${INSTALL_DIR} ${IDIR_BOOST_DEV}/usr/include + ${CP} ${WRKINST}/usr/include/* ${IDIR_BOOST_DEV}/usr/include + + include ${TOPDIR}/mk/pkg-bottom.mk -- cgit v1.2.3 From 40c2b2f6a83e9cca14567e855fc75a8d1ef78f28 Mon Sep 17 00:00:00 2001 From: Tobias Breckle Date: Mon, 5 Sep 2011 00:22:34 +0200 Subject: changed behavior of user.jam line removing --- package/boost/Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/package/boost/Makefile b/package/boost/Makefile index 65868dd9f..45c18e08e 100644 --- a/package/boost/Makefile +++ b/package/boost/Makefile @@ -115,16 +115,12 @@ pre-build: do-build: @echo "build boost library..." # remove exisiting using gcc line from user.jam -ifeq (`grep "^using gcc" ${USER_JAM} | wc -l`, 0) ${SED} "/^using gcc/d" ${USER_JAM} -endif # add using gcc line with determined options to user.jam echo "using gcc : ${GPP_VERSION} : ${GPP_PATH} ;" >> ${USER_JAM}; # remove exisiting using python line from user.jam -ifeq (`grep "^using python" ${USER_JAM} | wc -l`, 0) ${SED} "/^using python/d" ${USER_JAM} -endif ifneq (${ADK_PACKAGE_BOOST_PYTHON},) # add using python line with determined options to user.jam echo "using python : ${PYTHON_VERSION} : ${PYTHON_PATH} : ${PYTHON_INCLUDE} : ${PYTHON_LIB} ;" >> ${USER_JAM}; -- cgit v1.2.3 From 0bdb6697263f1bad1471fec73aac621e60618936 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 5 Sep 2011 11:49:52 +0200 Subject: rename internal library net->libnet to avoid clash with real libnet --- package/openjdk/Makefile | 2 +- package/openjdk/patches/rename-libnet.patch | 127 ++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 package/openjdk/patches/rename-libnet.patch diff --git a/package/openjdk/Makefile b/package/openjdk/Makefile index 4bb68bb88..e2bff393d 100644 --- a/package/openjdk/Makefile +++ b/package/openjdk/Makefile @@ -26,7 +26,7 @@ PKG_SITES:= http://download.java.net/openjdk/jdk6/promoted/b22/ \ PKG_HOST_DEPENDS:= !darwin !cygwin !openbsd !netbsd !freebsd PKG_ARCH_DEPENDS:= arm mips x86 x86_64 -PKG_SYSTEM_DEPENDS:= !lemote-yeelong !linksys-ag241 !fon-fon2100 +PKG_SYSTEM_DEPENDS:= !lemote-yeelong !linksys-ag241 !fon-fon2100 !broadcom-bcm47xx # autotools infrastructure for OpenJDK ICEDTEA_NAME:= icedtea6 diff --git a/package/openjdk/patches/rename-libnet.patch b/package/openjdk/patches/rename-libnet.patch new file mode 100644 index 000000000..671c80dcc --- /dev/null +++ b/package/openjdk/patches/rename-libnet.patch @@ -0,0 +1,127 @@ +https://evolvis.org/scm/viewvc.php/jalimo/trunk/oe-overlay/packages/openjdk/openjdk-6-6b18-1.8/icedtea-libnet-renaming.patch?revision=864&view=markup&pathrev=867 +--- w-openjdk-6.orig/openjdk-6/jdk/make/java/net/Makefile 2011-02-28 17:06:10.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/make/java/net/Makefile 2011-09-02 16:20:55.597991415 +0200 +@@ -25,7 +25,7 @@ + + BUILDDIR = ../.. + PACKAGE = java.net +-LIBRARY = net ++LIBRARY = javanet + PRODUCT = sun + include $(BUILDDIR)/common/Defs.gmk + +--- w-openjdk-6.orig/openjdk-6/jdk/make/java/nio/Makefile 2011-02-28 17:06:11.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/make/java/nio/Makefile 2011-09-02 16:21:37.817990454 +0200 +@@ -135,11 +135,11 @@ + endif + ifeq ($(PLATFORM), linux) + COMPILER_WARNINGS_FATAL=true +-OTHER_LDLIBS += -L$(LIBDIR)/$(LIBARCH) -ljava -lnet -lpthread -ldl ++OTHER_LDLIBS += -L$(LIBDIR)/$(LIBARCH) -ljava -ljavanet -lpthread -ldl + endif + ifeq ($(PLATFORM), solaris) + OTHER_LDLIBS += $(JVMLIB) $(LIBSOCKET) -lposix4 -ldl \ +- -L$(LIBDIR)/$(LIBARCH) -ljava -lnet ++ -L$(LIBDIR)/$(LIBARCH) -ljava -ljavanet + endif # PLATFORM + + # +--- w-openjdk-6.orig/openjdk-6/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java 2011-02-28 17:06:22.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java 2011-09-02 16:22:26.507995127 +0200 +@@ -59,7 +59,7 @@ + */ + static { + java.security.AccessController.doPrivileged( +- new sun.security.action.LoadLibraryAction("net")); ++ new sun.security.action.LoadLibraryAction("javanet")); + } + + /** +--- w-openjdk-6.orig/openjdk-6/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java 2011-02-28 17:06:22.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java 2011-09-02 16:22:58.041740544 +0200 +@@ -79,7 +79,7 @@ + */ + static { + java.security.AccessController.doPrivileged( +- new sun.security.action.LoadLibraryAction("net")); ++ new sun.security.action.LoadLibraryAction("javanet")); + } + + /** +--- w-openjdk-6.orig/openjdk-6/jdk/src/share/classes/java/net/DatagramPacket.java 2011-02-28 17:06:22.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/src/share/classes/java/net/DatagramPacket.java 2011-09-02 16:23:20.197991292 +0200 +@@ -47,7 +47,7 @@ + */ + static { + java.security.AccessController.doPrivileged( +- new sun.security.action.LoadLibraryAction("net")); ++ new sun.security.action.LoadLibraryAction("javanet")); + init(); + } + +--- w-openjdk-6.orig/openjdk-6/jdk/src/share/classes/java/net/InetAddress.java 2011-02-28 17:06:22.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/src/share/classes/java/net/InetAddress.java 2011-09-02 16:23:57.670490341 +0200 +@@ -231,7 +231,7 @@ + static { + preferIPv6Address = java.security.AccessController.doPrivileged( + new GetBooleanAction("java.net.preferIPv6Addresses")).booleanValue(); +- AccessController.doPrivileged(new LoadLibraryAction("net")); ++ AccessController.doPrivileged(new LoadLibraryAction("javanet")); + init(); + } + +--- w-openjdk-6.orig/openjdk-6/jdk/src/share/classes/java/net/NetworkInterface.java 2011-02-28 17:06:22.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/src/share/classes/java/net/NetworkInterface.java 2011-09-02 16:24:13.879239438 +0200 +@@ -52,7 +52,7 @@ + private boolean virtual = false; + + static { +- AccessController.doPrivileged(new LoadLibraryAction("net")); ++ AccessController.doPrivileged(new LoadLibraryAction("javanet")); + init(); + } + +--- w-openjdk-6.orig/openjdk-6/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java 2011-02-28 17:06:34.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java 2011-09-02 16:24:50.877990409 +0200 +@@ -89,7 +89,7 @@ + }}); + if (b != null && b.booleanValue()) { + java.security.AccessController.doPrivileged( +- new sun.security.action.LoadLibraryAction("net")); ++ new sun.security.action.LoadLibraryAction("javanet")); + hasSystemProxies = init(); + } + } +--- w-openjdk-6.orig/openjdk-6/jdk/src/share/classes/sun/nio/ch/Util.java 2011-02-28 17:06:35.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/src/share/classes/sun/nio/ch/Util.java 2011-09-02 16:25:45.749240462 +0200 +@@ -354,7 +354,7 @@ + return; + loaded = true; + java.security.AccessController +- .doPrivileged(new sun.security.action.LoadLibraryAction("net")); ++ .doPrivileged(new sun.security.action.LoadLibraryAction("javanet")); + java.security.AccessController + .doPrivileged(new sun.security.action.LoadLibraryAction("nio")); + // IOUtil must be initialized; Its native methods are called from +--- w-openjdk-6.orig/openjdk-6/jdk/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java 2011-02-28 17:06:48.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java 2011-09-02 16:26:36.017990742 +0200 +@@ -244,7 +244,7 @@ + + static { + java.security.AccessController.doPrivileged( +- new sun.security.action.LoadLibraryAction("net")); ++ new sun.security.action.LoadLibraryAction("javanet")); + } + + } +--- w-openjdk-6.orig/openjdk-6/jdk/src/windows/classes/sun/net/dns/ResolverConfigurationImpl.java 2011-02-28 17:06:51.000000000 +0100 ++++ w-openjdk-6/openjdk-6/jdk/src/windows/classes/sun/net/dns/ResolverConfigurationImpl.java 2011-09-02 16:27:07.069240501 +0200 +@@ -160,7 +160,7 @@ + + static { + java.security.AccessController.doPrivileged( +- new sun.security.action.LoadLibraryAction("net")); ++ new sun.security.action.LoadLibraryAction("javanet")); + init0(); + + // start the address listener thread -- cgit v1.2.3 From e61aad237ecb819635bb7550dbbf66f2b8817b50 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 5 Sep 2011 11:50:10 +0200 Subject: more make bulkallmod patches --- mk/build.mk | 8 ++--- mk/vars.mk | 6 ++++ package/cluster-glue/Makefile | 1 + package/cutter/patches/patch-cutter_c | 17 +++++++-- .../ipsec-tools/patches/patch-src_racoon_isakmp_c | 21 +++++++++++ package/libhugetlbfs/Makefile | 2 +- package/llvm/Makefile | 1 + package/pacemaker/Makefile | 1 + package/resource-agents/Makefile | 1 + target/arm/Makefile | 7 ++++ target/linux/patches/2.6.39/cris.patch | 42 +++++++++++----------- 11 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 package/ipsec-tools/patches/patch-src_racoon_isakmp_c diff --git a/mk/build.mk b/mk/build.mk index 854fdb19d..5eecb0a6d 100644 --- a/mk/build.mk +++ b/mk/build.mk @@ -513,7 +513,7 @@ bulktoolchain: bulk: for libc in uclibc eglibc glibc;do \ while read arch; do \ - systems=$$(./scripts/getsystems $$arch|grep -v toolchain); \ + systems=$$(./scripts/getsystems $$arch|grep -v toolchain|grep -v qemu); \ for system in $$systems;do \ mkdir -p $(TOPDIR)/bin/$${system}_$${arch}_$$libc; \ ( \ @@ -531,7 +531,7 @@ bulk: bulkall: for libc in uclibc eglibc glibc;do \ while read arch; do \ - systems=$$(./scripts/getsystems $$arch| grep -v toolchain); \ + systems=$$(./scripts/getsystems $$arch| grep -v toolchain|grep -v qemu); \ for system in $$systems;do \ mkdir -p $(TOPDIR)/bin/$${system}_$${arch}_$$libc; \ ( \ @@ -549,14 +549,14 @@ bulkall: bulkallmod: for libc in uclibc eglibc glibc;do \ while read arch; do \ - systems=$$(./scripts/getsystems $$arch| grep -v toolchain); \ + systems=$$(./scripts/getsystems $$arch| grep -v toolchain|grep -v qemu); \ for system in $$systems;do \ mkdir -p $(TOPDIR)/bin/$${system}_$${arch}_$$libc; \ ( \ echo === building $$arch $$system $$libc on $$(date); \ $(GMAKE) prereq && \ $(GMAKE) ARCH=$$arch SYSTEM=$$system LIBC=$$libc FS=archive allmodconfig; \ - $(GMAKE) VERBOSE=1 all; if [ $$? -ne 0 ]; then echo $$system >.exit; exit 1;fi; \ + $(GMAKE) VERBOSE=1 all; if [ $$? -ne 0 ]; then echo $$system-$$libc >.exit; exit 1;fi; \ rm .config; \ ) 2>&1 | tee $(TOPDIR)/bin/$${system}_$${arch}_$$libc/build.log; \ done; \ diff --git a/mk/vars.mk b/mk/vars.mk index 89d78be83..e77726943 100644 --- a/mk/vars.mk +++ b/mk/vars.mk @@ -53,6 +53,12 @@ endif ifeq ($(CPU_ARCH),mipsel) QEMU:= qemu-mipsel endif +ifeq ($(CPU_ARCH),mips) +QEMU:= qemu-mips +endif +ifeq ($(CPU_ARCH),i486) +QEMU:= qemu-i386 +endif ifeq ($(CPU_ARCH),i586) QEMU:= qemu-i386 endif diff --git a/package/cluster-glue/Makefile b/package/cluster-glue/Makefile index 0e889194f..140526ebc 100644 --- a/package/cluster-glue/Makefile +++ b/package/cluster-glue/Makefile @@ -15,6 +15,7 @@ PKG_SITES:= http://openadk.org/distfiles/ PKG_CFLINE_CLUSTER_GLUE:= depends on ADK_TARGET_LIB_GLIBC || ADK_TARGET_LIB_EGLIBC PKG_HOST_DEPENDS:= !darwin +PKG_ARCH_DEPENDS:= x86 x86_64 include $(TOPDIR)/mk/package.mk diff --git a/package/cutter/patches/patch-cutter_c b/package/cutter/patches/patch-cutter_c index 781c17401..03129f87e 100644 --- a/package/cutter/patches/patch-cutter_c +++ b/package/cutter/patches/patch-cutter_c @@ -1,7 +1,18 @@ $Id: update-patches 24 2008-08-31 14:56:13Z wbx $ --- cutter-1.03.orig/cutter.c 2005-04-30 09:01:03.000000000 +0200 -+++ cutter-1.03/cutter.c 2008-10-09 11:32:40.000000000 +0200 -@@ -297,7 +297,7 @@ int send_rst( ++++ cutter-1.03/cutter.c 2011-08-24 18:49:58.830478484 +0200 +@@ -35,6 +35,10 @@ + * improvment. + */ + ++#ifndef __packed ++#define __packed __attribute__((packed)) ++#endif ++ + #include + #include + #include +@@ -297,7 +301,7 @@ int send_rst( pheader.placeholder=0; pheader.protocol=IPPROTO_TCP; pheader.tcp_length=htons(TCPHDR); @@ -10,7 +21,7 @@ $Id: update-patches 24 2008-08-31 14:56:13Z wbx $ tpack.tcp.check=in_cksum((unsigned short *)&pheader,TCPHDR+12); /* -@@ -419,7 +419,7 @@ int send_rst( +@@ -419,7 +423,7 @@ int send_rst( pheader.placeholder=0; pheader.protocol=IPPROTO_TCP; pheader.tcp_length=htons(TCPHDR); diff --git a/package/ipsec-tools/patches/patch-src_racoon_isakmp_c b/package/ipsec-tools/patches/patch-src_racoon_isakmp_c new file mode 100644 index 000000000..fdf5356fc --- /dev/null +++ b/package/ipsec-tools/patches/patch-src_racoon_isakmp_c @@ -0,0 +1,21 @@ +--- ipsec-tools-0.8.0.orig/src/racoon/isakmp.c 2011-03-15 14:20:14.000000000 +0100 ++++ ipsec-tools-0.8.0/src/racoon/isakmp.c 2011-08-24 18:48:47.887978959 +0200 +@@ -33,6 +33,10 @@ + + #include "config.h" + ++#ifndef __packed ++#define __packed __attribute__((packed)) ++#endif ++ + #include + #include + #include +@@ -130,6 +134,7 @@ + # define SOL_UDP IPPROTO_UDP + # endif /* __NetBSD__ / __FreeBSD__ */ + ++ + static int nostate1 __P((struct ph1handle *, vchar_t *)); + static int nostate2 __P((struct ph2handle *, vchar_t *)); + diff --git a/package/libhugetlbfs/Makefile b/package/libhugetlbfs/Makefile index 11d8cc9a4..7541c3128 100644 --- a/package/libhugetlbfs/Makefile +++ b/package/libhugetlbfs/Makefile @@ -13,7 +13,7 @@ PKG_URL:= http://libhugetlbfs.ozlabs.org/ PKG_SITES:= ${MASTER_SITE_SOURCEFORGE:=libhugetlbfs/} PKG_CFLINE_LIBHUGETLBFS:= depends on ADK_TARGET_LIB_GLIBC || ADK_TARGET_LIB_EGLIBC -PKG_ARCH_DEPENDS:= x86 x86_64 arm +PKG_ARCH_DEPENDS:= x86 x86_64 include $(TOPDIR)/mk/package.mk diff --git a/package/llvm/Makefile b/package/llvm/Makefile index 0dfd2d3ec..1ac7c3a10 100644 --- a/package/llvm/Makefile +++ b/package/llvm/Makefile @@ -14,6 +14,7 @@ PKG_SITES:= http://llvm.org/releases/2.9/ PKG_CFLINE_LLVM:= depends on ADK_TARGET_LIB_GLIBC || ADK_TARGET_LIB_EGLIBC PKG_HOST_DEPENDS:= !darwin +PKG_ARCH_DEPENDS:= mips x86 x86_64 DISTFILES:= ${PKG_NAME}-${PKG_VERSION}.tgz diff --git a/package/pacemaker/Makefile b/package/pacemaker/Makefile index 8f0b6bbe2..82b217f17 100644 --- a/package/pacemaker/Makefile +++ b/package/pacemaker/Makefile @@ -15,6 +15,7 @@ PKG_SITES:= http://openadk.org/distfiles/ PKG_CFLINE_PACEMAKER:= depends on ADK_TARGET_LIB_GLIBC || ADK_TARGET_LIB_EGLIBC PKG_HOST_DEPENDS:= !darwin +PKG_ARCH_DEPENDS:= x86 include $(TOPDIR)/mk/package.mk diff --git a/package/resource-agents/Makefile b/package/resource-agents/Makefile index 30f63b07b..6611a579c 100644 --- a/package/resource-agents/Makefile +++ b/package/resource-agents/Makefile @@ -14,6 +14,7 @@ PKG_SITES:= http://openadk.org/distfiles/ PKG_CFLINE_RESOURCE_AGENTS:= depends on ADK_TARGET_LIB_GLIBC || ADK_TARGET_LIB_EGLIBC PKG_HOST_DEPENDS:= !darwin +PKG_ARCH_DEPENDS:= x86 include $(TOPDIR)/mk/package.mk diff --git a/target/arm/Makefile b/target/arm/Makefile index dbf955a81..5323750fe 100644 --- a/target/arm/Makefile +++ b/target/arm/Makefile @@ -41,22 +41,29 @@ imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo "The RootFS tarball is: $(BIN_DIR)/$(ROOTFSTARBALL)" +ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) @echo "Use following command to create a QEMU Image:" @echo "sudo ./scripts/create-image.sh -f $(ADK_TARGET_ROOTFS) qemu-${CPU_ARCH}.img $(BIN_DIR)/$(ROOTFSTARBALL)" @echo "Start qemu with following options:" @echo 'qemu-system-arm -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -hda qemu-${CPU_ARCH}.img -append "root=/dev/hda1"' endif +endif ifeq ($(ADK_TARGET_FS),initramfs) imageinstall: $(BIN_DIR)/$(INITRAMFS) @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo 'The initramfs image is: ${BIN_DIR}/${INITRAMFS}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) + @echo "Start qemu with following command line:" @echo 'qemu-system-arm -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) -initrd ${BIN_DIR}/${INITRAMFS}' endif +endif ifeq ($(ADK_TARGET_FS),initramfs-piggyback) imageinstall: ${BUILD_DIR}/${INITRAMFS_PIGGYBACK} createinitramfs @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) @echo 'The kernel+initramfs file is: $(BIN_DIR)/${TARGET_KERNEL}' +ifeq ($(ADK_TARGET_SYSTEM_QEMU_ARM),y) @echo "Start qemu with following command line:" @echo 'qemu-system-arm -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL)' endif +endif diff --git a/target/linux/patches/2.6.39/cris.patch b/target/linux/patches/2.6.39/cris.patch index 3bdc0acb8..2d56de399 100644 --- a/target/linux/patches/2.6.39/cris.patch +++ b/target/linux/patches/2.6.39/cris.patch @@ -1,6 +1,6 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/axisflashmap.c linux-2.6.39/arch/cris/arch-v10/drivers/axisflashmap.c --- linux-2.6.39.orig/arch/cris/arch-v10/drivers/axisflashmap.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/arch-v10/drivers/axisflashmap.c 2011-08-22 08:58:55.057980882 +0200 ++++ linux-2.6.39/arch/cris/arch-v10/drivers/axisflashmap.c 2011-08-25 07:43:00.179230147 +0200 @@ -113,7 +113,7 @@ /* If no partition-table was found, we use this default-set. */ @@ -148,7 +148,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/axisflashmap.c linux-2.6. diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/ds1302.c linux-2.6.39/arch/cris/arch-v10/drivers/ds1302.c --- linux-2.6.39.orig/arch/cris/arch-v10/drivers/ds1302.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/arch-v10/drivers/ds1302.c 2011-08-22 08:58:55.157980341 +0200 ++++ linux-2.6.39/arch/cris/arch-v10/drivers/ds1302.c 2011-08-25 07:43:00.339229517 +0200 @@ -22,6 +22,7 @@ #include #include @@ -183,7 +183,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/ds1302.c linux-2.6.39/arc } diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/gpio.c linux-2.6.39/arch/cris/arch-v10/drivers/gpio.c --- linux-2.6.39.orig/arch/cris/arch-v10/drivers/gpio.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/arch-v10/drivers/gpio.c 2011-08-22 08:58:55.227980067 +0200 ++++ linux-2.6.39/arch/cris/arch-v10/drivers/gpio.c 2011-08-25 07:43:00.588029746 +0200 @@ -20,6 +20,7 @@ #include #include @@ -219,7 +219,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/drivers/gpio.c linux-2.6.39/arch/ CRIS_LED_NETWORK_SET(0); diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/lib/hw_settings.S linux-2.6.39/arch/cris/arch-v10/lib/hw_settings.S --- linux-2.6.39.orig/arch/cris/arch-v10/lib/hw_settings.S 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/arch-v10/lib/hw_settings.S 2011-08-22 08:58:55.287980084 +0200 ++++ linux-2.6.39/arch/cris/arch-v10/lib/hw_settings.S 2011-08-25 07:43:00.799228984 +0200 @@ -58,3 +58,5 @@ .dword R_PORT_PB_SET .dword PB_SET_VALUE @@ -228,7 +228,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/lib/hw_settings.S linux-2.6.39/ar + .dword 0xdeadc0de diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/mm/init.c linux-2.6.39/arch/cris/arch-v10/mm/init.c --- linux-2.6.39.orig/arch/cris/arch-v10/mm/init.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/arch-v10/mm/init.c 2011-08-22 08:58:55.347981214 +0200 ++++ linux-2.6.39/arch/cris/arch-v10/mm/init.c 2011-08-25 07:43:01.069229695 +0200 @@ -184,6 +184,9 @@ free_area_init_node(0, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0); @@ -241,7 +241,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/arch-v10/mm/init.c linux-2.6.39/arch/cris/ * is called before any driver is initialized. diff -Nur linux-2.6.39.orig/arch/cris/boot/compressed/Makefile linux-2.6.39/arch/cris/boot/compressed/Makefile --- linux-2.6.39.orig/arch/cris/boot/compressed/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/boot/compressed/Makefile 2011-08-22 08:58:55.427980567 +0200 ++++ linux-2.6.39/arch/cris/boot/compressed/Makefile 2011-08-25 07:43:01.847994855 +0200 @@ -18,7 +18,7 @@ OBJECTS-$(CONFIG_ETRAX_ARCH_V32) = $(obj)/head_v32.o OBJECTS-$(CONFIG_ETRAX_ARCH_V10) = $(obj)/head_v10.o @@ -253,7 +253,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/boot/compressed/Makefile linux-2.6.39/arch cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@ diff -Nur linux-2.6.39.orig/arch/cris/boot/Makefile linux-2.6.39/arch/cris/boot/Makefile --- linux-2.6.39.orig/arch/cris/boot/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/boot/Makefile 2011-08-22 08:58:55.507980367 +0200 ++++ linux-2.6.39/arch/cris/boot/Makefile 2011-08-25 07:43:01.989240448 +0200 @@ -5,7 +5,7 @@ objcopyflags-$(CONFIG_ETRAX_ARCH_V10) += -R .note -R .comment objcopyflags-$(CONFIG_ETRAX_ARCH_V32) += --remove-section=.bss --remove-section=.note.gnu.build-id @@ -273,7 +273,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/boot/Makefile linux-2.6.39/arch/cris/boot/ @cp $< $@ diff -Nur linux-2.6.39.orig/arch/cris/Kconfig linux-2.6.39/arch/cris/Kconfig --- linux-2.6.39.orig/arch/cris/Kconfig 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/Kconfig 2011-08-22 08:58:55.587980284 +0200 ++++ linux-2.6.39/arch/cris/Kconfig 2011-08-25 07:43:57.197980003 +0200 @@ -168,6 +168,12 @@ help Size of DRAM (decimal in MB) typically 2, 8 or 16. @@ -296,7 +296,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/Kconfig linux-2.6.39/arch/cris/Kconfig select MTD_PARTITIONS select MTD_COMPLEX_MAPPINGS help -@@ -660,6 +666,11 @@ +@@ -660,6 +666,13 @@ source "drivers/ide/Kconfig" @@ -304,11 +304,13 @@ diff -Nur linux-2.6.39.orig/arch/cris/Kconfig linux-2.6.39/arch/cris/Kconfig +source "drivers/scsi/Kconfig" + +source "drivers/media/Kconfig" ++ ++source "drivers/misc/Kconfig" + source "drivers/net/Kconfig" source "drivers/i2c/Kconfig" -@@ -675,6 +686,8 @@ +@@ -675,6 +688,8 @@ source "fs/Kconfig" @@ -319,7 +321,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/Kconfig linux-2.6.39/arch/cris/Kconfig source "drivers/uwb/Kconfig" diff -Nur linux-2.6.39.orig/arch/cris/Makefile linux-2.6.39/arch/cris/Makefile --- linux-2.6.39.orig/arch/cris/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/Makefile 2011-08-22 08:58:55.837980069 +0200 ++++ linux-2.6.39/arch/cris/Makefile 2011-08-25 07:43:02.329230084 +0200 @@ -40,10 +40,10 @@ LD = $(CROSS_COMPILE)ld -mcrislinux @@ -335,7 +337,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/Makefile linux-2.6.39/arch/cris/Makefile ifdef CONFIG_FRAME_POINTER diff -Nur linux-2.6.39.orig/arch/cris/mm/init.c linux-2.6.39/arch/cris/mm/init.c --- linux-2.6.39.orig/arch/cris/mm/init.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/arch/cris/mm/init.c 2011-08-22 08:58:55.897980391 +0200 ++++ linux-2.6.39/arch/cris/mm/init.c 2011-08-25 07:43:02.489240456 +0200 @@ -16,6 +16,7 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); @@ -357,7 +359,7 @@ diff -Nur linux-2.6.39.orig/arch/cris/mm/init.c linux-2.6.39/arch/cris/mm/init.c +#endif diff -Nur linux-2.6.39.orig/drivers/net/cris/eth_v10.c linux-2.6.39/drivers/net/cris/eth_v10.c --- linux-2.6.39.orig/drivers/net/cris/eth_v10.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/net/cris/eth_v10.c 2011-08-22 08:58:55.987980420 +0200 ++++ linux-2.6.39/drivers/net/cris/eth_v10.c 2011-08-25 07:43:02.627979938 +0200 @@ -1714,7 +1714,7 @@ static void e100_netpoll(struct net_device* netdev) @@ -369,7 +371,7 @@ diff -Nur linux-2.6.39.orig/drivers/net/cris/eth_v10.c linux-2.6.39/drivers/net/ diff -Nur linux-2.6.39.orig/drivers/tty/serial/crisv10.c linux-2.6.39/drivers/tty/serial/crisv10.c --- linux-2.6.39.orig/drivers/tty/serial/crisv10.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/tty/serial/crisv10.c 2011-08-22 08:58:56.137981508 +0200 ++++ linux-2.6.39/drivers/tty/serial/crisv10.c 2011-08-25 07:43:02.637980323 +0200 @@ -26,6 +26,7 @@ #include #include @@ -413,7 +415,7 @@ diff -Nur linux-2.6.39.orig/drivers/tty/serial/crisv10.c linux-2.6.39/drivers/tt diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-cris-dbg.h linux-2.6.39/drivers/usb/host/hc-cris-dbg.h --- linux-2.6.39.orig/drivers/usb/host/hc-cris-dbg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/usb/host/hc-cris-dbg.h 2011-08-22 08:58:56.307980767 +0200 ++++ linux-2.6.39/drivers/usb/host/hc-cris-dbg.h 2011-08-25 07:43:02.837990398 +0200 @@ -0,0 +1,146 @@ + +/* macros for debug output */ @@ -563,7 +565,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-cris-dbg.h linux-2.6.39/drivers/ + }) diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-crisv10.c linux-2.6.39/drivers/usb/host/hc-crisv10.c --- linux-2.6.39.orig/drivers/usb/host/hc-crisv10.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/usb/host/hc-crisv10.c 2011-08-22 08:58:56.397980354 +0200 ++++ linux-2.6.39/drivers/usb/host/hc-crisv10.c 2011-08-25 07:43:02.897981683 +0200 @@ -0,0 +1,4801 @@ +/* + * @@ -5368,7 +5370,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-crisv10.c linux-2.6.39/drivers/u +module_exit(module_hcd_exit); diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-crisv10.h linux-2.6.39/drivers/usb/host/hc-crisv10.h --- linux-2.6.39.orig/drivers/usb/host/hc-crisv10.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39/drivers/usb/host/hc-crisv10.h 2011-08-22 08:58:56.467980502 +0200 ++++ linux-2.6.39/drivers/usb/host/hc-crisv10.h 2011-08-25 07:43:03.100480030 +0200 @@ -0,0 +1,331 @@ +#ifndef __LINUX_ETRAX_USB_H +#define __LINUX_ETRAX_USB_H @@ -5703,7 +5705,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/hc-crisv10.h linux-2.6.39/drivers/u +#endif diff -Nur linux-2.6.39.orig/drivers/usb/host/Makefile linux-2.6.39/drivers/usb/host/Makefile --- linux-2.6.39.orig/drivers/usb/host/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/usb/host/Makefile 2011-08-22 08:58:56.527980204 +0200 ++++ linux-2.6.39/drivers/usb/host/Makefile 2011-08-25 07:43:03.209057611 +0200 @@ -32,6 +32,7 @@ obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o @@ -5714,7 +5716,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/host/Makefile linux-2.6.39/drivers/usb/h obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o diff -Nur linux-2.6.39.orig/drivers/usb/Makefile linux-2.6.39/drivers/usb/Makefile --- linux-2.6.39.orig/drivers/usb/Makefile 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/drivers/usb/Makefile 2011-08-22 08:58:56.607990534 +0200 ++++ linux-2.6.39/drivers/usb/Makefile 2011-08-25 07:43:03.380490677 +0200 @@ -21,6 +21,7 @@ obj-$(CONFIG_USB_R8A66597_HCD) += host/ obj-$(CONFIG_USB_HWA_HCD) += host/ @@ -5725,7 +5727,7 @@ diff -Nur linux-2.6.39.orig/drivers/usb/Makefile linux-2.6.39/drivers/usb/Makefi obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ diff -Nur linux-2.6.39.orig/lib/klist.c linux-2.6.39/lib/klist.c --- linux-2.6.39.orig/lib/klist.c 2011-05-19 06:06:34.000000000 +0200 -+++ linux-2.6.39/lib/klist.c 2011-08-22 08:58:56.667990229 +0200 ++++ linux-2.6.39/lib/klist.c 2011-08-25 07:43:03.558483154 +0200 @@ -60,7 +60,7 @@ { knode->n_klist = klist; -- cgit v1.2.3 From 36c9d3691e0fdc8c661b2471d34f053e3cce8efe Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 5 Sep 2011 12:43:49 +0200 Subject: add missing dependency to zlib for compressed usb.ids file --- package/usbutils/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/usbutils/Makefile b/package/usbutils/Makefile index 31c2b6980..e4c903bef 100644 --- a/package/usbutils/Makefile +++ b/package/usbutils/Makefile @@ -9,8 +9,8 @@ PKG_RELEASE:= 1 PKG_MD5SUM:= 94a1738fe92062cdd6a9642eeaccefc1 PKG_DESCR:= A program to list USB devices PKG_SECTION:= utils -PKG_DEPENDS:= libusb libusb-compat libpthread -PKG_BUILDDEP:= libusb libusb-compat +PKG_DEPENDS:= libusb libusb-compat libpthread zlib +PKG_BUILDDEP:= libusb libusb-compat zlib PKG_SITES:= http://www.kernel.org/pub/linux/utils/usb/usbutils/ PKG_SUBPKGS:= LSUSB -- cgit v1.2.3 From e8157b5142acd0130c4f3e6edf821bd8ae90a8de Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 5 Sep 2011 12:58:18 +0200 Subject: unbreak build --- package/python/Makefile | 12 +- package/python/patches/patch-Makefile_pre_in | 53 +++-- package/python/patches/patch-configure | 343 +-------------------------- package/python/patches/patch-setup_py | 41 ++-- 4 files changed, 68 insertions(+), 381 deletions(-) diff --git a/package/python/Makefile b/package/python/Makefile index 4c6cc4428..993dcb034 100644 --- a/package/python/Makefile +++ b/package/python/Makefile @@ -4,11 +4,12 @@ include ${TOPDIR}/rules.mk PKG_NAME:= python -PKG_VERSION:= 3.2 +PKG_VERSION:= 3.2.2 PKG_RELEASE:= 1 -PKG_MD5SUM:= f1317dbb2398374d6691edd5bff1b91d +PKG_MD5SUM:= 3c63a6d97333f4da35976b6a0755eb67 PKG_DESCR:= Python scripting language (Version 3) PKG_SECTION:= lang +PKG_DEPENDS:= libpthread PKG_URL:= http://www.python.org/ PKG_SITES:= http://www.python.org/ftp/python/${PKG_VERSION}/ @@ -21,13 +22,16 @@ include ${TOPDIR}/mk/package.mk $(eval $(call PKG_template,PYTHON,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) +# disable honour cflags stuff +XAKE_FLAGS+= GCC_HONOUR_COPTS=s + MAKE_ENV+= OPT="$(TARGET_CFLAGS)" \ HOSTPYTHON=./hostpython \ HOSTPGEN=./Parser/hostpgen -CONFIGURE_ENV+= OPT="$(TARGET_CFLAGS)" CONFIGURE_ARGS:= --with-threads \ --with-system-ffi \ --without-cxx-main +CONFIGURE_ENV+= ac_cv_have_long_long_format=yes post-extract: (cd ${WRKBUILD}; rm -rf config.{cache,status} ; \ @@ -49,9 +53,11 @@ pre-configure: post-install: ${INSTALL_DIR} ${IDIR_PYTHON}/usr/bin ${IDIR_PYTHON}/usr/lib ${INSTALL_DIR} ${IDIR_PYTHON}/usr/lib/python3.2 + ${INSTALL_DIR} ${IDIR_PYTHON}/usr/include/python3.2m ${INSTALL_BIN} ${WRKINST}/usr/bin/python3 ${IDIR_PYTHON}/usr/bin ${CP} ${WRKINST}/usr/lib/libpython*.so* ${IDIR_PYTHON}/usr/lib cd ${IDIR_PYTHON}/usr/bin && ln -s python3 python ${CP} ${WRKINST}/usr/lib/python3.2/* ${IDIR_PYTHON}/usr/lib/python3.2 + ${CP} ${WRKINST}/usr/include/python3.2m/* ${IDIR_PYTHON}/usr/include/python3.2m include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/python/patches/patch-Makefile_pre_in b/package/python/patches/patch-Makefile_pre_in index 00504cb16..a2f7d96dc 100644 --- a/package/python/patches/patch-Makefile_pre_in +++ b/package/python/patches/patch-Makefile_pre_in @@ -1,6 +1,7 @@ ---- Python-3.1.1.orig/Makefile.pre.in 2009-06-12 00:54:11.000000000 +0200 -+++ Python-3.1.1/Makefile.pre.in 2009-09-28 19:01:13.167748736 +0200 -@@ -52,7 +52,7 @@ INSTALL_DATA= @INSTALL_DATA@ +diff -Nur Python-3.2.2.orig/Makefile.pre.in Python-3.2.2/Makefile.pre.in +--- Python-3.2.2.orig/Makefile.pre.in 2011-09-03 18:16:45.000000000 +0200 ++++ Python-3.2.2/Makefile.pre.in 2011-09-05 11:58:25.000000000 +0200 +@@ -57,7 +57,7 @@ # Shared libraries must be installed with executable mode on some systems; # rather than figuring out exactly which, we always give them executable mode. # Also, making them read-only seems to be a good idea... @@ -9,7 +10,7 @@ MAKESETUP= $(srcdir)/Modules/makesetup -@@ -177,6 +177,7 @@ LIBOBJS= @LIBOBJS@ +@@ -191,6 +191,7 @@ PYTHON= python$(EXE) BUILDPYTHON= python$(BUILDEXE) @@ -17,7 +18,7 @@ # The task to run while instrument when building the profile-opt target PROFILE_TASK= $(srcdir)/Tools/pybench/pybench.py -n 2 --with-gc --with-syscheck -@@ -217,6 +218,7 @@ GRAMMAR_INPUT= $(srcdir)/Grammar/Grammar +@@ -233,6 +234,7 @@ ########################################################################## # Parser PGEN= Parser/pgen$(EXE) @@ -25,7 +26,7 @@ POBJS= \ Parser/acceler.o \ -@@ -393,7 +395,7 @@ build_all_generate_profile: +@@ -413,7 +415,7 @@ $(MAKE) all CFLAGS="$(CFLAGS) -fprofile-generate" LIBS="$(LIBS) -lgcov" run_profile_task: @@ -34,12 +35,12 @@ build_all_use_profile: $(MAKE) all CFLAGS="$(CFLAGS) -fprofile-use" -@@ -411,14 +413,14 @@ $(BUILDPYTHON): Modules/python.o $(LIBRA - $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) +@@ -429,14 +431,14 @@ + $(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Modules/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) platform: $(BUILDPYTHON) -- $(RUNSHARED) ./$(BUILDPYTHON) -E -c 'import sys ; from distutils.util import get_platform ; print(get_platform()+"-"+sys.version[0:3])' >platform -+ $(RUNSHARED) $(HOSTPYTHON) -E -c 'import sys ; from distutils.util import get_platform ; print(get_platform()+"-"+sys.version[0:3])' >platform +- $(RUNSHARED) ./$(BUILDPYTHON) -E -c 'import sys ; from sysconfig import get_platform ; print(get_platform()+"-"+sys.version[0:3])' >platform ++ $(RUNSHARED) $(HOSTPYTHON) -E -c 'import sys ; from sysconfig import get_platform ; print(get_platform()+"-"+sys.version[0:3])' >platform # Build the shared modules @@ -52,43 +53,43 @@ esac # Build static library -@@ -542,7 +544,7 @@ $(IO_OBJS): $(IO_H) - - $(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT) +@@ -587,7 +589,7 @@ + $(GRAMMAR_H) $(GRAMMAR_C): Parser/pgen.stamp + Parser/pgen.stamp: $(PGEN) $(GRAMMAR_INPUT) -@$(INSTALL) -d Include -- -$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) +- $(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) + -$(HOSTPGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) + -touch Parser/pgen.stamp $(PGEN): $(PGENOBJS) - $(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN) -@@ -705,7 +707,7 @@ $(LIBRARY_OBJS) $(MODOBJS) Modules/pytho +@@ -758,7 +760,7 @@ TESTOPTS= -l $(EXTRATESTOPTS) TESTPROG= $(srcdir)/Lib/test/regrtest.py --TESTPYTHON= $(RUNSHARED) ./$(BUILDPYTHON) -E -bb -+TESTPYTHON= $(RUNSHARED) $(HOSTPYTHON) -E -bb +-TESTPYTHON= $(RUNSHARED) ./$(BUILDPYTHON) -Wd -E -bb $(TESTPYTHONOPTS) ++TESTPYTHON= $(RUNSHARED) $(HOSTPYTHON) -Wd -E -bb $(TESTPYTHONOPTS) test: all platform -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -@@ -1018,7 +1020,7 @@ libainstall: all +@@ -1102,7 +1104,7 @@ # Install the dynamically loadable modules # This goes into $(exec_prefix) - sharedinstall: + sharedinstall: sharedmods - $(RUNSHARED) ./$(BUILDPYTHON) -E $(srcdir)/setup.py install \ + $(RUNSHARED) $(HOSTPYTHON) -E $(srcdir)/setup.py install \ --prefix=$(prefix) \ --install-scripts=$(BINDIR) \ --install-platlib=$(DESTSHARED) \ -@@ -1056,7 +1058,7 @@ frameworkinstallstructure: $(LDLIBRARY) +@@ -1140,7 +1142,7 @@ fi; \ done - $(LN) -fsn include/python$(VERSION) $(DESTDIR)$(prefix)/Headers + $(LN) -fsn include/python$(LDVERSION) $(DESTDIR)$(prefix)/Headers - sed 's/%VERSION%/'"`$(RUNSHARED) ./$(BUILDPYTHON) -c 'import platform; print(platform.python_version())'`"'/g' < $(RESSRCDIR)/Info.plist > $(DESTDIR)$(prefix)/Resources/Info.plist + sed 's/%VERSION%/'"`$(RUNSHARED) $(HOSTPYTHON) -c 'import platform; print(platform.python_version())'`"'/g' < $(RESSRCDIR)/Info.plist > $(DESTDIR)$(prefix)/Resources/Info.plist $(LN) -fsn $(VERSION) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/Current $(LN) -fsn Versions/Current/$(PYTHONFRAMEWORK) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/$(PYTHONFRAMEWORK) $(LN) -fsn Versions/Current/Headers $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers -@@ -1098,7 +1100,7 @@ frameworkinstallextras: +@@ -1174,7 +1176,7 @@ # This installs a few of the useful scripts in Tools/scripts scriptsinstall: SRCDIR=$(srcdir) $(RUNSHARED) \ @@ -96,8 +97,8 @@ + $(HOSTPYTHON) $(srcdir)/Tools/scripts/setup.py install \ --prefix=$(prefix) \ --install-scripts=$(BINDIR) \ - --root=/$(DESTDIR) -@@ -1120,7 +1122,7 @@ config.status: $(srcdir)/configure + --root=$(DESTDIR)/ +@@ -1196,7 +1198,7 @@ # Run reindent on the library reindent: @@ -106,7 +107,7 @@ # Rerun configure with the same options as it was run last time, # provided the config.status script exists -@@ -1234,7 +1236,7 @@ funny: +@@ -1317,7 +1319,7 @@ # Perform some verification checks on any modified files. patchcheck: diff --git a/package/python/patches/patch-configure b/package/python/patches/patch-configure index b76afc821..b24d4c24f 100644 --- a/package/python/patches/patch-configure +++ b/package/python/patches/patch-configure @@ -1,12 +1,13 @@ ---- Python-3.1.1.orig/configure 2009-06-08 23:22:57.000000000 +0200 -+++ Python-3.1.1/configure 2010-11-07 20:52:09.000000000 +0100 -@@ -2051,12 +2051,12 @@ fi - echo $ECHO_N "checking MACHDEP... $ECHO_C" >&6; } +diff -Nur Python-3.2.2.orig/configure Python-3.2.2/configure +--- Python-3.2.2.orig/configure 2011-09-03 18:16:50.000000000 +0200 ++++ Python-3.2.2/configure 2011-09-05 11:35:01.000000000 +0200 +@@ -2983,12 +2983,12 @@ + $as_echo_n "checking MACHDEP... " >&6; } if test -z "$MACHDEP" then - ac_sys_system=`uname -s` + ac_sys_system=Linux - if test "$ac_sys_system" = "AIX" -o "$ac_sys_system" = "Monterey64" \ + if test "$ac_sys_system" = "AIX" \ -o "$ac_sys_system" = "UnixWare" -o "$ac_sys_system" = "OpenUNIX"; then ac_sys_release=`uname -v` else @@ -15,334 +16,12 @@ fi ac_md_system=`echo $ac_sys_system | tr -d '/ ' | tr '[A-Z]' '[a-z]'` -@@ -2224,7 +2224,7 @@ EXPORT_MACOSX_DEPLOYMENT_TARGET='#' +@@ -3140,7 +3140,7 @@ - { echo "$as_me:$LINENO: checking machine type as reported by uname -m" >&5 - echo $ECHO_N "checking machine type as reported by uname -m... $ECHO_C" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking machine type as reported by uname -m" >&5 + $as_echo_n "checking machine type as reported by uname -m... " >&6; } -ac_sys_machine=`uname -m` +ac_sys_machine=@@CPU_ARCH@@ - { echo "$as_me:$LINENO: result: $ac_sys_machine" >&5 - echo "${ECHO_T}$ac_sys_machine" >&6; } - -@@ -17204,141 +17204,6 @@ fi - fi - - --# On Tru64, chflags seems to be present, but calling it will --# exit Python --{ echo "$as_me:$LINENO: checking for chflags" >&5 --echo $ECHO_N "checking for chflags... $ECHO_C" >&6; } --if test "$cross_compiling" = yes; then -- { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling --See \`config.log' for more details." >&5 --echo "$as_me: error: cannot run test program while cross compiling --See \`config.log' for more details." >&2;} -- { (exit 1); exit 1; }; } --else -- cat >conftest.$ac_ext <<_ACEOF --/* confdefs.h. */ --_ACEOF --cat confdefs.h >>conftest.$ac_ext --cat >>conftest.$ac_ext <<_ACEOF --/* end confdefs.h. */ -- --#include --#include --int main(int argc, char*argv[]) --{ -- if(chflags(argv[0], 0) != 0) -- return 1; -- return 0; --} -- --_ACEOF --rm -f conftest$ac_exeext --if { (ac_try="$ac_link" --case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 -- (eval "$ac_link") 2>&5 -- ac_status=$? -- echo "$as_me:$LINENO: \$? = $ac_status" >&5 -- (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -- { (case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 -- (eval "$ac_try") 2>&5 -- ac_status=$? -- echo "$as_me:$LINENO: \$? = $ac_status" >&5 -- (exit $ac_status); }; }; then -- --cat >>confdefs.h <<\_ACEOF --#define HAVE_CHFLAGS 1 --_ACEOF -- -- { echo "$as_me:$LINENO: result: yes" >&5 --echo "${ECHO_T}yes" >&6; } --else -- echo "$as_me: program exited with status $ac_status" >&5 --echo "$as_me: failed program was:" >&5 --sed 's/^/| /' conftest.$ac_ext >&5 -- --( exit $ac_status ) --{ echo "$as_me:$LINENO: result: no" >&5 --echo "${ECHO_T}no" >&6; } -- --fi --rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext --fi -- -- -- --{ echo "$as_me:$LINENO: checking for lchflags" >&5 --echo $ECHO_N "checking for lchflags... $ECHO_C" >&6; } --if test "$cross_compiling" = yes; then -- { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling --See \`config.log' for more details." >&5 --echo "$as_me: error: cannot run test program while cross compiling --See \`config.log' for more details." >&2;} -- { (exit 1); exit 1; }; } --else -- cat >conftest.$ac_ext <<_ACEOF --/* confdefs.h. */ --_ACEOF --cat confdefs.h >>conftest.$ac_ext --cat >>conftest.$ac_ext <<_ACEOF --/* end confdefs.h. */ -- --#include --#include --int main(int argc, char*argv[]) --{ -- if(lchflags(argv[0], 0) != 0) -- return 1; -- return 0; --} -- --_ACEOF --rm -f conftest$ac_exeext --if { (ac_try="$ac_link" --case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 -- (eval "$ac_link") 2>&5 -- ac_status=$? -- echo "$as_me:$LINENO: \$? = $ac_status" >&5 -- (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -- { (case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 -- (eval "$ac_try") 2>&5 -- ac_status=$? -- echo "$as_me:$LINENO: \$? = $ac_status" >&5 -- (exit $ac_status); }; }; then -- --cat >>confdefs.h <<\_ACEOF --#define HAVE_LCHFLAGS 1 --_ACEOF -- -- { echo "$as_me:$LINENO: result: yes" >&5 --echo "${ECHO_T}yes" >&6; } --else -- echo "$as_me: program exited with status $ac_status" >&5 --echo "$as_me: failed program was:" >&5 --sed 's/^/| /' conftest.$ac_ext >&5 -- --( exit $ac_status ) --{ echo "$as_me:$LINENO: result: no" >&5 --echo "${ECHO_T}no" >&6; } -- --fi --rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext --fi - - - -@@ -22435,84 +22300,6 @@ fi - - LIBS=$LIBS_SAVE - --# Multiprocessing check for broken sem_getvalue --{ echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 --echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } --if test "$cross_compiling" = yes; then -- { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling --See \`config.log' for more details." >&5 --echo "$as_me: error: cannot run test program while cross compiling --See \`config.log' for more details." >&2;} -- { (exit 1); exit 1; }; } --else -- cat >conftest.$ac_ext <<_ACEOF --/* confdefs.h. */ --_ACEOF --cat confdefs.h >>conftest.$ac_ext --cat >>conftest.$ac_ext <<_ACEOF --/* end confdefs.h. */ -- --#include --#include --#include --#include --#include -- --int main(void){ -- sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); -- int count; -- int res; -- if(a==SEM_FAILED){ -- perror("sem_open"); -- return 1; -- -- } -- res = sem_getvalue(a, &count); -- sem_close(a); -- return res==-1 ? 1 : 0; --} -- -- --_ACEOF --rm -f conftest$ac_exeext --if { (ac_try="$ac_link" --case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 -- (eval "$ac_link") 2>&5 -- ac_status=$? -- echo "$as_me:$LINENO: \$? = $ac_status" >&5 -- (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -- { (case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 -- (eval "$ac_try") 2>&5 -- ac_status=$? -- echo "$as_me:$LINENO: \$? = $ac_status" >&5 -- (exit $ac_status); }; }; then -- { echo "$as_me:$LINENO: result: no" >&5 --echo "${ECHO_T}no" >&6; } --else -- echo "$as_me: program exited with status $ac_status" >&5 --echo "$as_me: failed program was:" >&5 --sed 's/^/| /' conftest.$ac_ext >&5 -- --( exit $ac_status ) --{ echo "$as_me:$LINENO: result: yes" >&5 --echo "${ECHO_T}yes" >&6; } -- --cat >>confdefs.h <<\_ACEOF --#define HAVE_BROKEN_SEM_GETVALUE 1 --_ACEOF -- -- --fi --rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext --fi - - - -@@ -25145,94 +24932,6 @@ else - echo "${ECHO_T}no" >&6; } - fi - --{ echo "$as_me:$LINENO: checking for %zd printf() format support" >&5 --echo $ECHO_N "checking for %zd printf() format support... $ECHO_C" >&6; } --if test "$cross_compiling" = yes; then -- { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling --See \`config.log' for more details." >&5 --echo "$as_me: error: cannot run test program while cross compiling --See \`config.log' for more details." >&2;} -- { (exit 1); exit 1; }; } --else -- cat >conftest.$ac_ext <<_ACEOF --/* confdefs.h. */ --_ACEOF --cat confdefs.h >>conftest.$ac_ext --cat >>conftest.$ac_ext <<_ACEOF --/* end confdefs.h. */ --#include --#include --#include -- --#ifdef HAVE_SYS_TYPES_H --#include --#endif -- --#ifdef HAVE_SSIZE_T --typedef ssize_t Py_ssize_t; --#elif SIZEOF_VOID_P == SIZEOF_LONG --typedef long Py_ssize_t; --#else --typedef int Py_ssize_t; --#endif -- --int main() --{ -- char buffer[256]; -- -- if(sprintf(buffer, "%zd", (size_t)123) < 0) -- return 1; -- -- if (strcmp(buffer, "123")) -- return 1; -- -- if (sprintf(buffer, "%zd", (Py_ssize_t)-123) < 0) -- return 1; -- -- if (strcmp(buffer, "-123")) -- return 1; -- -- return 0; --} --_ACEOF --rm -f conftest$ac_exeext --if { (ac_try="$ac_link" --case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 -- (eval "$ac_link") 2>&5 -- ac_status=$? -- echo "$as_me:$LINENO: \$? = $ac_status" >&5 -- (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -- { (case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 -- (eval "$ac_try") 2>&5 -- ac_status=$? -- echo "$as_me:$LINENO: \$? = $ac_status" >&5 -- (exit $ac_status); }; }; then -- { echo "$as_me:$LINENO: result: yes" >&5 --echo "${ECHO_T}yes" >&6; } -- --cat >>confdefs.h <<\_ACEOF --#define PY_FORMAT_SIZE_T "z" --_ACEOF -- --else -- echo "$as_me: program exited with status $ac_status" >&5 --echo "$as_me: failed program was:" >&5 --sed 's/^/| /' conftest.$ac_ext >&5 -- --( exit $ac_status ) --{ echo "$as_me:$LINENO: result: no" >&5 --echo "${ECHO_T}no" >&6; } --fi --rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext --fi - - + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_sys_machine" >&5 + $as_echo "$ac_sys_machine" >&6; } diff --git a/package/python/patches/patch-setup_py b/package/python/patches/patch-setup_py index c9f3dfe08..2c910039c 100644 --- a/package/python/patches/patch-setup_py +++ b/package/python/patches/patch-setup_py @@ -1,6 +1,7 @@ ---- Python-3.1.1.orig/setup.py 2009-08-12 20:39:44.000000000 +0200 -+++ Python-3.1.1/setup.py 2009-09-28 19:12:33.550271196 +0200 -@@ -255,36 +255,6 @@ class PyBuildExt(build_ext): +diff -Nur Python-3.2.2.orig/setup.py Python-3.2.2/setup.py +--- Python-3.2.2.orig/setup.py 2011-09-03 18:16:50.000000000 +0200 ++++ Python-3.2.2/setup.py 2011-09-05 12:17:57.000000000 +0200 +@@ -332,36 +332,6 @@ # cached. Clear that cache before trying to import. sys.path_importer_cache.clear() @@ -37,32 +38,32 @@ def get_platform(self): # Get value of sys.platform -@@ -295,8 +265,8 @@ class PyBuildExt(build_ext): - - def detect_modules(self): - # Ensure that /usr/local is always used +@@ -396,8 +366,8 @@ + # Ensure that /usr/local is always used, but the local build + # directories (i.e. '.' and 'Include') must be first. See issue + # 10520. - add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') - add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') + #add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') + #add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') + self.add_multiarch_paths() # Add paths specified in the environment variables LDFLAGS and - # CPPFLAGS for header and library files. -@@ -332,20 +302,22 @@ class PyBuildExt(build_ext): +@@ -434,25 +404,16 @@ for directory in reversed(options.dirs): add_dir_to_list(dir_list, directory) -- if os.path.normpath(sys.prefix) != '/usr': +- if os.path.normpath(sys.prefix) != '/usr' \ +- and not sysconfig.get_config_var('PYTHONFRAMEWORK'): +- # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework +- # (PYTHONFRAMEWORK is set) to avoid # linking problems when +- # building a framework with different architectures than +- # the one that is currently installed (issue #7473) - add_dir_to_list(self.compiler.library_dirs, - sysconfig.get_config_var("LIBDIR")) - add_dir_to_list(self.compiler.include_dirs, - sysconfig.get_config_var("INCLUDEDIR")) -+ #if os.path.normpath(sys.prefix) != '/usr': -+ # add_dir_to_list(self.compiler.library_dirs, -+ # sysconfig.get_config_var("LIBDIR")) -+ # add_dir_to_list(self.compiler.include_dirs, -+ # sysconfig.get_config_var("INCLUDEDIR")) - +- # lib_dirs and inc_dirs are used to search for files; # if a file is found in one of those directories, it can # be assumed that no additional -I,-L directives are needed. @@ -71,13 +72,13 @@ - '/lib', '/usr/lib', - ] - inc_dirs = self.compiler.include_dirs + ['/usr/include'] -+ #lib_dirs = self.compiler.library_dirs + [ ++ lib_dirs = self.compiler.library_dirs ++ #+ [ + # '/lib64', '/usr/lib64', + # '/lib', '/usr/lib', + # ] -+ #inc_dirs = self.compiler.include_dirs + ['/usr/include'] -+ inc_dirs = self.compiler.include_dirs -+ lib_dirs = self.compiler.library_dirs ++ inc_dirs = self.compiler.include_dirs ++ #+ ['/usr/include'] exts = [] missing = [] -- cgit v1.2.3 From 7380941d507ee1d245b3ce20d93e32aa83f8ea9c Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 5 Sep 2011 18:17:46 +0200 Subject: add kexec tools package --- package/kexec-tools/Makefile | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 package/kexec-tools/Makefile diff --git a/package/kexec-tools/Makefile b/package/kexec-tools/Makefile new file mode 100644 index 000000000..38b949326 --- /dev/null +++ b/package/kexec-tools/Makefile @@ -0,0 +1,26 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(TOPDIR)/rules.mk + +PKG_NAME:= kexec-tools +PKG_VERSION:= 2.0.2 +PKG_RELEASE:= 1 +PKG_MD5SUM:= bc401cf3262b25ff7c9a51fc76c8ab91 +PKG_DESCR:= kexec tools +PKG_SECTION:= misc +PKG_DEPENDS:= zlib +PKG_BUILDEP:= zlib +PKG_URL:= http://kernel.org/pub/linux/utils/kernel/kexec/ +PKG_SITES:= http://kernel.org/pub/linux/utils/kernel/kexec/ + +include $(TOPDIR)/mk/package.mk + +$(eval $(call PKG_template,KEXEC_TOOLS,kexec-tools,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) + +kexec-tools-install: + $(INSTALL_DIR) $(IDIR_KEXEC_TOOLS)/usr/sbin + $(INSTALL_BIN) $(WRKINST)/usr/sbin/kexec \ + $(IDIR_KEXEC_TOOLS)/usr/sbin + +include ${TOPDIR}/mk/pkg-bottom.mk -- cgit v1.2.3 From a0e2c5dc26f0126d8462e15e3bdf9a92bbbbee34 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 5 Sep 2011 18:25:34 +0200 Subject: some sparc help fixes --- mk/rootfs.mk | 2 ++ target/config/Config.in | 1 + target/sparc/Makefile | 6 ++++++ target/sparc64/Makefile | 6 ++++++ 4 files changed, 15 insertions(+) diff --git a/mk/rootfs.mk b/mk/rootfs.mk index 5080944e6..6b34156a5 100644 --- a/mk/rootfs.mk +++ b/mk/rootfs.mk @@ -9,8 +9,10 @@ endif endef ifeq ($(ADK_HARDWARE_QEMU),y) +ifeq ($(ADK_TARGET_ROOTFS_ARCHIVE),y) ROOTFS:= root=/dev/sda1 endif +endif ifeq ($(ADK_TARGET_SYSTEM_MIKROTIK_RB532),y) ROOTFS:= root=/dev/sda2 diff --git a/target/config/Config.in b/target/config/Config.in index 7be4cf844..fd0f3e146 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -303,6 +303,7 @@ config ADK_TARGET_CPU_ARCH default "arm" if ADK_LINUX_ARM && ADK_little default "armeb" if ADK_LINUX_ARM && ADK_big default "sparc" if ADK_LINUX_SPARC + default "sparc64" if ADK_LINUX_SPARC64 default "sh" if ADK_LINUX_SH default "cris" if ADK_CPU_CRIS_V10 default "crisv32" if ADK_CPU_CRIS_V32 diff --git a/target/sparc/Makefile b/target/sparc/Makefile index 5fe97c12a..7a19300b4 100644 --- a/target/sparc/Makefile +++ b/target/sparc/Makefile @@ -14,6 +14,12 @@ imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) @cp $(KERNEL) $(BIN_DIR)/${TARGET_KERNEL} @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo "The RootFS tarball is: $(BIN_DIR)/$(ROOTFSTARBALL)" +ifeq ($(ADK_TARGET_SYSTEM_QEMU_SPARC),y) + @echo "Use following command to create a QEMU Image:" + @echo "sudo ./scripts/create-image.sh -f ${ADK_TARGET_ROOTFS} qemu-${CPU_ARCH}.img $(BIN_DIR)/$(ROOTFSTARBALL)" + @echo "Start qemu with following command line:" + @echo 'qemu-system-sparc -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) qemu-${CPU_ARCH}.img -append "root=/dev/sda1"' +endif endif ifeq ($(ADK_TARGET_FS),initramfs) imageinstall: $(BIN_DIR)/$(INITRAMFS) diff --git a/target/sparc64/Makefile b/target/sparc64/Makefile index 3e7240621..d3d46d571 100644 --- a/target/sparc64/Makefile +++ b/target/sparc64/Makefile @@ -14,6 +14,12 @@ imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) @cp $(KERNEL) $(BIN_DIR)/${TARGET_KERNEL} @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo "The RootFS tarball is: $(BIN_DIR)/$(ROOTFSTARBALL)" +ifeq ($(ADK_TARGET_SYSTEM_QEMU_SPARC64),y) + @echo "Use following command to create a QEMU Image:" + @echo "sudo ./scripts/create-image.sh -f ${ADK_TARGET_ROOTFS} qemu-${CPU_ARCH}.img $(BIN_DIR)/$(ROOTFSTARBALL)" + @echo "Start qemu with following command line:" + @echo 'qemu-system-sparc64 -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) qemu-${CPU_ARCH}.img -append "root=/dev/sda1"' +endif endif ifeq ($(ADK_TARGET_FS),initramfs) imageinstall: $(BIN_DIR)/$(INITRAMFS) -- cgit v1.2.3 From 5bd343f06caa18e95825a4e6f4f31cf4786e7688 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 5 Sep 2011 18:54:48 +0200 Subject: add Kexec kernel option to menu, fix usage of shutdown -r in kexec --- package/kexec-tools/patches/patch-kexec_kexec_c | 24 ++++++++++++++++++++++++ target/linux/config/Config.in.misc | 6 ++++++ 2 files changed, 30 insertions(+) create mode 100644 package/kexec-tools/patches/patch-kexec_kexec_c diff --git a/package/kexec-tools/patches/patch-kexec_kexec_c b/package/kexec-tools/patches/patch-kexec_kexec_c new file mode 100644 index 000000000..68dc2bee9 --- /dev/null +++ b/package/kexec-tools/patches/patch-kexec_kexec_c @@ -0,0 +1,24 @@ +--- kexec-tools-2.0.2.orig/kexec/kexec.c 2010-07-29 06:19:59.000000000 +0200 ++++ kexec-tools-2.0.2/kexec/kexec.c 2011-09-05 18:50:27.679232756 +0200 +@@ -796,17 +796,14 @@ int k_unload (unsigned long kexec_flags) + static int my_shutdown(void) + { + char *args[] = { +- "shutdown", +- "-r", +- "now", ++ "reboot", ++ "-f", + NULL + }; + +- execv("/sbin/shutdown", args); +- execv("/etc/shutdown", args); +- execv("/bin/shutdown", args); ++ execv("/sbin/reboot", args); + +- perror("shutdown"); ++ perror("reboot"); + return -1; + } + diff --git a/target/linux/config/Config.in.misc b/target/linux/config/Config.in.misc index e7891a465..2a2b3e860 100644 --- a/target/linux/config/Config.in.misc +++ b/target/linux/config/Config.in.misc @@ -15,6 +15,12 @@ config ADK_KERNEL_RTC_INTF_DEV menu "Miscellaneous devices support" +config ADK_KERNEL_KEXEC + prompt ".................................. Add KEXEC syscall" + boolean + help + You need also kexec-tools to benefit from it. + config ADK_KERNEL_RTC_DRV_AT91SAM9 prompt ".................................. RTC support for AT91SAM9 (Fox G20)" boolean -- cgit v1.2.3 From 78cbe696f16fdb6c76a860c84afe5f28b5b68677 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 5 Sep 2011 19:07:32 +0200 Subject: enable graphic mode in qemu-i686 --- target/linux/config/Config.in.graphics | 11 +++++++++++ target/linux/config/Config.in.input | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/target/linux/config/Config.in.graphics b/target/linux/config/Config.in.graphics index 5cbe307f0..61e124098 100644 --- a/target/linux/config/Config.in.graphics +++ b/target/linux/config/Config.in.graphics @@ -48,6 +48,17 @@ config ADK_KERNEL_AGP_INTEL menu "Graphic devices support" depends on ADK_TARGET_WITH_VGA +config ADK_KERNEL_FB_CIRRUS + prompt "................................ Framebuffer support for QEMU Emulator" + tristate + select ADK_KERNEL_FB + select ADK_KERNEL_FRAMEBUFFER_CONSOLE + default y if ADK_TARGET_SYSTEM_QEMU_I686 + default n + depends on ADK_TARGET_SYSTEM_QEMU_I686 + help + Framebuffer support for Qemu Emulator. + config ADK_KERNEL_FB_GEODE_LX prompt "................................ Framebuffer support for ALIX boards with VGA" tristate diff --git a/target/linux/config/Config.in.input b/target/linux/config/Config.in.input index 65524a0d3..07fc751a5 100644 --- a/target/linux/config/Config.in.input +++ b/target/linux/config/Config.in.input @@ -3,6 +3,7 @@ depends on ADK_TARGET_WITH_USB || ADK_TARGET_WITH_INPUT config ADK_KERNEL_INPUT boolean + default y if ADK_TARGET_SYSTEM_QEMU_I686 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 @@ -14,6 +15,7 @@ config ADK_KERNEL_INPUT config ADK_KERNEL_INPUT_KEYBOARD boolean + default y if ADK_TARGET_SYSTEM_QEMU_I686 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 @@ -25,6 +27,7 @@ config ADK_KERNEL_INPUT_KEYBOARD config ADK_KERNEL_KEYBOARD_ATKBD boolean + default y if ADK_TARGET_SYSTEM_QEMU_I686 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 @@ -36,6 +39,7 @@ config ADK_KERNEL_KEYBOARD_ATKBD config ADK_KERNEL_INPUT_MOUSE boolean + default y if ADK_TARGET_SYSTEM_QEMU_I686 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 @@ -47,6 +51,7 @@ config ADK_KERNEL_INPUT_MOUSE config ADK_KERNEL_INPUT_MOUSEDEV boolean + default y if ADK_TARGET_SYSTEM_QEMU_I686 default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX1C default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 -- cgit v1.2.3 From 218111185307d2dc3da59ae467aa0c8e68324a86 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 5 Sep 2011 19:58:50 +0200 Subject: allow booting from image disk --- target/ppc/Makefile | 7 +++ target/ppc/kernel.config | 133 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 136 insertions(+), 4 deletions(-) diff --git a/target/ppc/Makefile b/target/ppc/Makefile index 1b225d657..47a4b7df1 100644 --- a/target/ppc/Makefile +++ b/target/ppc/Makefile @@ -14,6 +14,13 @@ imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL) @cp $(KERNEL) $(BIN_DIR)/${TARGET_KERNEL} @echo 'The kernel file is: $(BIN_DIR)/${TARGET_KERNEL}' @echo "The RootFS tarball is: $(BIN_DIR)/$(ROOTFSTARBALL)" +ifeq ($(ADK_HARDWARE_QEMU),y) + @cp $(KERNEL) $(BIN_DIR)/$(TARGET_KERNEL) + @echo "Use following command to create a QEMU Image:" + @echo "sudo ./scripts/create-image.sh -f ${ADK_TARGET_ROOTFS} qemu-${CPU_ARCH}.img $(BIN_DIR)/$(ROOTFSTARBALL)" + @echo "Start qemu with following command line:" + @echo 'qemu-system-ppc -nographic -kernel $(BIN_DIR)/$(TARGET_KERNEL) qemu-${CPU_ARCH}.img' +endif endif ifeq ($(ADK_TARGET_FS),initramfs) imageinstall: $(BIN_DIR)/$(INITRAMFS) diff --git a/target/ppc/kernel.config b/target/ppc/kernel.config index d97b641cc..42f6e73e2 100644 --- a/target/ppc/kernel.config +++ b/target/ppc/kernel.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux/powerpc 2.6.39 Kernel Configuration -# Tue Aug 23 14:16:21 2011 +# Mon Sep 5 19:53:55 2011 # # CONFIG_PPC64 is not set @@ -460,11 +460,136 @@ CONFIG_HAVE_IDE=y # CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +# CONFIG_BLK_DEV_SD is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_AHCI_PLATFORM is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_ACARD_AHCI is not set +# CONFIG_SATA_SIL24 is not set +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_SX4 is not set +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set + +# +# PATA SFF controllers with BMDMA +# +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARASAN_CF is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_ATP867X is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5536 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +CONFIG_PATA_MACIO=y +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RDC is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SCH is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set + +# +# PIO-only SFF controllers +# +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_RZ1000 is not set + +# +# Generic fallback / legacy drivers +# +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set # CONFIG_FUSION is not set # -- cgit v1.2.3 From 7ed65cbcb419432904ce12096723689992bac047 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 6 Sep 2011 17:05:42 +0200 Subject: add missing deps --- target/linux/config/Config.in.netdevice | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/linux/config/Config.in.netdevice b/target/linux/config/Config.in.netdevice index b615156f9..2eea73b4a 100644 --- a/target/linux/config/Config.in.netdevice +++ b/target/linux/config/Config.in.netdevice @@ -409,6 +409,8 @@ config ADK_KPACKAGE_KMOD_RTL8187 tristate depends on ADK_TARGET_WITH_USB depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX + select ADK_KPACKAGE_KMOD_MAC80211 + select ADK_KPACKAGE_KMOD_EEPROM_93CX6 default n help Driver for Realtek RTL8187/RTL8187B wireless chips. -- cgit v1.2.3 From 491591b1136277a00c6b3f11656ed851cc7378f1 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 6 Sep 2011 17:14:30 +0200 Subject: select kernel feature --- package/kexec-tools/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/kexec-tools/Makefile b/package/kexec-tools/Makefile index 38b949326..d66da0ff3 100644 --- a/package/kexec-tools/Makefile +++ b/package/kexec-tools/Makefile @@ -14,6 +14,8 @@ PKG_BUILDEP:= zlib PKG_URL:= http://kernel.org/pub/linux/utils/kernel/kexec/ PKG_SITES:= http://kernel.org/pub/linux/utils/kernel/kexec/ +PKG_CFLINE_KEXEC_TOOLS:= select ADK_KERNEL_KEXEC + include $(TOPDIR)/mk/package.mk $(eval $(call PKG_template,KEXEC_TOOLS,kexec-tools,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) -- cgit v1.2.3 From f0fefd2be69a816c2c64593596719e7e2af9bf05 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 7 Sep 2011 10:36:24 +0200 Subject: add resize2fs subpackage --- package/e2fsprogs/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/package/e2fsprogs/Makefile b/package/e2fsprogs/Makefile index cd2c3caeb..ac605e2d2 100644 --- a/package/e2fsprogs/Makefile +++ b/package/e2fsprogs/Makefile @@ -17,6 +17,7 @@ PKG_CFLINE_E2FSPROGS:= default y if ADK_TARGET_ROOTFS_CF PKG_SUBPKGS:= E2FSPROGS LIBUUID LIBCOM_ERR LIBSS LIBBLKID E2FSCK_STATIC PKG_SUBPKGS+= LIBCOM_ERR_DEV LIBSS_DEV LIBUUID_DEV LIBBLKID_DEV +PKG_SUBPKGS+= RESIZE2FS PKGSD_LIBUUID:= UUID library PKGSC_LIBUUID:= libs PKGSD_LIBUUID_DEV:= UUID headers @@ -35,6 +36,8 @@ PKGSD_LIBBLKID_DEV:= blkid headers PKGSC_LIBBLKID_DEV:= devel PKGSD_E2FSCK_STATIC:= Static build of e2fsck PKGSC_E2FSCK_STATIC:= fs +PKGSD_RESIZE2FS:= Resize FS utility +PKGSC_RESIZE2FS:= fs include ${TOPDIR}/mk/package.mk @@ -48,6 +51,7 @@ $(eval $(call PKG_template,LIBSS_DEV,libss-dev,${PKG_VERSION}-${PKG_RELEASE},,${ $(eval $(call PKG_template,LIBBLKID,libblkid,${PKG_VERSION}-${PKG_RELEASE},,${PKGSD_LIBBLKID},${PKGSC_LIBBLKID})) $(eval $(call PKG_template,LIBBLKID_DEV,libblkid-dev,${PKG_VERSION}-${PKG_RELEASE},,${PKGSD_LIBBLKID_DEV},${PKGSC_LIBBLKID_DEV})) $(eval $(call PKG_template,E2FSCK_STATIC,e2fsck-static,${PKG_VERSION}-${PKG_RELEASE},,${PKGSD_E2FSCK_STATIC},${PKGSC_E2FSCK_STATIC})) +$(eval $(call PKG_template,RESIZE2FS,resize2fs,${PKG_VERSION}-${PKG_RELEASE},,${PKGSD_RESIZE2FS},${PKGSC_RESIZE2FS})) CONFIGURE_ARGS+= --enable-elf-shlibs --disable-rpath INSTALL_TARGET+= install-libs @@ -78,6 +82,10 @@ e2fsprogs-install: ${CP} ${WRKINST}/usr/lib/lib{e2p,ext2fs}.so.* \ ${IDIR_E2FSPROGS}/usr/lib +resize2fs-install: + ${INSTALL_DIR} ${IDIR_RESIZE2FS}/usr/sbin + ${INSTALL_BIN} ${WRKINST}/usr/sbin/resize2fs ${IDIR_RESIZE2FS}/usr/sbin + libblkid-install: ${INSTALL_DIR} ${IDIR_LIBBLKID}/usr/lib ${CP} ${WRKINST}/usr/lib/libblkid.so* \ -- cgit v1.2.3 From 38473a0062d298a7e74022b7ef21eeda151bcb5d Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 7 Sep 2011 10:36:48 +0200 Subject: move devel package to x11/devel --- package/xorg-server/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package/xorg-server/Makefile b/package/xorg-server/Makefile index f953d434f..04e6471d5 100644 --- a/package/xorg-server/Makefile +++ b/package/xorg-server/Makefile @@ -22,6 +22,8 @@ PKG_SITES:= ${MASTER_SITE_XORG} PKG_NEED_CXX:= 1 PKG_SUBPKGS:= XORG_SERVER XORG_SERVER_DEV +PKGSD_XORG_SERVER_DEV:= Xorg server development files +PKGSC_XORG_SERVER_DEV:= x11/devel PKG_CFLINE_XORG_SERVER:=depends on ADK_TARGET_WITH_VGA PKG_ARCH_DEPENDS:= !cris @@ -42,7 +44,7 @@ PKGCB_WITH_CRYPTO:= openssl include $(TOPDIR)/mk/package.mk $(eval $(call PKG_template,XORG_SERVER,${PKG_NAME},$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) -$(eval $(call PKG_template,XORG_SERVER_DEV,${PKG_NAME}-dev,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) +$(eval $(call PKG_template,XORG_SERVER_DEV,${PKG_NAME}-dev,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKGSD_XORG_SERVER_DEV},${PKGSC_XORG_SERVER_DEV})) ifeq (${ADK_PACKAGE_XORG_SERVER_WITH_GCRYPT},y) CONFIGURE_ARGS+= --with-sha1=libgcrypt -- cgit v1.2.3 From ac21ab9f35317c2c53b22763e340d96f993e9f61 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 7 Sep 2011 10:37:05 +0200 Subject: enable hibernation for lemote yeelong --- target/linux/config/Config.in.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/target/linux/config/Config.in.pm b/target/linux/config/Config.in.pm index 4e35a12b2..7d7dc1f8f 100644 --- a/target/linux/config/Config.in.pm +++ b/target/linux/config/Config.in.pm @@ -23,7 +23,7 @@ config ADK_KERNEL_ACPI_DOCK boolean menu "Power Management support" -depends on ADK_TARGET_WITH_ACPI +depends on ADK_TARGET_WITH_ACPI || ADK_TARGET_SYSTEM_LEMOTE_YEELONG config ADK_HARDWARE_ACPI prompt "Enable ACPI support" @@ -52,6 +52,8 @@ config ADK_KERNEL_SUSPEND default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG + default y if ADK_NATIVE_SYSTEM_LEMOTE_YEELONG default n help Enable Suspend-to-RAM support. @@ -66,6 +68,8 @@ config ADK_KERNEL_HIBERNATION default y if ADK_NATIVE_SYSTEM_INTEL_ATOM default y if ADK_TARGET_SYSTEM_IBM_X40 default y if ADK_NATIVE_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG + default y if ADK_NATIVE_SYSTEM_LEMOTE_YEELONG default n help Enable Suspend-to-Disk support. -- cgit v1.2.3 From f4679aecd7a17d4f3b42282d415e73f0d3a96956 Mon Sep 17 00:00:00 2001 From: Tobias Breckle Date: Thu, 8 Sep 2011 10:57:24 +0200 Subject: added lm_sensors --- package/lm_sensors/Makefile | 64 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 package/lm_sensors/Makefile diff --git a/package/lm_sensors/Makefile b/package/lm_sensors/Makefile new file mode 100644 index 000000000..1c9733e3e --- /dev/null +++ b/package/lm_sensors/Makefile @@ -0,0 +1,64 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include ${TOPDIR}/rules.mk + +PKG_NAME:= lm_sensors +PKG_VERSION:= 3.3.1 +PKG_RELEASE:= 1 +PKG_MD5SUM:= 8c0eebda8524fc87da1393b4564d279b +PKG_DESCR:= linux hw sensor toolset +PKG_DEPENDS:= sysfsutils +PKG_SECTION:= misc +PKG_URL:= http://www.lm-sensors.org +PKG_SITES:= http://dl.lm-sensors.org/lm-sensors/releases/ +DISTFILES:= ${PKG_NAME}-${PKG_VERSION}.tar.bz2 +TARGET_CFLAGS:= ${TARGET_CFLAGS_ARCH} -fwrapv -fno-ident + +PKG_SUBPKGS:= LM_SENSORS LM_SENSORS_DEV LM_SENSORS_DETECT +PKGSD_LM_SENSORS_DEV:= lm_sensors header files +PKGSC_LM_SENSORS_DEV:= devel +PKGSD_LM_SENSORS_DETECT:= lm_sensors perl scripts (e.g. sensors-detect) +PKGSC_LM_SENSORS_DETECT:= misc +PKGSS_LM_SENSORS_DETECT:= perl +PKGSB_LM_SENSORS_DETECT:= perl + + +include ${TOPDIR}/mk/package.mk + +$(eval $(call PKG_template,LM_SENSORS,lm-sensors,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) +$(eval $(call PKG_template,LM_SENSORS_DEV,lm-sensors-dev,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKGSD_LM_SENSORS_DEV},${PKGSC_LM_SENSORS_DEV})) +$(eval $(call PKG_template,LM_SENSORS_DETECT,lm-sensors-detect,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKGSD_LM_SENSORS_DETECT},${PKGSC_LM_SENSORS_DETECT})) + +CONFIG_STYLE:= manual + +do-build: + ${MAKE} -C ${WRKBUILD} \ + ${TARGET_CONFIGURE_OPTS} \ + MACHINE="${CPU_ARCH}" \ + LINUX="${LINUX_DIR}" \ + STAGING_DIR="${STAGING_DIR}" \ + PREFIX="/usr" \ + user + +lm-sensors-install: + ${INSTALL_DIR} ${IDIR_LM_SENSORS}/usr/bin + ${INSTALL_BIN} ${WRKINST}/usr/local/bin/sensors ${IDIR_LM_SENSORS}/usr/bin/sensors + ${INSTALL_DIR} ${IDIR_LM_SENSORS}/usr/lib + ${CP} ${WRKINST}/usr/local/lib/libsensors.so* ${IDIR_LM_SENSORS}/usr/lib + ${INSTALL_DIR} ${IDIR_LM_SENSORS}/etc + ${CP} ${WRKINST}/etc/sensors3.conf ${IDIR_LM_SENSORS}/etc + +lm-sensors-dev-install: + ${INSTALL_DIR} ${IDIR_LM_SENSORS_DEV}/usr/include/sensors + ${CP} ${WRKINST}/usr/local/include/sensors/*.h ${IDIR_LM_SENSORS_DEV}/usr/include/sensors + +lm-sensors-detect-install: + ${INSTALL_DIR} ${IDIR_LM_SENSORS_DETECT}/usr/sbin + ${INSTALL_BIN} ${WRKINST}/usr/local/sbin/fancontrol ${IDIR_LM_SENSORS_DETECT}/usr/sbin/fancontrol + ${INSTALL_BIN} ${WRKINST}/usr/local/sbin/isadump ${IDIR_LM_SENSORS_DETECT}/usr/sbin/isadump + ${INSTALL_BIN} ${WRKINST}/usr/local/sbin/isaset ${IDIR_LM_SENSORS_DETECT}/usr/sbin/isaset + ${INSTALL_BIN} ${WRKINST}/usr/local/sbin/pwmconfig ${IDIR_LM_SENSORS_DETECT}/usr/sbin/pwmconfig + ${INSTALL_BIN} ${WRKINST}/usr/local/sbin/sensors-detect ${IDIR_LM_SENSORS_DETECT}/usr/sbin/sensors-detect + +include ${TOPDIR}/mk/pkg-bottom.mk -- cgit v1.2.3 From d6ce7a9b7c34b166d5e7e69aa840f628add622b4 Mon Sep 17 00:00:00 2001 From: Tobias Breckle Date: Thu, 8 Sep 2011 10:57:37 +0200 Subject: added log4cxx --- package/log4cxx/Makefile | 37 ++++++++++++++++++++++ package/log4cxx/patches/patch-src_Makefile_am | 8 +++++ package/log4cxx/patches/patch-src_Makefile_in | 11 +++++++ .../patches/patch-src_examples_cpp_console_cpp | 11 +++++++ .../patch-src_main_cpp_inputstreamreader_cpp | 10 ++++++ .../patch-src_main_cpp_socketoutputstream_cpp | 10 ++++++ 6 files changed, 87 insertions(+) create mode 100644 package/log4cxx/Makefile create mode 100644 package/log4cxx/patches/patch-src_Makefile_am create mode 100644 package/log4cxx/patches/patch-src_Makefile_in create mode 100644 package/log4cxx/patches/patch-src_examples_cpp_console_cpp create mode 100644 package/log4cxx/patches/patch-src_main_cpp_inputstreamreader_cpp create mode 100644 package/log4cxx/patches/patch-src_main_cpp_socketoutputstream_cpp diff --git a/package/log4cxx/Makefile b/package/log4cxx/Makefile new file mode 100644 index 000000000..c65fe0b84 --- /dev/null +++ b/package/log4cxx/Makefile @@ -0,0 +1,37 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include ${TOPDIR}/rules.mk + +PKG_NAME:= log4cxx +PKG_VERSION:= 0.10.0 +PKG_RELEASE:= 1 +PKG_MD5SUM:= b30ffb8da3665178e68940ff7a61084c +PKG_DESCR:= Apache logging framework for C++ +PKG_SECTION:= libs +PKG_DEPENDS:= apr apr-util +PKG_BUILDDEP:= apr apr-util +PKG_URL:= http://logging.apache.org/log4cxx/ +PKG_SITES:= http://www.apache.org/dist/logging/log4cxx/0.10.0/ +DISTFILES:= apache-${PKG_NAME}-${PKG_VERSION}.tar.gz +WRKDIST= ${WRKDIR}/apache-${PKG_NAME}-${PKG_VERSION} + +PKG_SUBPKGS:= LOG4CXX LOG4CXX_DEV +PKGSD_LOG4CXX_DEV:= log4cxx development headers +PKGSC_LOG4CXX_DEV:= devel + +include ${TOPDIR}/mk/package.mk + +$(eval $(call PKG_template,LOG4CXX,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) +$(eval $(call PKG_template,LOG4CXX_DEV,${PKG_NAME}_dev,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKGSD_LOG4CXX_DEV},${PKGSC_LOG4CXX_DEV})) + +log4cxx-install: + ${INSTALL_DIR} ${IDIR_LOG4CXX}/usr/lib + ${CP} ${WRKINST}/usr/lib/*.a ${IDIR_LOG4CXX}/usr/lib + ${CP} ${WRKINST}/usr/lib/*.so* ${IDIR_LOG4CXX}/usr/lib + +log4cxx_dev-install: + ${INSTALL_DIR} ${IDIR_LOG4CXX_DEV}/usr/include + ${CP} ${WRKINST}/usr/include/* ${IDIR_LOG4CXX_DEV}/usr/include + +include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/log4cxx/patches/patch-src_Makefile_am b/package/log4cxx/patches/patch-src_Makefile_am new file mode 100644 index 000000000..339a18eeb --- /dev/null +++ b/package/log4cxx/patches/patch-src_Makefile_am @@ -0,0 +1,8 @@ +--- apache-log4cxx-0.10.0.orig/src/Makefile.am 2008-04-01 00:34:52.000000000 +0200 ++++ apache-log4cxx-0.10.0/src/Makefile.am 2011-09-08 09:41:19.679507959 +0200 +@@ -13,4 +13,4 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + # +-SUBDIRS = main examples site test ++SUBDIRS = main diff --git a/package/log4cxx/patches/patch-src_Makefile_in b/package/log4cxx/patches/patch-src_Makefile_in new file mode 100644 index 000000000..da14caed3 --- /dev/null +++ b/package/log4cxx/patches/patch-src_Makefile_in @@ -0,0 +1,11 @@ +--- apache-log4cxx-0.10.0.orig/src/Makefile.in 2008-04-01 00:44:12.000000000 +0200 ++++ apache-log4cxx-0.10.0/src/Makefile.in 2011-09-08 10:16:06.139506556 +0200 +@@ -209,7 +209,7 @@ target_vendor = @target_vendor@ + # See the License for the specific language governing permissions and + # limitations under the License. + # +-SUBDIRS = main examples site test ++SUBDIRS = main + all: all-recursive + + .SUFFIXES: diff --git a/package/log4cxx/patches/patch-src_examples_cpp_console_cpp b/package/log4cxx/patches/patch-src_examples_cpp_console_cpp new file mode 100644 index 000000000..da948e211 --- /dev/null +++ b/package/log4cxx/patches/patch-src_examples_cpp_console_cpp @@ -0,0 +1,11 @@ +--- apache-log4cxx-0.10.0.orig/src/examples/cpp/console.cpp 2008-04-01 00:34:52.000000000 +0200 ++++ apache-log4cxx-0.10.0/src/examples/cpp/console.cpp 2011-09-08 09:33:04.799508250 +0200 +@@ -16,6 +16,8 @@ + */ + + #include ++#include ++#include + #include + #include + #include diff --git a/package/log4cxx/patches/patch-src_main_cpp_inputstreamreader_cpp b/package/log4cxx/patches/patch-src_main_cpp_inputstreamreader_cpp new file mode 100644 index 000000000..3768a2f6b --- /dev/null +++ b/package/log4cxx/patches/patch-src_main_cpp_inputstreamreader_cpp @@ -0,0 +1,10 @@ +--- apache-log4cxx-0.10.0.orig/src/main/cpp/inputstreamreader.cpp 2008-04-01 00:34:09.000000000 +0200 ++++ apache-log4cxx-0.10.0/src/main/cpp/inputstreamreader.cpp 2011-09-08 09:33:04.799508250 +0200 +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + using namespace log4cxx; + using namespace log4cxx::helpers; diff --git a/package/log4cxx/patches/patch-src_main_cpp_socketoutputstream_cpp b/package/log4cxx/patches/patch-src_main_cpp_socketoutputstream_cpp new file mode 100644 index 000000000..bc19643b2 --- /dev/null +++ b/package/log4cxx/patches/patch-src_main_cpp_socketoutputstream_cpp @@ -0,0 +1,10 @@ +--- apache-log4cxx-0.10.0.orig/src/main/cpp/socketoutputstream.cpp 2008-04-01 00:34:09.000000000 +0200 ++++ apache-log4cxx-0.10.0/src/main/cpp/socketoutputstream.cpp 2011-09-08 09:33:04.799508250 +0200 +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + using namespace log4cxx; + using namespace log4cxx::helpers; -- cgit v1.2.3