Index: target/linux/atheros/patches-2.6.34/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch
===================================================================
--- target/linux/atheros/patches-2.6.34/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
+++ target/linux/atheros/patches-2.6.34/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
@@ -0,0 +1,575 @@
+diff -urN a/arch/mips/ar231x/ar2315.c b/arch/mips/ar231x/ar2315.c
+--- a/arch/mips/ar231x/ar2315.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/ar2315.c	2010-10-24 15:42:23.673791281 +0700
+@@ -22,7 +22,6 @@
+ #include <linux/kernel.h>
+ #include <linux/reboot.h>
+ #include <linux/delay.h>
+-#include <linux/leds.h>
+ #include <asm/bootinfo.h>
+ #include <asm/reboot.h>
+ #include <asm/time.h>
+@@ -481,52 +480,6 @@
+ 	return (u8 *) ar2315_spiflash_res[0].end + 1;
+ }
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar2315_leds[6];
+-static struct gpio_led_platform_data ar2315_led_data = {
+-	.leds = (void *) ar2315_leds,
+-};
+-
+-static struct platform_device ar2315_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev = {
+-		.platform_data = (void *) &ar2315_led_data,
+-	}
+-};
+-
+-static void __init
+-ar2315_init_gpio(void)
+-{
+-	static char led_names[6][6];
+-	int i, led = 0;
+-
+-	ar2315_led_data.num_leds = 0;
+-	for(i = 1; i < 8; i++)
+-	{
+-		if((i == AR2315_RESET_GPIO) ||
+-		   (i == ar231x_board.config->resetConfigGpio))
+-			continue;
+-
+-		if(i == ar231x_board.config->sysLedGpio)
+-			strcpy(led_names[led], "wlan");
+-		else
+-			sprintf(led_names[led], "gpio%d", i);
+-
+-		ar2315_leds[led].name = led_names[led];
+-		ar2315_leds[led].gpio = i;
+-		ar2315_leds[led].active_low = 0;
+-		led++;
+-	}
+-	ar2315_led_data.num_leds = led;
+-	platform_device_register(&ar2315_gpio_leds);
+-}
+-#else
+-static inline void ar2315_init_gpio(void)
+-{
+-}
+-#endif
+-
+ int __init
+ ar2315_init_devices(void)
+ {
+@@ -537,7 +490,6 @@
+ 	ar231x_find_config(ar2315_flash_limit());
+ 	ar2315_eth_data.macaddr = ar231x_board.config->enet0_mac;
+ 
+-	ar2315_init_gpio();
+ 	platform_device_register(&ar2315_wdt);
+ 	platform_device_register(&ar2315_spiflash);
+ 	ar231x_add_ethernet(0, AR2315_ENET0, AR2315_IRQ_ENET0_INTRS,
+diff -urN a/arch/mips/ar231x/ar5312.c b/arch/mips/ar231x/ar5312.c
+--- a/arch/mips/ar231x/ar5312.c	2010-10-24 15:33:03.865423290 +0700
++++ b/arch/mips/ar231x/ar5312.c	2010-10-24 15:08:48.354041241 +0700
+@@ -245,23 +245,6 @@
+ 	.num_resources = 1,
+ };
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar5312_leds[] = {
+-	{ .name = "wlan", .gpio = 0, .active_low = 1, },
+-};
+-
+-static const struct gpio_led_platform_data ar5312_led_data = {
+-	.num_leds = ARRAY_SIZE(ar5312_leds),
+-	.leds = (void *) ar5312_leds,
+-};
+-
+-static struct platform_device ar5312_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev.platform_data = (void *) &ar5312_led_data,
+-};
+-#endif
+-
+ /*
+  * NB: This mapping size is larger than the actual flash size,
+  * but this shouldn't be a problem here, because the flash
+@@ -350,11 +333,6 @@
+ 
+ 	platform_device_register(&ar5312_physmap_flash);
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-	ar5312_leds[0].gpio = config->sysLedGpio;
+-	platform_device_register(&ar5312_gpio_leds);
+-#endif
+-
+ 	/* Fix up MAC addresses if necessary */
+ 	if (!memcmp(config->enet0_mac, "\xff\xff\xff\xff\xff\xff", 6))
+ 		memcpy(config->enet0_mac, config->enet1_mac, 6);
+diff -urN a/arch/mips/ar231x/devices.c b/arch/mips/ar231x/devices.c
+--- a/arch/mips/ar231x/devices.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/devices.c	2010-10-24 20:48:48.011645424 +0700
+@@ -1,14 +1,31 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ #include <linux/serial.h>
+ #include <linux/serial_core.h>
+ #include <linux/serial_8250.h>
+ #include <linux/platform_device.h>
+ #include <ar231x_platform.h>
+ #include <ar231x.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
+ #include "devices.h"
+ #include "ar5312.h"
+ #include "ar2315.h"
++#include "machtype.h"
++#include "gpio.h"
+ 
+ struct ar231x_board_config ar231x_board;
+ int ar231x_devtype = DEV_TYPE_UNKNOWN;
+@@ -159,6 +176,38 @@
+ 	return platform_device_register(&ar231x_wmac[nr]);
+ }
+ 
++static int board_init = 0;
++
++static void __init
++ar231x_set_default_mach(void)
++{
++        mips_machtype = AR231X_MACH_GENERIC;
++}
++
++static int __init
++ar231x_machtype_setup(char *board)
++{
++	int machtype  = mips_machtype_setup(board);
++	/* Use generic if board not detected */
++	if (machtype) {
++		ar231x_set_default_mach();
++	}
++	board_init = 1;
++
++	return 0;
++}
++
++__setup("board=", ar231x_machtype_setup);
++
++int __init
++ar231x_machine_setup(void)
++{
++	if (!board_init) ar231x_set_default_mach();
++	mips_machine_setup();
++
++	return 0;
++}
++
+ static int __init ar231x_register_devices(void)
+ {
+ 	static struct resource res = {
+@@ -169,7 +218,39 @@
+ 	ar5312_init_devices();
+ 	ar2315_init_devices();
+ 
++	ar231x_machine_setup();
++	ar231x_register_gpio();
++
+ 	return 0;
+ }
+ 
+ device_initcall(ar231x_register_devices);
++
++void __init
++ar231x_generic_gpio_setup(void)
++{
++#ifdef CONFIG_LEDS_GPIO
++#define LED_NAME_SZ 7
++	int i, n;
++        char *led_name;
++        n = is_2315() ? AR2315_NUM_GPIO : AR531X_NUM_GPIO;
++
++        for (i = 1; i <= n; i++)
++        {
++                if((i == AR2315_RESET_GPIO && is_2315()) ||
++                   (i == ar231x_board.config->resetConfigGpio))
++                        continue;
++
++                led_name = (char *) kmalloc(LED_NAME_SZ, GFP_KERNEL);
++		if(led_name == NULL) continue;
++		if(i == ar231x_board.config->sysLedGpio)
++                        strcpy(led_name, "wlan");
++                else
++                        sprintf(led_name, "gpio%d", i);
++                ar231x_add_led(led_name, i);
++        }
++#endif
++}
++
++MIPS_MACHINE(AR231X_MACH_GENERIC, "GENERIC", "Atheros AR231X Generic Board",
++                ar231x_generic_gpio_setup);
+diff -urN a/arch/mips/ar231x/gpio.c b/arch/mips/ar231x/gpio.c
+--- a/arch/mips/ar231x/gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.c	2010-10-24 22:20:32.859506793 +0700
+@@ -0,0 +1,167 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/leds.h>
++#include <linux/gpio_buttons.h>
++#include <linux/input.h>
++#include <ar231x_platform.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
++
++#include "devices.h"
++
++#define AR231X_MAX_LEDS 6 
++
++static struct gpio_led ar231x_leds[AR231X_MAX_LEDS];
++static int led = 0, led_default_active_low = 0;
++
++void __init
++ar231x_set_led_default_active_low(int active_low)
++{
++	led_default_active_low = active_low;
++}
++
++void __init
++ar231x_add_led(char *name, int gpio)
++{
++        if (led >= AR231X_MAX_LEDS) return;
++        ar231x_leds[led].name = name;
++        ar231x_leds[led].gpio = gpio;
++        ar231x_leds[led].active_low = led_default_active_low;
++        led++;
++}
++
++void __init
++ar231x_register_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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_leds:
++        kfree(p);
++}
++
++#define AR231X_MAX_BUTTONS              2
++#define AR231X_BUTTONS_POLL_INTERVAL    20
++
++static struct gpio_button ar231x_buttons[AR231X_MAX_BUTTONS];
++static int button = 0, button_default_threshold = 3, button_default_active_low = 0;
++
++void __init
++ar231x_set_button_default_active_low(int active_low)
++{
++	button_default_active_low = active_low;
++}
++
++void __init
++ar231x_set_button_default_threshold(int threshold)
++{
++	button_default_threshold = threshold;
++}
++
++void __init
++ar231x_add_button(char *desc, int code, int gpio)
++{
++        if (button >= AR231X_MAX_BUTTONS) return;
++        ar231x_buttons[button].desc = desc;
++        ar231x_buttons[button].type = EV_KEY;
++        ar231x_buttons[button].code = code;
++        ar231x_buttons[button].gpio = gpio;
++        ar231x_buttons[button].threshold = button_default_threshold;
++        ar231x_buttons[button].active_low = button_default_active_low;
++        button++;
++}
++
++void __init
++ar231x_register_gpio_buttons(int id, unsigned poll_interval, unsigned nbuttons,
++		struct gpio_button *buttons)
++{
++        struct platform_device *pdev;
++        struct gpio_buttons_platform_data pdata;
++        struct gpio_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-buttons", id);
++        if (!pdev)
++                goto err_free_buttons;
++
++        memset(&pdata, 0, sizeof(pdata));
++        pdata.poll_interval = poll_interval;
++        pdata.nbuttons = nbuttons;
++        pdata.buttons = 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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_buttons:
++        kfree(p);
++}
++
++void __init
++ar231x_register_gpio(void)
++{
++        if (button) {
++                ar231x_register_gpio_buttons(-1, AR231X_BUTTONS_POLL_INTERVAL, button, ar231x_buttons);
++        }
++        if (led) {
++		ar231x_register_leds_gpio(-1, led, ar231x_leds);
++        }
++}
+diff -urN a/arch/mips/ar231x/gpio.h b/arch/mips/ar231x/gpio.h
+--- a/arch/mips/ar231x/gpio.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.h	2010-10-24 21:01:53.108447507 +0700
+@@ -0,0 +1,25 @@
++#ifndef __GPIO_H
++#define __GPIO_H
++
++#ifdef CONFIG_ATHEROS_AR231X_GPIO
++
++extern void ar231x_register_gpio(void);
++extern void ar231x_set_led_default_active_low(int active_low);
++extern void ar231x_add_led(char *name, int gpio);
++extern void ar231x_set_button_default_active_low(int active_low);
++extern void ar231x_set_button_default_threshold(int threshold);
++extern void ar231x_add_button(char *desc, int code, int gpio);
++
++#else
++
++static inline void ar231x_register_gpio(void) {}
++static inline void ar231x_set_led_default_active_low(int active_low) {}
++static inline void ar231x_add_led(char *name, int gpio) {}
++static inline void ar231x_set_button_default_active_low(int active_low) {}
++static inline void ar231x_set_button_default_threshold(int threshold) {}
++static inline void ar231x_add_button(char *desc, int code, int gpio) {}
++
++#endif
++
++
++#endif
+diff -urN a/arch/mips/ar231x/Kconfig b/arch/mips/ar231x/Kconfig
+--- a/arch/mips/ar231x/Kconfig	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/Kconfig	2010-10-24 21:10:13.655611973 +0700
+@@ -25,3 +25,13 @@
+ 	select USB_ARCH_HAS_OHCI
+ 	select USB_ARCH_HAS_EHCI
+ 	default y
++
++config ATHEROS_AR231X_GPIO
++	bool "Atheros 231X GPIO support"
++	depends on ATHEROS_AR231X
++	default y
++
++config ATHEROS_AR231X_MACH_DIR_300_A1
++	bool "D-LINK DIR-300 rev. A1 GPIO support"
++	depends on ATHEROS_AR231X
++	default n
+diff -urN a/arch/mips/ar231x/mach-dir-300-a1-gpio.c b/arch/mips/ar231x/mach-dir-300-a1-gpio.c
+--- a/arch/mips/ar231x/mach-dir-300-a1-gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/mach-dir-300-a1-gpio.c	2010-10-24 15:08:48.345675857 +0700
+@@ -0,0 +1,36 @@
++/*
++ *  D-Link DIR-300 rev. A1 GPIO support
++ *
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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/input.h>
++#include "machtype.h"
++#include "gpio.h"
++
++#define DIR_300_A1_GPIO_LED_SYSTEM	7
++#define DIR_300_A1_GPIO_LED_WLAN	2
++#define DIR_300_A1_GPIO_LED_WPS_BLUE	1
++#define DIR_300_A1_GPIO_LED_WPS_RED	3
++
++#define DIR_300_A1_GPIO_BUTTON_RESET	6
++#define DIR_300_A1_GPIO_BUTTON_WPS	4
++
++static void __init dir_300_a1_gpio_setup(void)
++{
++	ar231x_add_button("reset", KEY_RESTART, DIR_300_A1_GPIO_BUTTON_RESET);
++	ar231x_add_button("wps", KEY_WPS_BUTTON, DIR_300_A1_GPIO_BUTTON_WPS);
++	
++	ar231x_add_led("dir300:green:system", DIR_300_A1_GPIO_LED_SYSTEM);
++	ar231x_add_led("dir300:green:wlan", DIR_300_A1_GPIO_LED_WLAN);
++	ar231x_add_led("dir300:blue:wps", DIR_300_A1_GPIO_LED_WPS_BLUE);
++	ar231x_add_led("dir300:red:wps", DIR_300_A1_GPIO_LED_WPS_RED);
++}
++
++MIPS_MACHINE(AR231X_MACH_DIR_300_A1, "DIR-300-A1", "D-Link DIR-300 rev. A1",
++	     dir_300_a1_gpio_setup);
+diff -urN a/arch/mips/ar231x/machtype.h b/arch/mips/ar231x/machtype.h
+--- a/arch/mips/ar231x/machtype.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/machtype.h	2010-10-24 15:08:48.354041241 +0700
+@@ -0,0 +1,23 @@
++/*
++ *  Atheros AR231X machine type definitions
++ *
++ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
++ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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 _AR231X_MACHTYPE_H
++#define _AR231X_MACHTYPE_H
++
++#include <asm/mips_machine.h>
++
++enum ar231x_mach_type {
++	AR231X_MACH_GENERIC = 0,
++	AR231X_MACH_DIR_300_A1,	/* D-Link DIR-300 rev. A1 */
++};
++
++#endif /* _AR231X_MACHTYPE_H */
+diff -urN a/arch/mips/ar231x/Makefile b/arch/mips/ar231x/Makefile
+--- a/arch/mips/ar231x/Makefile	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/Makefile	2010-10-24 20:59:31.735693794 +0700
+@@ -15,3 +15,5 @@
+ obj-$(CONFIG_ATHEROS_AR5312) += ar5312.o
+ obj-$(CONFIG_ATHEROS_AR2315) += ar2315.o
+ obj-$(CONFIG_ATHEROS_AR2315_PCI) += pci.o
++obj-$(CONFIG_ATHEROS_AR231X_GPIO) += gpio.o
++obj-$(CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1) += mach-dir-300-a1-gpio.o
+diff -urN a/arch/mips/ar231x/prom.c b/arch/mips/ar231x/prom.c
+--- a/arch/mips/ar231x/prom.c	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/prom.c	2010-10-24 23:38:31.312244791 +0700
+@@ -26,8 +26,42 @@
+ #include "ar5312.h"
+ #include "ar2315.h"
+ 
++#ifdef CONFIG_IMAGE_CMDLINE_HACK
++extern char __image_cmdline[];
++
++static int __init ar231x_use__image_cmdline(void)
++{
++        char *p = __image_cmdline;
++        int replace = 0;
++
++        if (*p == '-') {
++                replace = 1;
++                p++;
++        }
++
++        if (*p == '\0')
++                return 0;
++
++	if (strlen(arcs_cmdline) == 0)
++		replace = 1;
++
++        if (replace) {
++                strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline));
++        } else {
++                strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
++                strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
++        }
++
++        return 1;
++}
++#else
++static int inline ar231x_use__image_cmdline(void) { return 0; }
++#endif
++
+ void __init prom_init(void)
+ {
++	ar231x_use__image_cmdline();
++
+ 	ar5312_prom_init();
+ 	ar2315_prom_init();
+ }
+diff -urN a/arch/mips/Kconfig b/arch/mips/Kconfig
+--- a/arch/mips/Kconfig	2010-10-24 15:33:04.157474056 +0700
++++ b/arch/mips/Kconfig	2010-10-24 15:08:48.681423282 +0700
+@@ -95,6 +95,7 @@
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select GENERIC_GPIO
+ 	select SYS_HAS_EARLY_PRINTK
++	select MIPS_MACHINE
+ 	help
+ 	  Support for AR231x and AR531x based boards
+ 
Index: target/linux/atheros/patches-2.6.35/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch
===================================================================
--- target/linux/atheros/patches-2.6.35/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
+++ target/linux/atheros/patches-2.6.35/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
@@ -0,0 +1,575 @@
+diff -urN a/arch/mips/ar231x/ar2315.c b/arch/mips/ar231x/ar2315.c
+--- a/arch/mips/ar231x/ar2315.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/ar2315.c	2010-10-24 15:42:23.673791281 +0700
+@@ -22,7 +22,6 @@
+ #include <linux/kernel.h>
+ #include <linux/reboot.h>
+ #include <linux/delay.h>
+-#include <linux/leds.h>
+ #include <asm/bootinfo.h>
+ #include <asm/reboot.h>
+ #include <asm/time.h>
+@@ -481,52 +480,6 @@
+ 	return (u8 *) ar2315_spiflash_res[0].end + 1;
+ }
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar2315_leds[6];
+-static struct gpio_led_platform_data ar2315_led_data = {
+-	.leds = (void *) ar2315_leds,
+-};
+-
+-static struct platform_device ar2315_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev = {
+-		.platform_data = (void *) &ar2315_led_data,
+-	}
+-};
+-
+-static void __init
+-ar2315_init_gpio(void)
+-{
+-	static char led_names[6][6];
+-	int i, led = 0;
+-
+-	ar2315_led_data.num_leds = 0;
+-	for(i = 1; i < 8; i++)
+-	{
+-		if((i == AR2315_RESET_GPIO) ||
+-		   (i == ar231x_board.config->resetConfigGpio))
+-			continue;
+-
+-		if(i == ar231x_board.config->sysLedGpio)
+-			strcpy(led_names[led], "wlan");
+-		else
+-			sprintf(led_names[led], "gpio%d", i);
+-
+-		ar2315_leds[led].name = led_names[led];
+-		ar2315_leds[led].gpio = i;
+-		ar2315_leds[led].active_low = 0;
+-		led++;
+-	}
+-	ar2315_led_data.num_leds = led;
+-	platform_device_register(&ar2315_gpio_leds);
+-}
+-#else
+-static inline void ar2315_init_gpio(void)
+-{
+-}
+-#endif
+-
+ int __init
+ ar2315_init_devices(void)
+ {
+@@ -537,7 +490,6 @@
+ 	ar231x_find_config(ar2315_flash_limit());
+ 	ar2315_eth_data.macaddr = ar231x_board.config->enet0_mac;
+ 
+-	ar2315_init_gpio();
+ 	platform_device_register(&ar2315_wdt);
+ 	platform_device_register(&ar2315_spiflash);
+ 	ar231x_add_ethernet(0, AR2315_ENET0, AR2315_IRQ_ENET0_INTRS,
+diff -urN a/arch/mips/ar231x/ar5312.c b/arch/mips/ar231x/ar5312.c
+--- a/arch/mips/ar231x/ar5312.c	2010-10-24 15:33:03.865423290 +0700
++++ b/arch/mips/ar231x/ar5312.c	2010-10-24 15:08:48.354041241 +0700
+@@ -245,23 +245,6 @@
+ 	.num_resources = 1,
+ };
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar5312_leds[] = {
+-	{ .name = "wlan", .gpio = 0, .active_low = 1, },
+-};
+-
+-static const struct gpio_led_platform_data ar5312_led_data = {
+-	.num_leds = ARRAY_SIZE(ar5312_leds),
+-	.leds = (void *) ar5312_leds,
+-};
+-
+-static struct platform_device ar5312_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev.platform_data = (void *) &ar5312_led_data,
+-};
+-#endif
+-
+ /*
+  * NB: This mapping size is larger than the actual flash size,
+  * but this shouldn't be a problem here, because the flash
+@@ -350,11 +333,6 @@
+ 
+ 	platform_device_register(&ar5312_physmap_flash);
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-	ar5312_leds[0].gpio = config->sysLedGpio;
+-	platform_device_register(&ar5312_gpio_leds);
+-#endif
+-
+ 	/* Fix up MAC addresses if necessary */
+ 	if (!memcmp(config->enet0_mac, "\xff\xff\xff\xff\xff\xff", 6))
+ 		memcpy(config->enet0_mac, config->enet1_mac, 6);
+diff -urN a/arch/mips/ar231x/devices.c b/arch/mips/ar231x/devices.c
+--- a/arch/mips/ar231x/devices.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/devices.c	2010-10-24 20:48:48.011645424 +0700
+@@ -1,14 +1,31 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ #include <linux/serial.h>
+ #include <linux/serial_core.h>
+ #include <linux/serial_8250.h>
+ #include <linux/platform_device.h>
+ #include <ar231x_platform.h>
+ #include <ar231x.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
+ #include "devices.h"
+ #include "ar5312.h"
+ #include "ar2315.h"
++#include "machtype.h"
++#include "gpio.h"
+ 
+ struct ar231x_board_config ar231x_board;
+ int ar231x_devtype = DEV_TYPE_UNKNOWN;
+@@ -159,6 +176,38 @@
+ 	return platform_device_register(&ar231x_wmac[nr]);
+ }
+ 
++static int board_init = 0;
++
++static void __init
++ar231x_set_default_mach(void)
++{
++        mips_machtype = AR231X_MACH_GENERIC;
++}
++
++static int __init
++ar231x_machtype_setup(char *board)
++{
++	int machtype  = mips_machtype_setup(board);
++	/* Use generic if board not detected */
++	if (machtype) {
++		ar231x_set_default_mach();
++	}
++	board_init = 1;
++
++	return 0;
++}
++
++__setup("board=", ar231x_machtype_setup);
++
++int __init
++ar231x_machine_setup(void)
++{
++	if (!board_init) ar231x_set_default_mach();
++	mips_machine_setup();
++
++	return 0;
++}
++
+ static int __init ar231x_register_devices(void)
+ {
+ 	static struct resource res = {
+@@ -169,7 +218,39 @@
+ 	ar5312_init_devices();
+ 	ar2315_init_devices();
+ 
++	ar231x_machine_setup();
++	ar231x_register_gpio();
++
+ 	return 0;
+ }
+ 
+ device_initcall(ar231x_register_devices);
++
++void __init
++ar231x_generic_gpio_setup(void)
++{
++#ifdef CONFIG_LEDS_GPIO
++#define LED_NAME_SZ 7
++	int i, n;
++        char *led_name;
++        n = is_2315() ? AR2315_NUM_GPIO : AR531X_NUM_GPIO;
++
++        for (i = 1; i <= n; i++)
++        {
++                if((i == AR2315_RESET_GPIO && is_2315()) ||
++                   (i == ar231x_board.config->resetConfigGpio))
++                        continue;
++
++                led_name = (char *) kmalloc(LED_NAME_SZ, GFP_KERNEL);
++		if(led_name == NULL) continue;
++		if(i == ar231x_board.config->sysLedGpio)
++                        strcpy(led_name, "wlan");
++                else
++                        sprintf(led_name, "gpio%d", i);
++                ar231x_add_led(led_name, i);
++        }
++#endif
++}
++
++MIPS_MACHINE(AR231X_MACH_GENERIC, "GENERIC", "Atheros AR231X Generic Board",
++                ar231x_generic_gpio_setup);
+diff -urN a/arch/mips/ar231x/gpio.c b/arch/mips/ar231x/gpio.c
+--- a/arch/mips/ar231x/gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.c	2010-10-24 22:20:32.859506793 +0700
+@@ -0,0 +1,167 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/leds.h>
++#include <linux/gpio_buttons.h>
++#include <linux/input.h>
++#include <ar231x_platform.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
++
++#include "devices.h"
++
++#define AR231X_MAX_LEDS 6 
++
++static struct gpio_led ar231x_leds[AR231X_MAX_LEDS];
++static int led = 0, led_default_active_low = 0;
++
++void __init
++ar231x_set_led_default_active_low(int active_low)
++{
++	led_default_active_low = active_low;
++}
++
++void __init
++ar231x_add_led(char *name, int gpio)
++{
++        if (led >= AR231X_MAX_LEDS) return;
++        ar231x_leds[led].name = name;
++        ar231x_leds[led].gpio = gpio;
++        ar231x_leds[led].active_low = led_default_active_low;
++        led++;
++}
++
++void __init
++ar231x_register_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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_leds:
++        kfree(p);
++}
++
++#define AR231X_MAX_BUTTONS              2
++#define AR231X_BUTTONS_POLL_INTERVAL    20
++
++static struct gpio_button ar231x_buttons[AR231X_MAX_BUTTONS];
++static int button = 0, button_default_threshold = 3, button_default_active_low = 0;
++
++void __init
++ar231x_set_button_default_active_low(int active_low)
++{
++	button_default_active_low = active_low;
++}
++
++void __init
++ar231x_set_button_default_threshold(int threshold)
++{
++	button_default_threshold = threshold;
++}
++
++void __init
++ar231x_add_button(char *desc, int code, int gpio)
++{
++        if (button >= AR231X_MAX_BUTTONS) return;
++        ar231x_buttons[button].desc = desc;
++        ar231x_buttons[button].type = EV_KEY;
++        ar231x_buttons[button].code = code;
++        ar231x_buttons[button].gpio = gpio;
++        ar231x_buttons[button].threshold = button_default_threshold;
++        ar231x_buttons[button].active_low = button_default_active_low;
++        button++;
++}
++
++void __init
++ar231x_register_gpio_buttons(int id, unsigned poll_interval, unsigned nbuttons,
++		struct gpio_button *buttons)
++{
++        struct platform_device *pdev;
++        struct gpio_buttons_platform_data pdata;
++        struct gpio_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-buttons", id);
++        if (!pdev)
++                goto err_free_buttons;
++
++        memset(&pdata, 0, sizeof(pdata));
++        pdata.poll_interval = poll_interval;
++        pdata.nbuttons = nbuttons;
++        pdata.buttons = 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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_buttons:
++        kfree(p);
++}
++
++void __init
++ar231x_register_gpio(void)
++{
++        if (button) {
++                ar231x_register_gpio_buttons(-1, AR231X_BUTTONS_POLL_INTERVAL, button, ar231x_buttons);
++        }
++        if (led) {
++		ar231x_register_leds_gpio(-1, led, ar231x_leds);
++        }
++}
+diff -urN a/arch/mips/ar231x/gpio.h b/arch/mips/ar231x/gpio.h
+--- a/arch/mips/ar231x/gpio.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.h	2010-10-24 21:01:53.108447507 +0700
+@@ -0,0 +1,25 @@
++#ifndef __GPIO_H
++#define __GPIO_H
++
++#ifdef CONFIG_ATHEROS_AR231X_GPIO
++
++extern void ar231x_register_gpio(void);
++extern void ar231x_set_led_default_active_low(int active_low);
++extern void ar231x_add_led(char *name, int gpio);
++extern void ar231x_set_button_default_active_low(int active_low);
++extern void ar231x_set_button_default_threshold(int threshold);
++extern void ar231x_add_button(char *desc, int code, int gpio);
++
++#else
++
++static inline void ar231x_register_gpio(void) {}
++static inline void ar231x_set_led_default_active_low(int active_low) {}
++static inline void ar231x_add_led(char *name, int gpio) {}
++static inline void ar231x_set_button_default_active_low(int active_low) {}
++static inline void ar231x_set_button_default_threshold(int threshold) {}
++static inline void ar231x_add_button(char *desc, int code, int gpio) {}
++
++#endif
++
++
++#endif
+diff -urN a/arch/mips/ar231x/Kconfig b/arch/mips/ar231x/Kconfig
+--- a/arch/mips/ar231x/Kconfig	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/Kconfig	2010-10-24 21:10:13.655611973 +0700
+@@ -25,3 +25,13 @@
+ 	select USB_ARCH_HAS_OHCI
+ 	select USB_ARCH_HAS_EHCI
+ 	default y
++
++config ATHEROS_AR231X_GPIO
++	bool "Atheros 231X GPIO support"
++	depends on ATHEROS_AR231X
++	default y
++
++config ATHEROS_AR231X_MACH_DIR_300_A1
++	bool "D-LINK DIR-300 rev. A1 GPIO support"
++	depends on ATHEROS_AR231X
++	default n
+diff -urN a/arch/mips/ar231x/mach-dir-300-a1-gpio.c b/arch/mips/ar231x/mach-dir-300-a1-gpio.c
+--- a/arch/mips/ar231x/mach-dir-300-a1-gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/mach-dir-300-a1-gpio.c	2010-10-24 15:08:48.345675857 +0700
+@@ -0,0 +1,36 @@
++/*
++ *  D-Link DIR-300 rev. A1 GPIO support
++ *
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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/input.h>
++#include "machtype.h"
++#include "gpio.h"
++
++#define DIR_300_A1_GPIO_LED_SYSTEM	7
++#define DIR_300_A1_GPIO_LED_WLAN	2
++#define DIR_300_A1_GPIO_LED_WPS_BLUE	1
++#define DIR_300_A1_GPIO_LED_WPS_RED	3
++
++#define DIR_300_A1_GPIO_BUTTON_RESET	6
++#define DIR_300_A1_GPIO_BUTTON_WPS	4
++
++static void __init dir_300_a1_gpio_setup(void)
++{
++	ar231x_add_button("reset", KEY_RESTART, DIR_300_A1_GPIO_BUTTON_RESET);
++	ar231x_add_button("wps", KEY_WPS_BUTTON, DIR_300_A1_GPIO_BUTTON_WPS);
++	
++	ar231x_add_led("dir300:green:system", DIR_300_A1_GPIO_LED_SYSTEM);
++	ar231x_add_led("dir300:green:wlan", DIR_300_A1_GPIO_LED_WLAN);
++	ar231x_add_led("dir300:blue:wps", DIR_300_A1_GPIO_LED_WPS_BLUE);
++	ar231x_add_led("dir300:red:wps", DIR_300_A1_GPIO_LED_WPS_RED);
++}
++
++MIPS_MACHINE(AR231X_MACH_DIR_300_A1, "DIR-300-A1", "D-Link DIR-300 rev. A1",
++	     dir_300_a1_gpio_setup);
+diff -urN a/arch/mips/ar231x/machtype.h b/arch/mips/ar231x/machtype.h
+--- a/arch/mips/ar231x/machtype.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/machtype.h	2010-10-24 15:08:48.354041241 +0700
+@@ -0,0 +1,23 @@
++/*
++ *  Atheros AR231X machine type definitions
++ *
++ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
++ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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 _AR231X_MACHTYPE_H
++#define _AR231X_MACHTYPE_H
++
++#include <asm/mips_machine.h>
++
++enum ar231x_mach_type {
++	AR231X_MACH_GENERIC = 0,
++	AR231X_MACH_DIR_300_A1,	/* D-Link DIR-300 rev. A1 */
++};
++
++#endif /* _AR231X_MACHTYPE_H */
+diff -urN a/arch/mips/ar231x/Makefile b/arch/mips/ar231x/Makefile
+--- a/arch/mips/ar231x/Makefile	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/Makefile	2010-10-24 20:59:31.735693794 +0700
+@@ -15,3 +15,5 @@
+ obj-$(CONFIG_ATHEROS_AR5312) += ar5312.o
+ obj-$(CONFIG_ATHEROS_AR2315) += ar2315.o
+ obj-$(CONFIG_ATHEROS_AR2315_PCI) += pci.o
++obj-$(CONFIG_ATHEROS_AR231X_GPIO) += gpio.o
++obj-$(CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1) += mach-dir-300-a1-gpio.o
+diff -urN a/arch/mips/ar231x/prom.c b/arch/mips/ar231x/prom.c
+--- a/arch/mips/ar231x/prom.c	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/prom.c	2010-10-24 23:38:31.312244791 +0700
+@@ -26,8 +26,42 @@
+ #include "ar5312.h"
+ #include "ar2315.h"
+ 
++#ifdef CONFIG_IMAGE_CMDLINE_HACK
++extern char __image_cmdline[];
++
++static int __init ar231x_use__image_cmdline(void)
++{
++        char *p = __image_cmdline;
++        int replace = 0;
++
++        if (*p == '-') {
++                replace = 1;
++                p++;
++        }
++
++        if (*p == '\0')
++                return 0;
++
++	if (strlen(arcs_cmdline) == 0)
++		replace = 1;
++
++        if (replace) {
++                strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline));
++        } else {
++                strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
++                strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
++        }
++
++        return 1;
++}
++#else
++static int inline ar231x_use__image_cmdline(void) { return 0; }
++#endif
++
+ void __init prom_init(void)
+ {
++	ar231x_use__image_cmdline();
++
+ 	ar5312_prom_init();
+ 	ar2315_prom_init();
+ }
+diff -urN a/arch/mips/Kconfig b/arch/mips/Kconfig
+--- a/arch/mips/Kconfig	2010-10-24 15:33:04.157474056 +0700
++++ b/arch/mips/Kconfig	2010-10-24 15:08:48.681423282 +0700
+@@ -95,6 +95,7 @@
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select GENERIC_GPIO
+ 	select SYS_HAS_EARLY_PRINTK
++	select MIPS_MACHINE
+ 	help
+ 	  Support for AR231x and AR531x based boards
+ 
Index: target/linux/atheros/patches-2.6.36/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch
===================================================================
--- target/linux/atheros/patches-2.6.36/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
+++ target/linux/atheros/patches-2.6.36/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
@@ -0,0 +1,575 @@
+diff -urN a/arch/mips/ar231x/ar2315.c b/arch/mips/ar231x/ar2315.c
+--- a/arch/mips/ar231x/ar2315.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/ar2315.c	2010-10-24 15:42:23.673791281 +0700
+@@ -22,7 +22,6 @@
+ #include <linux/kernel.h>
+ #include <linux/reboot.h>
+ #include <linux/delay.h>
+-#include <linux/leds.h>
+ #include <asm/bootinfo.h>
+ #include <asm/reboot.h>
+ #include <asm/time.h>
+@@ -481,52 +480,6 @@
+ 	return (u8 *) ar2315_spiflash_res[0].end + 1;
+ }
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar2315_leds[6];
+-static struct gpio_led_platform_data ar2315_led_data = {
+-	.leds = (void *) ar2315_leds,
+-};
+-
+-static struct platform_device ar2315_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev = {
+-		.platform_data = (void *) &ar2315_led_data,
+-	}
+-};
+-
+-static void __init
+-ar2315_init_gpio(void)
+-{
+-	static char led_names[6][6];
+-	int i, led = 0;
+-
+-	ar2315_led_data.num_leds = 0;
+-	for(i = 1; i < 8; i++)
+-	{
+-		if((i == AR2315_RESET_GPIO) ||
+-		   (i == ar231x_board.config->resetConfigGpio))
+-			continue;
+-
+-		if(i == ar231x_board.config->sysLedGpio)
+-			strcpy(led_names[led], "wlan");
+-		else
+-			sprintf(led_names[led], "gpio%d", i);
+-
+-		ar2315_leds[led].name = led_names[led];
+-		ar2315_leds[led].gpio = i;
+-		ar2315_leds[led].active_low = 0;
+-		led++;
+-	}
+-	ar2315_led_data.num_leds = led;
+-	platform_device_register(&ar2315_gpio_leds);
+-}
+-#else
+-static inline void ar2315_init_gpio(void)
+-{
+-}
+-#endif
+-
+ int __init
+ ar2315_init_devices(void)
+ {
+@@ -537,7 +490,6 @@
+ 	ar231x_find_config(ar2315_flash_limit());
+ 	ar2315_eth_data.macaddr = ar231x_board.config->enet0_mac;
+ 
+-	ar2315_init_gpio();
+ 	platform_device_register(&ar2315_wdt);
+ 	platform_device_register(&ar2315_spiflash);
+ 	ar231x_add_ethernet(0, AR2315_ENET0, AR2315_IRQ_ENET0_INTRS,
+diff -urN a/arch/mips/ar231x/ar5312.c b/arch/mips/ar231x/ar5312.c
+--- a/arch/mips/ar231x/ar5312.c	2010-10-24 15:33:03.865423290 +0700
++++ b/arch/mips/ar231x/ar5312.c	2010-10-24 15:08:48.354041241 +0700
+@@ -245,23 +245,6 @@
+ 	.num_resources = 1,
+ };
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar5312_leds[] = {
+-	{ .name = "wlan", .gpio = 0, .active_low = 1, },
+-};
+-
+-static const struct gpio_led_platform_data ar5312_led_data = {
+-	.num_leds = ARRAY_SIZE(ar5312_leds),
+-	.leds = (void *) ar5312_leds,
+-};
+-
+-static struct platform_device ar5312_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev.platform_data = (void *) &ar5312_led_data,
+-};
+-#endif
+-
+ /*
+  * NB: This mapping size is larger than the actual flash size,
+  * but this shouldn't be a problem here, because the flash
+@@ -350,11 +333,6 @@
+ 
+ 	platform_device_register(&ar5312_physmap_flash);
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-	ar5312_leds[0].gpio = config->sysLedGpio;
+-	platform_device_register(&ar5312_gpio_leds);
+-#endif
+-
+ 	/* Fix up MAC addresses if necessary */
+ 	if (!memcmp(config->enet0_mac, "\xff\xff\xff\xff\xff\xff", 6))
+ 		memcpy(config->enet0_mac, config->enet1_mac, 6);
+diff -urN a/arch/mips/ar231x/devices.c b/arch/mips/ar231x/devices.c
+--- a/arch/mips/ar231x/devices.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/devices.c	2010-10-24 20:48:48.011645424 +0700
+@@ -1,14 +1,31 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ #include <linux/serial.h>
+ #include <linux/serial_core.h>
+ #include <linux/serial_8250.h>
+ #include <linux/platform_device.h>
+ #include <ar231x_platform.h>
+ #include <ar231x.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
+ #include "devices.h"
+ #include "ar5312.h"
+ #include "ar2315.h"
++#include "machtype.h"
++#include "gpio.h"
+ 
+ struct ar231x_board_config ar231x_board;
+ int ar231x_devtype = DEV_TYPE_UNKNOWN;
+@@ -159,6 +176,38 @@
+ 	return platform_device_register(&ar231x_wmac[nr]);
+ }
+ 
++static int board_init = 0;
++
++static void __init
++ar231x_set_default_mach(void)
++{
++        mips_machtype = AR231X_MACH_GENERIC;
++}
++
++static int __init
++ar231x_machtype_setup(char *board)
++{
++	int machtype  = mips_machtype_setup(board);
++	/* Use generic if board not detected */
++	if (machtype) {
++		ar231x_set_default_mach();
++	}
++	board_init = 1;
++
++	return 0;
++}
++
++__setup("board=", ar231x_machtype_setup);
++
++int __init
++ar231x_machine_setup(void)
++{
++	if (!board_init) ar231x_set_default_mach();
++	mips_machine_setup();
++
++	return 0;
++}
++
+ static int __init ar231x_register_devices(void)
+ {
+ 	static struct resource res = {
+@@ -169,7 +218,39 @@
+ 	ar5312_init_devices();
+ 	ar2315_init_devices();
+ 
++	ar231x_machine_setup();
++	ar231x_register_gpio();
++
+ 	return 0;
+ }
+ 
+ device_initcall(ar231x_register_devices);
++
++void __init
++ar231x_generic_gpio_setup(void)
++{
++#ifdef CONFIG_LEDS_GPIO
++#define LED_NAME_SZ 7
++	int i, n;
++        char *led_name;
++        n = is_2315() ? AR2315_NUM_GPIO : AR531X_NUM_GPIO;
++
++        for (i = 1; i <= n; i++)
++        {
++                if((i == AR2315_RESET_GPIO && is_2315()) ||
++                   (i == ar231x_board.config->resetConfigGpio))
++                        continue;
++
++                led_name = (char *) kmalloc(LED_NAME_SZ, GFP_KERNEL);
++		if(led_name == NULL) continue;
++		if(i == ar231x_board.config->sysLedGpio)
++                        strcpy(led_name, "wlan");
++                else
++                        sprintf(led_name, "gpio%d", i);
++                ar231x_add_led(led_name, i);
++        }
++#endif
++}
++
++MIPS_MACHINE(AR231X_MACH_GENERIC, "GENERIC", "Atheros AR231X Generic Board",
++                ar231x_generic_gpio_setup);
+diff -urN a/arch/mips/ar231x/gpio.c b/arch/mips/ar231x/gpio.c
+--- a/arch/mips/ar231x/gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.c	2010-10-24 22:20:32.859506793 +0700
+@@ -0,0 +1,167 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/leds.h>
++#include <linux/gpio_buttons.h>
++#include <linux/input.h>
++#include <ar231x_platform.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
++
++#include "devices.h"
++
++#define AR231X_MAX_LEDS 6 
++
++static struct gpio_led ar231x_leds[AR231X_MAX_LEDS];
++static int led = 0, led_default_active_low = 0;
++
++void __init
++ar231x_set_led_default_active_low(int active_low)
++{
++	led_default_active_low = active_low;
++}
++
++void __init
++ar231x_add_led(char *name, int gpio)
++{
++        if (led >= AR231X_MAX_LEDS) return;
++        ar231x_leds[led].name = name;
++        ar231x_leds[led].gpio = gpio;
++        ar231x_leds[led].active_low = led_default_active_low;
++        led++;
++}
++
++void __init
++ar231x_register_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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_leds:
++        kfree(p);
++}
++
++#define AR231X_MAX_BUTTONS              2
++#define AR231X_BUTTONS_POLL_INTERVAL    20
++
++static struct gpio_button ar231x_buttons[AR231X_MAX_BUTTONS];
++static int button = 0, button_default_threshold = 3, button_default_active_low = 0;
++
++void __init
++ar231x_set_button_default_active_low(int active_low)
++{
++	button_default_active_low = active_low;
++}
++
++void __init
++ar231x_set_button_default_threshold(int threshold)
++{
++	button_default_threshold = threshold;
++}
++
++void __init
++ar231x_add_button(char *desc, int code, int gpio)
++{
++        if (button >= AR231X_MAX_BUTTONS) return;
++        ar231x_buttons[button].desc = desc;
++        ar231x_buttons[button].type = EV_KEY;
++        ar231x_buttons[button].code = code;
++        ar231x_buttons[button].gpio = gpio;
++        ar231x_buttons[button].threshold = button_default_threshold;
++        ar231x_buttons[button].active_low = button_default_active_low;
++        button++;
++}
++
++void __init
++ar231x_register_gpio_buttons(int id, unsigned poll_interval, unsigned nbuttons,
++		struct gpio_button *buttons)
++{
++        struct platform_device *pdev;
++        struct gpio_buttons_platform_data pdata;
++        struct gpio_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-buttons", id);
++        if (!pdev)
++                goto err_free_buttons;
++
++        memset(&pdata, 0, sizeof(pdata));
++        pdata.poll_interval = poll_interval;
++        pdata.nbuttons = nbuttons;
++        pdata.buttons = 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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_buttons:
++        kfree(p);
++}
++
++void __init
++ar231x_register_gpio(void)
++{
++        if (button) {
++                ar231x_register_gpio_buttons(-1, AR231X_BUTTONS_POLL_INTERVAL, button, ar231x_buttons);
++        }
++        if (led) {
++		ar231x_register_leds_gpio(-1, led, ar231x_leds);
++        }
++}
+diff -urN a/arch/mips/ar231x/gpio.h b/arch/mips/ar231x/gpio.h
+--- a/arch/mips/ar231x/gpio.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.h	2010-10-24 21:01:53.108447507 +0700
+@@ -0,0 +1,25 @@
++#ifndef __GPIO_H
++#define __GPIO_H
++
++#ifdef CONFIG_ATHEROS_AR231X_GPIO
++
++extern void ar231x_register_gpio(void);
++extern void ar231x_set_led_default_active_low(int active_low);
++extern void ar231x_add_led(char *name, int gpio);
++extern void ar231x_set_button_default_active_low(int active_low);
++extern void ar231x_set_button_default_threshold(int threshold);
++extern void ar231x_add_button(char *desc, int code, int gpio);
++
++#else
++
++static inline void ar231x_register_gpio(void) {}
++static inline void ar231x_set_led_default_active_low(int active_low) {}
++static inline void ar231x_add_led(char *name, int gpio) {}
++static inline void ar231x_set_button_default_active_low(int active_low) {}
++static inline void ar231x_set_button_default_threshold(int threshold) {}
++static inline void ar231x_add_button(char *desc, int code, int gpio) {}
++
++#endif
++
++
++#endif
+diff -urN a/arch/mips/ar231x/Kconfig b/arch/mips/ar231x/Kconfig
+--- a/arch/mips/ar231x/Kconfig	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/Kconfig	2010-10-24 21:10:13.655611973 +0700
+@@ -25,3 +25,13 @@
+ 	select USB_ARCH_HAS_OHCI
+ 	select USB_ARCH_HAS_EHCI
+ 	default y
++
++config ATHEROS_AR231X_GPIO
++	bool "Atheros 231X GPIO support"
++	depends on ATHEROS_AR231X
++	default y
++
++config ATHEROS_AR231X_MACH_DIR_300_A1
++	bool "D-LINK DIR-300 rev. A1 GPIO support"
++	depends on ATHEROS_AR231X
++	default n
+diff -urN a/arch/mips/ar231x/mach-dir-300-a1-gpio.c b/arch/mips/ar231x/mach-dir-300-a1-gpio.c
+--- a/arch/mips/ar231x/mach-dir-300-a1-gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/mach-dir-300-a1-gpio.c	2010-10-24 15:08:48.345675857 +0700
+@@ -0,0 +1,36 @@
++/*
++ *  D-Link DIR-300 rev. A1 GPIO support
++ *
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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/input.h>
++#include "machtype.h"
++#include "gpio.h"
++
++#define DIR_300_A1_GPIO_LED_SYSTEM	7
++#define DIR_300_A1_GPIO_LED_WLAN	2
++#define DIR_300_A1_GPIO_LED_WPS_BLUE	1
++#define DIR_300_A1_GPIO_LED_WPS_RED	3
++
++#define DIR_300_A1_GPIO_BUTTON_RESET	6
++#define DIR_300_A1_GPIO_BUTTON_WPS	4
++
++static void __init dir_300_a1_gpio_setup(void)
++{
++	ar231x_add_button("reset", KEY_RESTART, DIR_300_A1_GPIO_BUTTON_RESET);
++	ar231x_add_button("wps", KEY_WPS_BUTTON, DIR_300_A1_GPIO_BUTTON_WPS);
++	
++	ar231x_add_led("dir300:green:system", DIR_300_A1_GPIO_LED_SYSTEM);
++	ar231x_add_led("dir300:green:wlan", DIR_300_A1_GPIO_LED_WLAN);
++	ar231x_add_led("dir300:blue:wps", DIR_300_A1_GPIO_LED_WPS_BLUE);
++	ar231x_add_led("dir300:red:wps", DIR_300_A1_GPIO_LED_WPS_RED);
++}
++
++MIPS_MACHINE(AR231X_MACH_DIR_300_A1, "DIR-300-A1", "D-Link DIR-300 rev. A1",
++	     dir_300_a1_gpio_setup);
+diff -urN a/arch/mips/ar231x/machtype.h b/arch/mips/ar231x/machtype.h
+--- a/arch/mips/ar231x/machtype.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/machtype.h	2010-10-24 15:08:48.354041241 +0700
+@@ -0,0 +1,23 @@
++/*
++ *  Atheros AR231X machine type definitions
++ *
++ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
++ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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 _AR231X_MACHTYPE_H
++#define _AR231X_MACHTYPE_H
++
++#include <asm/mips_machine.h>
++
++enum ar231x_mach_type {
++	AR231X_MACH_GENERIC = 0,
++	AR231X_MACH_DIR_300_A1,	/* D-Link DIR-300 rev. A1 */
++};
++
++#endif /* _AR231X_MACHTYPE_H */
+diff -urN a/arch/mips/ar231x/Makefile b/arch/mips/ar231x/Makefile
+--- a/arch/mips/ar231x/Makefile	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/Makefile	2010-10-24 20:59:31.735693794 +0700
+@@ -15,3 +15,5 @@
+ obj-$(CONFIG_ATHEROS_AR5312) += ar5312.o
+ obj-$(CONFIG_ATHEROS_AR2315) += ar2315.o
+ obj-$(CONFIG_ATHEROS_AR2315_PCI) += pci.o
++obj-$(CONFIG_ATHEROS_AR231X_GPIO) += gpio.o
++obj-$(CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1) += mach-dir-300-a1-gpio.o
+diff -urN a/arch/mips/ar231x/prom.c b/arch/mips/ar231x/prom.c
+--- a/arch/mips/ar231x/prom.c	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/prom.c	2010-10-24 23:38:31.312244791 +0700
+@@ -26,8 +26,42 @@
+ #include "ar5312.h"
+ #include "ar2315.h"
+ 
++#ifdef CONFIG_IMAGE_CMDLINE_HACK
++extern char __image_cmdline[];
++
++static int __init ar231x_use__image_cmdline(void)
++{
++        char *p = __image_cmdline;
++        int replace = 0;
++
++        if (*p == '-') {
++                replace = 1;
++                p++;
++        }
++
++        if (*p == '\0')
++                return 0;
++
++	if (strlen(arcs_cmdline) == 0)
++		replace = 1;
++
++        if (replace) {
++                strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline));
++        } else {
++                strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
++                strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
++        }
++
++        return 1;
++}
++#else
++static int inline ar231x_use__image_cmdline(void) { return 0; }
++#endif
++
+ void __init prom_init(void)
+ {
++	ar231x_use__image_cmdline();
++
+ 	ar5312_prom_init();
+ 	ar2315_prom_init();
+ }
+diff -urN a/arch/mips/Kconfig b/arch/mips/Kconfig
+--- a/arch/mips/Kconfig	2010-10-24 15:33:04.157474056 +0700
++++ b/arch/mips/Kconfig	2010-10-24 15:08:48.681423282 +0700
+@@ -95,6 +95,7 @@
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select GENERIC_GPIO
+ 	select SYS_HAS_EARLY_PRINTK
++	select MIPS_MACHINE
+ 	help
+ 	  Support for AR231x and AR531x based boards
+ 
Index: target/linux/atheros/image/Makefile
===================================================================
--- target/linux/atheros/image/Makefile	(revision 23620)
+++ target/linux/atheros/image/Makefile	(working copy)
@@ -7,56 +7,104 @@
 include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/image.mk
 
+define CompressLzma
+	$(STAGING_DIR_HOST)/bin/lzma e $(1) $(2)
+endef
+
+define CompressGzip
+	gzip -9 -c $(1) > $(2)
+endef
+
+define PatchKernelLzma
+	cp $(KDIR)/vmlinux $(KDIR)/vmlinux-$(1)
+	$(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR)/vmlinux-$(1) '$(strip $(2))'
+	$(call CompressLzma,$(KDIR)/vmlinux-$(1),$(KDIR)/vmlinux-$(1).bin.l7)
+endef
+
+define PatchKernelGzip
+	cp $(KDIR)/vmlinux $(KDIR)/vmlinux-$(1)
+	$(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR)/vmlinux-$(1) '$(strip $(2))'
+	$(call CompressGzip,$(KDIR)/vmlinux-$(1),$(KDIR)/vmlinux-$(1).bin.gz)
+endef
+
 define Image/BuildKernel
 	cp $(KDIR)/vmlinux.elf $(BIN_DIR)/$(IMG_PREFIX)-vmlinux.elf
-	gzip -9 -c $(KDIR)/vmlinux > $(KDIR)/vmlinux.bin.gz
-	$(STAGING_DIR_HOST)/bin/lzma e $(KDIR)/vmlinux $(KDIR)/vmlinux.bin.l7
+	$(call CompressLzma,$(KDIR)/vmlinux,$(KDIR)/vmlinux.bin.l7)
+	$(call CompressGzip,$(KDIR)/vmlinux,$(KDIR)/vmlinux.bin.gz)
 	dd if=$(KDIR)/vmlinux.bin.l7 of=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux.lzma bs=65536 conv=sync
 	dd if=$(KDIR)/vmlinux.bin.gz of=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux.gz bs=65536 conv=sync
 endef
 
 define Image/Build/squashfs
-    $(call prepare_generic_squashfs,$(KDIR)/root.squashfs)
+	$(call prepare_generic_squashfs,$(KDIR)/root.squashfs)
 endef
 
-define Image/Build
-	$(call Image/Build/$(1))
-	dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync
+define Image/Build/Combine
+	-sh $(TOPDIR)/scripts/combined-image.sh \
+		"$(BIN_DIR)/$(IMG_PREFIX)-$(1)" \
+		"$(BIN_DIR)/$(IMG_PREFIX)-$(2)" \
+		"$(BIN_DIR)/$(IMG_PREFIX)-$(3).img"
+endef
 
-	-$(STAGING_DIR_HOST)/bin/mkfwimage \
-		-B XS2 -v XS2.ar2316.OpenWrt.$(REVISION) \
-		-k $(BIN_DIR)/$(IMG_PREFIX)-vmlinux.lzma \
-		-r $(BIN_DIR)/$(IMG_PREFIX)-root.$(1) \
-		-o $(BIN_DIR)/$(IMG_PREFIX)-ubnt2-$(1).bin
+define Image/Build/Template/Lzma
+	$(call PatchKernelLzma,$(1),$(2))
+	dd if=$(KDIR)/vmlinux-$(1).bin.l7 of=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux-$(1).lzma bs=65536 conv=sync
+	$(call Image/Build/Combine,vmlinux-$(1).lzma,root.$(3),$(1)-combined.$(3))
+endef
 
+define Image/Build/Template/UBNT
 	-$(STAGING_DIR_HOST)/bin/mkfwimage \
-		-B XS5 -v XS5.ar2313.OpenWrt.$(REVISION) \
+		-B $(1) -v $(2).OpenWrt.$(REVISION) \
 		-k $(BIN_DIR)/$(IMG_PREFIX)-vmlinux.lzma \
-		-r $(BIN_DIR)/$(IMG_PREFIX)-root.$(1) \
-		-o $(BIN_DIR)/$(IMG_PREFIX)-ubnt5-$(1).bin
+		-r $(BIN_DIR)/$(IMG_PREFIX)-root.$(4) \
+		-o $(BIN_DIR)/$(IMG_PREFIX)-$(3)-$(4).bin
+endef
 
-	-$(STAGING_DIR_HOST)/bin/mkfwimage \
-		-B XS2-8 -v XS2.ar2316.OpenWrt.$(REVISION) \
-		-k $(BIN_DIR)/$(IMG_PREFIX)-vmlinux.lzma \
-		-r $(BIN_DIR)/$(IMG_PREFIX)-root.$(1) \
-		-o $(BIN_DIR)/$(IMG_PREFIX)-ubnt2-pico2-$(1).bin
-
-	-$(STAGING_DIR_HOST)/bin/mkmylofw -B np25g \
+define Image/Build/Template/COMPEX
+	-$(STAGING_DIR_HOST)/bin/mkmylofw -B $(1) \
 		-p0x020000:0x130000:ah:0x80041000:linux:$(KDIR)/vmlinux.bin.gz  \
-		-p0x150000:0x2a0000:::rootfs:$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) \
-		$(BIN_DIR)/$(IMG_PREFIX)-np25g-$(1).bin
+		-p0x150000:0x2a0000:::rootfs:$(BIN_DIR)/$(IMG_PREFIX)-root.$(2) \
+		$(BIN_DIR)/$(IMG_PREFIX)-$(1)-$(2).bin
+endef
 
-	-$(STAGING_DIR_HOST)/bin/mkmylofw -B wpe53g \
-		-p0x020000:0x130000:ah:0x80041000:linux:$(KDIR)/vmlinux.bin.gz  \
-		-p0x150000:0x2a0000:::rootfs:$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) \
-		$(BIN_DIR)/$(IMG_PREFIX)-wpe53g-$(1).bin
+define Image/Build/UBNTXS2
+	$(call Image/Build/Template/UBNT,XS2,XS2.ar2316,ubnt2,$(1))
+endef
 
-  ifeq ($(BOARD),atheros)
-	-sh $(TOPDIR)/scripts/combined-image.sh \
-		"$(BIN_DIR)/$(IMG_PREFIX)-vmlinux.lzma" \
-		"$(BIN_DIR)/$(IMG_PREFIX)-root.$(1)" \
-		"$(BIN_DIR)/$(IMG_PREFIX)-combined.$(1).img"
-  endif
+define Image/Build/UBNTXS5
+	$(call Image/Build/Template/UBNT,XS5,XS5.ar2313,ubnt5,$(1))
 endef
 
+define Image/Build/UBNTXS2-8
+	$(call Image/Build/Template/UBNT,XS2-8,XS2.ar2316,ubnt2-pico2,$(1))
+endef
+
+define Image/Build/NP25G
+	$(call Image/Build/Template/COMPEX,np25g,$(1))
+endef
+
+define Image/Build/WPE53G
+	$(call Image/Build/Template/COMPEX,wpe53g,$(1))
+endef
+
+define Image/Build/Profile/Default
+	$(call Image/Build/UBNTXS2,$(1))
+	$(call Image/Build/UBNTXS5,$(1))
+	$(call Image/Build/UBNTXS2-8,$(1))
+	$(call Image/Build/NP25G,$(1))
+	$(call Image/Build/WPE53G,$(1))
+	$(call Image/Build/Combine,vmlinux.lzma,root.$(1),combined.$(1))
+endef
+
+define Image/Build/Profile/DIR300A1
+	$(call Image/Build/Template/Lzma,dir-300-a1,board=DIR-300-A1,$(1))
+endef
+
+define Image/Build
+	$(call Image/Build/$(1))
+	dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync
+
+	$(call Image/Build/Profile/$(PROFILE),$(1))
+endef
+
 $(eval $(call BuildImage))
Index: target/linux/atheros/profiles/d-link.mk
===================================================================
--- target/linux/atheros/profiles/d-link.mk	(revision 0)
+++ target/linux/atheros/profiles/d-link.mk	(revision 0)
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2009 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/DIR300A1
+	NAME:=D-LINK DIR-300 REV. A1
+	PACKAGES:=kmod-switch-ip17xx kmod-leds-gpio kmod-input-gpio-buttons kmod-button-hotplug wpad hostapd-utils
+endef
+
+define Profile/DIR300A1/Description
+	Package set optimized for the D-LINK DIR-300 REV. A1.
+endef
+
+$(eval $(call Profile,DIR300A1))
Index: target/linux/atheros/profiles/00-default.mk
===================================================================
--- target/linux/atheros/profiles/00-default.mk	(revision 0)
+++ target/linux/atheros/profiles/00-default.mk	(revision 0)
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2009 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/Default
+	NAME:=Default Profile
+	PACKAGES:=wpad-mini
+endef
+
+define Profile/Default/Description
+	Default package set compatible with most boards.
+endef
+$(eval $(call Profile,Default))
Index: target/linux/atheros/config-2.6.30
===================================================================
--- target/linux/atheros/config-2.6.30	(revision 23620)
+++ target/linux/atheros/config-2.6.30	(working copy)
@@ -11,6 +11,8 @@
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ATHEROS_AR2315=y
 CONFIG_ATHEROS_AR2315_PCI=y
+CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1=y
+CONFIG_ATHEROS_AR231X_GPIO=y
 CONFIG_ATHEROS_AR231X=y
 CONFIG_ATHEROS_AR5312=y
 CONFIG_ATHEROS_WDT=y
@@ -84,7 +86,7 @@
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_IP17XX_PHY=y
 CONFIG_IRQ_CPU=y
-# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_GPIO=y
 # CONFIG_LEMOTE_FULONG is not set
 # CONFIG_MACH_ALCHEMY is not set
 # CONFIG_MACH_DECSTATION is not set
Index: target/linux/atheros/config-2.6.32
===================================================================
--- target/linux/atheros/config-2.6.32	(revision 23620)
+++ target/linux/atheros/config-2.6.32	(working copy)
@@ -14,6 +14,8 @@
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ATHEROS_AR2315=y
 CONFIG_ATHEROS_AR2315_PCI=y
+CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1=y
+CONFIG_ATHEROS_AR231X_GPIO=y
 CONFIG_ATHEROS_AR231X=y
 CONFIG_ATHEROS_AR5312=y
 CONFIG_ATHEROS_WDT=y
@@ -90,7 +92,7 @@
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_IP17XX_PHY=y
 CONFIG_IRQ_CPU=y
-# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_GPIO=y
 # CONFIG_MACH_ALCHEMY is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
Index: target/linux/atheros/config-2.6.33
===================================================================
--- target/linux/atheros/config-2.6.33	(revision 23620)
+++ target/linux/atheros/config-2.6.33	(working copy)
@@ -14,6 +14,8 @@
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ATHEROS_AR2315=y
 CONFIG_ATHEROS_AR2315_PCI=y
+CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1=y
+CONFIG_ATHEROS_AR231X_GPIO=y
 CONFIG_ATHEROS_AR231X=y
 CONFIG_ATHEROS_AR5312=y
 CONFIG_ATHEROS_WDT=y
@@ -97,7 +99,7 @@
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_IP17XX_PHY=y
 CONFIG_IRQ_CPU=y
-# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_GPIO=y
 CONFIG_LOONGSON_UART_BASE=y
 # CONFIG_MACH_ALCHEMY is not set
 # CONFIG_MACH_DECSTATION is not set
Index: target/linux/atheros/config-2.6.34
===================================================================
--- target/linux/atheros/config-2.6.34	(revision 23620)
+++ target/linux/atheros/config-2.6.34	(working copy)
@@ -15,6 +15,8 @@
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ATHEROS_AR2315=y
 CONFIG_ATHEROS_AR2315_PCI=y
+CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1=y
+CONFIG_ATHEROS_AR231X_GPIO=y
 CONFIG_ATHEROS_AR231X=y
 CONFIG_ATHEROS_AR5312=y
 CONFIG_ATHEROS_WDT=y
@@ -97,7 +99,7 @@
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_IP17XX_PHY=y
 CONFIG_IRQ_CPU=y
-# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_GPIO=y
 CONFIG_LOONGSON_UART_BASE=y
 # CONFIG_MACH_ALCHEMY is not set
 # CONFIG_MACH_DECSTATION is not set
Index: target/linux/atheros/config-2.6.35
===================================================================
--- target/linux/atheros/config-2.6.35	(revision 23620)
+++ target/linux/atheros/config-2.6.35	(working copy)
@@ -15,6 +15,8 @@
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ATHEROS_AR2315=y
 CONFIG_ATHEROS_AR2315_PCI=y
+CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1=y
+CONFIG_ATHEROS_AR231X_GPIO=y
 CONFIG_ATHEROS_AR231X=y
 CONFIG_ATHEROS_AR5312=y
 CONFIG_ATHEROS_WDT=y
@@ -95,8 +97,9 @@
 CONFIG_HW_RANDOM=y
 CONFIG_IMAGE_CMDLINE_HACK=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IP17XX_PHY=y
 CONFIG_IRQ_CPU=y
-# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_GPIO=y
 CONFIG_LOONGSON_UART_BASE=y
 # CONFIG_MACH_ALCHEMY is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -109,7 +112,7 @@
 CONFIG_MIPS=y
 # CONFIG_MIPS_COBALT is not set
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_MIPS_MACHINE is not set
+CONFIG_MIPS_MACHINE=y
 # CONFIG_MIPS_MALTA is not set
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
Index: target/linux/atheros/config-2.6.36
===================================================================
--- target/linux/atheros/config-2.6.36	(revision 23620)
+++ target/linux/atheros/config-2.6.36	(working copy)
@@ -14,6 +14,8 @@
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ATHEROS_AR2315=y
 CONFIG_ATHEROS_AR2315_PCI=y
+CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1=y
+CONFIG_ATHEROS_AR231X_GPIO=y
 CONFIG_ATHEROS_AR231X=y
 CONFIG_ATHEROS_AR5312=y
 CONFIG_ATHEROS_WDT=y
@@ -76,8 +78,9 @@
 CONFIG_HW_RANDOM=y
 CONFIG_IMAGE_CMDLINE_HACK=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IP17XX_PHY=y
 CONFIG_IRQ_CPU=y
-# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_GPIO=y
 # CONFIG_LOONGSON_MC146818 is not set
 CONFIG_LOONGSON_UART_BASE=y
 # CONFIG_MACH_DECSTATION is not set
@@ -92,7 +95,7 @@
 # CONFIG_MIPS_ALCHEMY is not set
 # CONFIG_MIPS_COBALT is not set
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_MIPS_MACHINE is not set
+CONFIG_MIPS_MACHINE=y
 # CONFIG_MIPS_MALTA is not set
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_SIM is not set
Index: target/linux/atheros/patches-2.6.30/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch
===================================================================
--- target/linux/atheros/patches-2.6.30/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
+++ target/linux/atheros/patches-2.6.30/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
@@ -0,0 +1,575 @@
+diff -urN a/arch/mips/ar231x/ar2315.c b/arch/mips/ar231x/ar2315.c
+--- a/arch/mips/ar231x/ar2315.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/ar2315.c	2010-10-24 15:42:23.673791281 +0700
+@@ -22,7 +22,6 @@
+ #include <linux/kernel.h>
+ #include <linux/reboot.h>
+ #include <linux/delay.h>
+-#include <linux/leds.h>
+ #include <asm/bootinfo.h>
+ #include <asm/reboot.h>
+ #include <asm/time.h>
+@@ -481,52 +480,6 @@
+ 	return (u8 *) ar2315_spiflash_res[0].end + 1;
+ }
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar2315_leds[6];
+-static struct gpio_led_platform_data ar2315_led_data = {
+-	.leds = (void *) ar2315_leds,
+-};
+-
+-static struct platform_device ar2315_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev = {
+-		.platform_data = (void *) &ar2315_led_data,
+-	}
+-};
+-
+-static void __init
+-ar2315_init_gpio(void)
+-{
+-	static char led_names[6][6];
+-	int i, led = 0;
+-
+-	ar2315_led_data.num_leds = 0;
+-	for(i = 1; i < 8; i++)
+-	{
+-		if((i == AR2315_RESET_GPIO) ||
+-		   (i == ar231x_board.config->resetConfigGpio))
+-			continue;
+-
+-		if(i == ar231x_board.config->sysLedGpio)
+-			strcpy(led_names[led], "wlan");
+-		else
+-			sprintf(led_names[led], "gpio%d", i);
+-
+-		ar2315_leds[led].name = led_names[led];
+-		ar2315_leds[led].gpio = i;
+-		ar2315_leds[led].active_low = 0;
+-		led++;
+-	}
+-	ar2315_led_data.num_leds = led;
+-	platform_device_register(&ar2315_gpio_leds);
+-}
+-#else
+-static inline void ar2315_init_gpio(void)
+-{
+-}
+-#endif
+-
+ int __init
+ ar2315_init_devices(void)
+ {
+@@ -537,7 +490,6 @@
+ 	ar231x_find_config(ar2315_flash_limit());
+ 	ar2315_eth_data.macaddr = ar231x_board.config->enet0_mac;
+ 
+-	ar2315_init_gpio();
+ 	platform_device_register(&ar2315_wdt);
+ 	platform_device_register(&ar2315_spiflash);
+ 	ar231x_add_ethernet(0, AR2315_ENET0, AR2315_IRQ_ENET0_INTRS,
+diff -urN a/arch/mips/ar231x/ar5312.c b/arch/mips/ar231x/ar5312.c
+--- a/arch/mips/ar231x/ar5312.c	2010-10-24 15:33:03.865423290 +0700
++++ b/arch/mips/ar231x/ar5312.c	2010-10-24 15:08:48.354041241 +0700
+@@ -245,23 +245,6 @@
+ 	.num_resources = 1,
+ };
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar5312_leds[] = {
+-	{ .name = "wlan", .gpio = 0, .active_low = 1, },
+-};
+-
+-static const struct gpio_led_platform_data ar5312_led_data = {
+-	.num_leds = ARRAY_SIZE(ar5312_leds),
+-	.leds = (void *) ar5312_leds,
+-};
+-
+-static struct platform_device ar5312_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev.platform_data = (void *) &ar5312_led_data,
+-};
+-#endif
+-
+ /*
+  * NB: This mapping size is larger than the actual flash size,
+  * but this shouldn't be a problem here, because the flash
+@@ -350,11 +333,6 @@
+ 
+ 	platform_device_register(&ar5312_physmap_flash);
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-	ar5312_leds[0].gpio = config->sysLedGpio;
+-	platform_device_register(&ar5312_gpio_leds);
+-#endif
+-
+ 	/* Fix up MAC addresses if necessary */
+ 	if (!memcmp(config->enet0_mac, "\xff\xff\xff\xff\xff\xff", 6))
+ 		memcpy(config->enet0_mac, config->enet1_mac, 6);
+diff -urN a/arch/mips/ar231x/devices.c b/arch/mips/ar231x/devices.c
+--- a/arch/mips/ar231x/devices.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/devices.c	2010-10-24 20:48:48.011645424 +0700
+@@ -1,14 +1,31 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ #include <linux/serial.h>
+ #include <linux/serial_core.h>
+ #include <linux/serial_8250.h>
+ #include <linux/platform_device.h>
+ #include <ar231x_platform.h>
+ #include <ar231x.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
+ #include "devices.h"
+ #include "ar5312.h"
+ #include "ar2315.h"
++#include "machtype.h"
++#include "gpio.h"
+ 
+ struct ar231x_board_config ar231x_board;
+ int ar231x_devtype = DEV_TYPE_UNKNOWN;
+@@ -159,6 +176,38 @@
+ 	return platform_device_register(&ar231x_wmac[nr]);
+ }
+ 
++static int board_init = 0;
++
++static void __init
++ar231x_set_default_mach(void)
++{
++        mips_machtype = AR231X_MACH_GENERIC;
++}
++
++static int __init
++ar231x_machtype_setup(char *board)
++{
++	int machtype  = mips_machtype_setup(board);
++	/* Use generic if board not detected */
++	if (machtype) {
++		ar231x_set_default_mach();
++	}
++	board_init = 1;
++
++	return 0;
++}
++
++__setup("board=", ar231x_machtype_setup);
++
++int __init
++ar231x_machine_setup(void)
++{
++	if (!board_init) ar231x_set_default_mach();
++	mips_machine_setup();
++
++	return 0;
++}
++
+ static int __init ar231x_register_devices(void)
+ {
+ 	static struct resource res = {
+@@ -169,7 +218,39 @@
+ 	ar5312_init_devices();
+ 	ar2315_init_devices();
+ 
++	ar231x_machine_setup();
++	ar231x_register_gpio();
++
+ 	return 0;
+ }
+ 
+ device_initcall(ar231x_register_devices);
++
++void __init
++ar231x_generic_gpio_setup(void)
++{
++#ifdef CONFIG_LEDS_GPIO
++#define LED_NAME_SZ 7
++	int i, n;
++        char *led_name;
++        n = is_2315() ? AR2315_NUM_GPIO : AR531X_NUM_GPIO;
++
++        for (i = 1; i <= n; i++)
++        {
++                if((i == AR2315_RESET_GPIO && is_2315()) ||
++                   (i == ar231x_board.config->resetConfigGpio))
++                        continue;
++
++                led_name = (char *) kmalloc(LED_NAME_SZ, GFP_KERNEL);
++		if(led_name == NULL) continue;
++		if(i == ar231x_board.config->sysLedGpio)
++                        strcpy(led_name, "wlan");
++                else
++                        sprintf(led_name, "gpio%d", i);
++                ar231x_add_led(led_name, i);
++        }
++#endif
++}
++
++MIPS_MACHINE(AR231X_MACH_GENERIC, "GENERIC", "Atheros AR231X Generic Board",
++                ar231x_generic_gpio_setup);
+diff -urN a/arch/mips/ar231x/gpio.c b/arch/mips/ar231x/gpio.c
+--- a/arch/mips/ar231x/gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.c	2010-10-24 22:20:32.859506793 +0700
+@@ -0,0 +1,167 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/leds.h>
++#include <linux/gpio_buttons.h>
++#include <linux/input.h>
++#include <ar231x_platform.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
++
++#include "devices.h"
++
++#define AR231X_MAX_LEDS 6 
++
++static struct gpio_led ar231x_leds[AR231X_MAX_LEDS];
++static int led = 0, led_default_active_low = 0;
++
++void __init
++ar231x_set_led_default_active_low(int active_low)
++{
++	led_default_active_low = active_low;
++}
++
++void __init
++ar231x_add_led(char *name, int gpio)
++{
++        if (led >= AR231X_MAX_LEDS) return;
++        ar231x_leds[led].name = name;
++        ar231x_leds[led].gpio = gpio;
++        ar231x_leds[led].active_low = led_default_active_low;
++        led++;
++}
++
++void __init
++ar231x_register_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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_leds:
++        kfree(p);
++}
++
++#define AR231X_MAX_BUTTONS              2
++#define AR231X_BUTTONS_POLL_INTERVAL    20
++
++static struct gpio_button ar231x_buttons[AR231X_MAX_BUTTONS];
++static int button = 0, button_default_threshold = 3, button_default_active_low = 0;
++
++void __init
++ar231x_set_button_default_active_low(int active_low)
++{
++	button_default_active_low = active_low;
++}
++
++void __init
++ar231x_set_button_default_threshold(int threshold)
++{
++	button_default_threshold = threshold;
++}
++
++void __init
++ar231x_add_button(char *desc, int code, int gpio)
++{
++        if (button >= AR231X_MAX_BUTTONS) return;
++        ar231x_buttons[button].desc = desc;
++        ar231x_buttons[button].type = EV_KEY;
++        ar231x_buttons[button].code = code;
++        ar231x_buttons[button].gpio = gpio;
++        ar231x_buttons[button].threshold = button_default_threshold;
++        ar231x_buttons[button].active_low = button_default_active_low;
++        button++;
++}
++
++void __init
++ar231x_register_gpio_buttons(int id, unsigned poll_interval, unsigned nbuttons,
++		struct gpio_button *buttons)
++{
++        struct platform_device *pdev;
++        struct gpio_buttons_platform_data pdata;
++        struct gpio_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-buttons", id);
++        if (!pdev)
++                goto err_free_buttons;
++
++        memset(&pdata, 0, sizeof(pdata));
++        pdata.poll_interval = poll_interval;
++        pdata.nbuttons = nbuttons;
++        pdata.buttons = 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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_buttons:
++        kfree(p);
++}
++
++void __init
++ar231x_register_gpio(void)
++{
++        if (button) {
++                ar231x_register_gpio_buttons(-1, AR231X_BUTTONS_POLL_INTERVAL, button, ar231x_buttons);
++        }
++        if (led) {
++		ar231x_register_leds_gpio(-1, led, ar231x_leds);
++        }
++}
+diff -urN a/arch/mips/ar231x/gpio.h b/arch/mips/ar231x/gpio.h
+--- a/arch/mips/ar231x/gpio.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.h	2010-10-24 21:01:53.108447507 +0700
+@@ -0,0 +1,25 @@
++#ifndef __GPIO_H
++#define __GPIO_H
++
++#ifdef CONFIG_ATHEROS_AR231X_GPIO
++
++extern void ar231x_register_gpio(void);
++extern void ar231x_set_led_default_active_low(int active_low);
++extern void ar231x_add_led(char *name, int gpio);
++extern void ar231x_set_button_default_active_low(int active_low);
++extern void ar231x_set_button_default_threshold(int threshold);
++extern void ar231x_add_button(char *desc, int code, int gpio);
++
++#else
++
++static inline void ar231x_register_gpio(void) {}
++static inline void ar231x_set_led_default_active_low(int active_low) {}
++static inline void ar231x_add_led(char *name, int gpio) {}
++static inline void ar231x_set_button_default_active_low(int active_low) {}
++static inline void ar231x_set_button_default_threshold(int threshold) {}
++static inline void ar231x_add_button(char *desc, int code, int gpio) {}
++
++#endif
++
++
++#endif
+diff -urN a/arch/mips/ar231x/Kconfig b/arch/mips/ar231x/Kconfig
+--- a/arch/mips/ar231x/Kconfig	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/Kconfig	2010-10-24 21:10:13.655611973 +0700
+@@ -25,3 +25,13 @@
+ 	select USB_ARCH_HAS_OHCI
+ 	select USB_ARCH_HAS_EHCI
+ 	default y
++
++config ATHEROS_AR231X_GPIO
++	bool "Atheros 231X GPIO support"
++	depends on ATHEROS_AR231X
++	default y
++
++config ATHEROS_AR231X_MACH_DIR_300_A1
++	bool "D-LINK DIR-300 rev. A1 GPIO support"
++	depends on ATHEROS_AR231X
++	default n
+diff -urN a/arch/mips/ar231x/mach-dir-300-a1-gpio.c b/arch/mips/ar231x/mach-dir-300-a1-gpio.c
+--- a/arch/mips/ar231x/mach-dir-300-a1-gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/mach-dir-300-a1-gpio.c	2010-10-24 15:08:48.345675857 +0700
+@@ -0,0 +1,36 @@
++/*
++ *  D-Link DIR-300 rev. A1 GPIO support
++ *
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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/input.h>
++#include "machtype.h"
++#include "gpio.h"
++
++#define DIR_300_A1_GPIO_LED_SYSTEM	7
++#define DIR_300_A1_GPIO_LED_WLAN	2
++#define DIR_300_A1_GPIO_LED_WPS_BLUE	1
++#define DIR_300_A1_GPIO_LED_WPS_RED	3
++
++#define DIR_300_A1_GPIO_BUTTON_RESET	6
++#define DIR_300_A1_GPIO_BUTTON_WPS	4
++
++static void __init dir_300_a1_gpio_setup(void)
++{
++	ar231x_add_button("reset", KEY_RESTART, DIR_300_A1_GPIO_BUTTON_RESET);
++	ar231x_add_button("wps", KEY_WPS_BUTTON, DIR_300_A1_GPIO_BUTTON_WPS);
++	
++	ar231x_add_led("dir300:green:system", DIR_300_A1_GPIO_LED_SYSTEM);
++	ar231x_add_led("dir300:green:wlan", DIR_300_A1_GPIO_LED_WLAN);
++	ar231x_add_led("dir300:blue:wps", DIR_300_A1_GPIO_LED_WPS_BLUE);
++	ar231x_add_led("dir300:red:wps", DIR_300_A1_GPIO_LED_WPS_RED);
++}
++
++MIPS_MACHINE(AR231X_MACH_DIR_300_A1, "DIR-300-A1", "D-Link DIR-300 rev. A1",
++	     dir_300_a1_gpio_setup);
+diff -urN a/arch/mips/ar231x/machtype.h b/arch/mips/ar231x/machtype.h
+--- a/arch/mips/ar231x/machtype.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/machtype.h	2010-10-24 15:08:48.354041241 +0700
+@@ -0,0 +1,23 @@
++/*
++ *  Atheros AR231X machine type definitions
++ *
++ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
++ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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 _AR231X_MACHTYPE_H
++#define _AR231X_MACHTYPE_H
++
++#include <asm/mips_machine.h>
++
++enum ar231x_mach_type {
++	AR231X_MACH_GENERIC = 0,
++	AR231X_MACH_DIR_300_A1,	/* D-Link DIR-300 rev. A1 */
++};
++
++#endif /* _AR231X_MACHTYPE_H */
+diff -urN a/arch/mips/ar231x/Makefile b/arch/mips/ar231x/Makefile
+--- a/arch/mips/ar231x/Makefile	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/Makefile	2010-10-24 20:59:31.735693794 +0700
+@@ -15,3 +15,5 @@
+ obj-$(CONFIG_ATHEROS_AR5312) += ar5312.o
+ obj-$(CONFIG_ATHEROS_AR2315) += ar2315.o
+ obj-$(CONFIG_ATHEROS_AR2315_PCI) += pci.o
++obj-$(CONFIG_ATHEROS_AR231X_GPIO) += gpio.o
++obj-$(CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1) += mach-dir-300-a1-gpio.o
+diff -urN a/arch/mips/ar231x/prom.c b/arch/mips/ar231x/prom.c
+--- a/arch/mips/ar231x/prom.c	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/prom.c	2010-10-24 23:38:31.312244791 +0700
+@@ -26,8 +26,42 @@
+ #include "ar5312.h"
+ #include "ar2315.h"
+ 
++#ifdef CONFIG_IMAGE_CMDLINE_HACK
++extern char __image_cmdline[];
++
++static int __init ar231x_use__image_cmdline(void)
++{
++        char *p = __image_cmdline;
++        int replace = 0;
++
++        if (*p == '-') {
++                replace = 1;
++                p++;
++        }
++
++        if (*p == '\0')
++                return 0;
++
++	if (strlen(arcs_cmdline) == 0)
++		replace = 1;
++
++        if (replace) {
++                strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline));
++        } else {
++                strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
++                strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
++        }
++
++        return 1;
++}
++#else
++static int inline ar231x_use__image_cmdline(void) { return 0; }
++#endif
++
+ void __init prom_init(void)
+ {
++	ar231x_use__image_cmdline();
++
+ 	ar5312_prom_init();
+ 	ar2315_prom_init();
+ }
+diff -urN a/arch/mips/Kconfig b/arch/mips/Kconfig
+--- a/arch/mips/Kconfig	2010-10-24 15:33:04.157474056 +0700
++++ b/arch/mips/Kconfig	2010-10-24 15:08:48.681423282 +0700
+@@ -95,6 +95,7 @@
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select GENERIC_GPIO
+ 	select SYS_HAS_EARLY_PRINTK
++	select MIPS_MACHINE
+ 	help
+ 	  Support for AR231x and AR531x based boards
+ 
Index: target/linux/atheros/Makefile
===================================================================
--- target/linux/atheros/Makefile	(revision 23620)
+++ target/linux/atheros/Makefile	(working copy)
@@ -11,11 +11,11 @@
 BOARDNAME:=Atheros AR231x/AR5312
 FEATURES:=squashfs jffs2
 
-LINUX_VERSION:=2.6.32.24
+LINUX_VERSION:=2.6.35.7
 
 include $(INCLUDE_DIR)/target.mk
 
-DEFAULT_PACKAGES += wpad-mini kmod-madwifi gpioctl swconfig
+DEFAULT_PACKAGES += kmod-madwifi gpioctl swconfig
 
 define Target/Description
 	Build firmware images for Atheros SoC boards
Index: target/linux/atheros/patches-2.6.32/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch
===================================================================
--- target/linux/atheros/patches-2.6.32/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
+++ target/linux/atheros/patches-2.6.32/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
@@ -0,0 +1,575 @@
+diff -urN a/arch/mips/ar231x/ar2315.c b/arch/mips/ar231x/ar2315.c
+--- a/arch/mips/ar231x/ar2315.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/ar2315.c	2010-10-24 15:42:23.673791281 +0700
+@@ -22,7 +22,6 @@
+ #include <linux/kernel.h>
+ #include <linux/reboot.h>
+ #include <linux/delay.h>
+-#include <linux/leds.h>
+ #include <asm/bootinfo.h>
+ #include <asm/reboot.h>
+ #include <asm/time.h>
+@@ -481,52 +480,6 @@
+ 	return (u8 *) ar2315_spiflash_res[0].end + 1;
+ }
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar2315_leds[6];
+-static struct gpio_led_platform_data ar2315_led_data = {
+-	.leds = (void *) ar2315_leds,
+-};
+-
+-static struct platform_device ar2315_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev = {
+-		.platform_data = (void *) &ar2315_led_data,
+-	}
+-};
+-
+-static void __init
+-ar2315_init_gpio(void)
+-{
+-	static char led_names[6][6];
+-	int i, led = 0;
+-
+-	ar2315_led_data.num_leds = 0;
+-	for(i = 1; i < 8; i++)
+-	{
+-		if((i == AR2315_RESET_GPIO) ||
+-		   (i == ar231x_board.config->resetConfigGpio))
+-			continue;
+-
+-		if(i == ar231x_board.config->sysLedGpio)
+-			strcpy(led_names[led], "wlan");
+-		else
+-			sprintf(led_names[led], "gpio%d", i);
+-
+-		ar2315_leds[led].name = led_names[led];
+-		ar2315_leds[led].gpio = i;
+-		ar2315_leds[led].active_low = 0;
+-		led++;
+-	}
+-	ar2315_led_data.num_leds = led;
+-	platform_device_register(&ar2315_gpio_leds);
+-}
+-#else
+-static inline void ar2315_init_gpio(void)
+-{
+-}
+-#endif
+-
+ int __init
+ ar2315_init_devices(void)
+ {
+@@ -537,7 +490,6 @@
+ 	ar231x_find_config(ar2315_flash_limit());
+ 	ar2315_eth_data.macaddr = ar231x_board.config->enet0_mac;
+ 
+-	ar2315_init_gpio();
+ 	platform_device_register(&ar2315_wdt);
+ 	platform_device_register(&ar2315_spiflash);
+ 	ar231x_add_ethernet(0, AR2315_ENET0, AR2315_IRQ_ENET0_INTRS,
+diff -urN a/arch/mips/ar231x/ar5312.c b/arch/mips/ar231x/ar5312.c
+--- a/arch/mips/ar231x/ar5312.c	2010-10-24 15:33:03.865423290 +0700
++++ b/arch/mips/ar231x/ar5312.c	2010-10-24 15:08:48.354041241 +0700
+@@ -245,23 +245,6 @@
+ 	.num_resources = 1,
+ };
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar5312_leds[] = {
+-	{ .name = "wlan", .gpio = 0, .active_low = 1, },
+-};
+-
+-static const struct gpio_led_platform_data ar5312_led_data = {
+-	.num_leds = ARRAY_SIZE(ar5312_leds),
+-	.leds = (void *) ar5312_leds,
+-};
+-
+-static struct platform_device ar5312_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev.platform_data = (void *) &ar5312_led_data,
+-};
+-#endif
+-
+ /*
+  * NB: This mapping size is larger than the actual flash size,
+  * but this shouldn't be a problem here, because the flash
+@@ -350,11 +333,6 @@
+ 
+ 	platform_device_register(&ar5312_physmap_flash);
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-	ar5312_leds[0].gpio = config->sysLedGpio;
+-	platform_device_register(&ar5312_gpio_leds);
+-#endif
+-
+ 	/* Fix up MAC addresses if necessary */
+ 	if (!memcmp(config->enet0_mac, "\xff\xff\xff\xff\xff\xff", 6))
+ 		memcpy(config->enet0_mac, config->enet1_mac, 6);
+diff -urN a/arch/mips/ar231x/devices.c b/arch/mips/ar231x/devices.c
+--- a/arch/mips/ar231x/devices.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/devices.c	2010-10-24 20:48:48.011645424 +0700
+@@ -1,14 +1,31 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ #include <linux/serial.h>
+ #include <linux/serial_core.h>
+ #include <linux/serial_8250.h>
+ #include <linux/platform_device.h>
+ #include <ar231x_platform.h>
+ #include <ar231x.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
+ #include "devices.h"
+ #include "ar5312.h"
+ #include "ar2315.h"
++#include "machtype.h"
++#include "gpio.h"
+ 
+ struct ar231x_board_config ar231x_board;
+ int ar231x_devtype = DEV_TYPE_UNKNOWN;
+@@ -159,6 +176,38 @@
+ 	return platform_device_register(&ar231x_wmac[nr]);
+ }
+ 
++static int board_init = 0;
++
++static void __init
++ar231x_set_default_mach(void)
++{
++        mips_machtype = AR231X_MACH_GENERIC;
++}
++
++static int __init
++ar231x_machtype_setup(char *board)
++{
++	int machtype  = mips_machtype_setup(board);
++	/* Use generic if board not detected */
++	if (machtype) {
++		ar231x_set_default_mach();
++	}
++	board_init = 1;
++
++	return 0;
++}
++
++__setup("board=", ar231x_machtype_setup);
++
++int __init
++ar231x_machine_setup(void)
++{
++	if (!board_init) ar231x_set_default_mach();
++	mips_machine_setup();
++
++	return 0;
++}
++
+ static int __init ar231x_register_devices(void)
+ {
+ 	static struct resource res = {
+@@ -169,7 +218,39 @@
+ 	ar5312_init_devices();
+ 	ar2315_init_devices();
+ 
++	ar231x_machine_setup();
++	ar231x_register_gpio();
++
+ 	return 0;
+ }
+ 
+ device_initcall(ar231x_register_devices);
++
++void __init
++ar231x_generic_gpio_setup(void)
++{
++#ifdef CONFIG_LEDS_GPIO
++#define LED_NAME_SZ 7
++	int i, n;
++        char *led_name;
++        n = is_2315() ? AR2315_NUM_GPIO : AR531X_NUM_GPIO;
++
++        for (i = 1; i <= n; i++)
++        {
++                if((i == AR2315_RESET_GPIO && is_2315()) ||
++                   (i == ar231x_board.config->resetConfigGpio))
++                        continue;
++
++                led_name = (char *) kmalloc(LED_NAME_SZ, GFP_KERNEL);
++		if(led_name == NULL) continue;
++		if(i == ar231x_board.config->sysLedGpio)
++                        strcpy(led_name, "wlan");
++                else
++                        sprintf(led_name, "gpio%d", i);
++                ar231x_add_led(led_name, i);
++        }
++#endif
++}
++
++MIPS_MACHINE(AR231X_MACH_GENERIC, "GENERIC", "Atheros AR231X Generic Board",
++                ar231x_generic_gpio_setup);
+diff -urN a/arch/mips/ar231x/gpio.c b/arch/mips/ar231x/gpio.c
+--- a/arch/mips/ar231x/gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.c	2010-10-24 22:20:32.859506793 +0700
+@@ -0,0 +1,167 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/leds.h>
++#include <linux/gpio_buttons.h>
++#include <linux/input.h>
++#include <ar231x_platform.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
++
++#include "devices.h"
++
++#define AR231X_MAX_LEDS 6 
++
++static struct gpio_led ar231x_leds[AR231X_MAX_LEDS];
++static int led = 0, led_default_active_low = 0;
++
++void __init
++ar231x_set_led_default_active_low(int active_low)
++{
++	led_default_active_low = active_low;
++}
++
++void __init
++ar231x_add_led(char *name, int gpio)
++{
++        if (led >= AR231X_MAX_LEDS) return;
++        ar231x_leds[led].name = name;
++        ar231x_leds[led].gpio = gpio;
++        ar231x_leds[led].active_low = led_default_active_low;
++        led++;
++}
++
++void __init
++ar231x_register_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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_leds:
++        kfree(p);
++}
++
++#define AR231X_MAX_BUTTONS              2
++#define AR231X_BUTTONS_POLL_INTERVAL    20
++
++static struct gpio_button ar231x_buttons[AR231X_MAX_BUTTONS];
++static int button = 0, button_default_threshold = 3, button_default_active_low = 0;
++
++void __init
++ar231x_set_button_default_active_low(int active_low)
++{
++	button_default_active_low = active_low;
++}
++
++void __init
++ar231x_set_button_default_threshold(int threshold)
++{
++	button_default_threshold = threshold;
++}
++
++void __init
++ar231x_add_button(char *desc, int code, int gpio)
++{
++        if (button >= AR231X_MAX_BUTTONS) return;
++        ar231x_buttons[button].desc = desc;
++        ar231x_buttons[button].type = EV_KEY;
++        ar231x_buttons[button].code = code;
++        ar231x_buttons[button].gpio = gpio;
++        ar231x_buttons[button].threshold = button_default_threshold;
++        ar231x_buttons[button].active_low = button_default_active_low;
++        button++;
++}
++
++void __init
++ar231x_register_gpio_buttons(int id, unsigned poll_interval, unsigned nbuttons,
++		struct gpio_button *buttons)
++{
++        struct platform_device *pdev;
++        struct gpio_buttons_platform_data pdata;
++        struct gpio_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-buttons", id);
++        if (!pdev)
++                goto err_free_buttons;
++
++        memset(&pdata, 0, sizeof(pdata));
++        pdata.poll_interval = poll_interval;
++        pdata.nbuttons = nbuttons;
++        pdata.buttons = 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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_buttons:
++        kfree(p);
++}
++
++void __init
++ar231x_register_gpio(void)
++{
++        if (button) {
++                ar231x_register_gpio_buttons(-1, AR231X_BUTTONS_POLL_INTERVAL, button, ar231x_buttons);
++        }
++        if (led) {
++		ar231x_register_leds_gpio(-1, led, ar231x_leds);
++        }
++}
+diff -urN a/arch/mips/ar231x/gpio.h b/arch/mips/ar231x/gpio.h
+--- a/arch/mips/ar231x/gpio.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.h	2010-10-24 21:01:53.108447507 +0700
+@@ -0,0 +1,25 @@
++#ifndef __GPIO_H
++#define __GPIO_H
++
++#ifdef CONFIG_ATHEROS_AR231X_GPIO
++
++extern void ar231x_register_gpio(void);
++extern void ar231x_set_led_default_active_low(int active_low);
++extern void ar231x_add_led(char *name, int gpio);
++extern void ar231x_set_button_default_active_low(int active_low);
++extern void ar231x_set_button_default_threshold(int threshold);
++extern void ar231x_add_button(char *desc, int code, int gpio);
++
++#else
++
++static inline void ar231x_register_gpio(void) {}
++static inline void ar231x_set_led_default_active_low(int active_low) {}
++static inline void ar231x_add_led(char *name, int gpio) {}
++static inline void ar231x_set_button_default_active_low(int active_low) {}
++static inline void ar231x_set_button_default_threshold(int threshold) {}
++static inline void ar231x_add_button(char *desc, int code, int gpio) {}
++
++#endif
++
++
++#endif
+diff -urN a/arch/mips/ar231x/Kconfig b/arch/mips/ar231x/Kconfig
+--- a/arch/mips/ar231x/Kconfig	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/Kconfig	2010-10-24 21:10:13.655611973 +0700
+@@ -25,3 +25,13 @@
+ 	select USB_ARCH_HAS_OHCI
+ 	select USB_ARCH_HAS_EHCI
+ 	default y
++
++config ATHEROS_AR231X_GPIO
++	bool "Atheros 231X GPIO support"
++	depends on ATHEROS_AR231X
++	default y
++
++config ATHEROS_AR231X_MACH_DIR_300_A1
++	bool "D-LINK DIR-300 rev. A1 GPIO support"
++	depends on ATHEROS_AR231X
++	default n
+diff -urN a/arch/mips/ar231x/mach-dir-300-a1-gpio.c b/arch/mips/ar231x/mach-dir-300-a1-gpio.c
+--- a/arch/mips/ar231x/mach-dir-300-a1-gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/mach-dir-300-a1-gpio.c	2010-10-24 15:08:48.345675857 +0700
+@@ -0,0 +1,36 @@
++/*
++ *  D-Link DIR-300 rev. A1 GPIO support
++ *
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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/input.h>
++#include "machtype.h"
++#include "gpio.h"
++
++#define DIR_300_A1_GPIO_LED_SYSTEM	7
++#define DIR_300_A1_GPIO_LED_WLAN	2
++#define DIR_300_A1_GPIO_LED_WPS_BLUE	1
++#define DIR_300_A1_GPIO_LED_WPS_RED	3
++
++#define DIR_300_A1_GPIO_BUTTON_RESET	6
++#define DIR_300_A1_GPIO_BUTTON_WPS	4
++
++static void __init dir_300_a1_gpio_setup(void)
++{
++	ar231x_add_button("reset", KEY_RESTART, DIR_300_A1_GPIO_BUTTON_RESET);
++	ar231x_add_button("wps", KEY_WPS_BUTTON, DIR_300_A1_GPIO_BUTTON_WPS);
++	
++	ar231x_add_led("dir300:green:system", DIR_300_A1_GPIO_LED_SYSTEM);
++	ar231x_add_led("dir300:green:wlan", DIR_300_A1_GPIO_LED_WLAN);
++	ar231x_add_led("dir300:blue:wps", DIR_300_A1_GPIO_LED_WPS_BLUE);
++	ar231x_add_led("dir300:red:wps", DIR_300_A1_GPIO_LED_WPS_RED);
++}
++
++MIPS_MACHINE(AR231X_MACH_DIR_300_A1, "DIR-300-A1", "D-Link DIR-300 rev. A1",
++	     dir_300_a1_gpio_setup);
+diff -urN a/arch/mips/ar231x/machtype.h b/arch/mips/ar231x/machtype.h
+--- a/arch/mips/ar231x/machtype.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/machtype.h	2010-10-24 15:08:48.354041241 +0700
+@@ -0,0 +1,23 @@
++/*
++ *  Atheros AR231X machine type definitions
++ *
++ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
++ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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 _AR231X_MACHTYPE_H
++#define _AR231X_MACHTYPE_H
++
++#include <asm/mips_machine.h>
++
++enum ar231x_mach_type {
++	AR231X_MACH_GENERIC = 0,
++	AR231X_MACH_DIR_300_A1,	/* D-Link DIR-300 rev. A1 */
++};
++
++#endif /* _AR231X_MACHTYPE_H */
+diff -urN a/arch/mips/ar231x/Makefile b/arch/mips/ar231x/Makefile
+--- a/arch/mips/ar231x/Makefile	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/Makefile	2010-10-24 20:59:31.735693794 +0700
+@@ -15,3 +15,5 @@
+ obj-$(CONFIG_ATHEROS_AR5312) += ar5312.o
+ obj-$(CONFIG_ATHEROS_AR2315) += ar2315.o
+ obj-$(CONFIG_ATHEROS_AR2315_PCI) += pci.o
++obj-$(CONFIG_ATHEROS_AR231X_GPIO) += gpio.o
++obj-$(CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1) += mach-dir-300-a1-gpio.o
+diff -urN a/arch/mips/ar231x/prom.c b/arch/mips/ar231x/prom.c
+--- a/arch/mips/ar231x/prom.c	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/prom.c	2010-10-24 23:38:31.312244791 +0700
+@@ -26,8 +26,42 @@
+ #include "ar5312.h"
+ #include "ar2315.h"
+ 
++#ifdef CONFIG_IMAGE_CMDLINE_HACK
++extern char __image_cmdline[];
++
++static int __init ar231x_use__image_cmdline(void)
++{
++        char *p = __image_cmdline;
++        int replace = 0;
++
++        if (*p == '-') {
++                replace = 1;
++                p++;
++        }
++
++        if (*p == '\0')
++                return 0;
++
++	if (strlen(arcs_cmdline) == 0)
++		replace = 1;
++
++        if (replace) {
++                strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline));
++        } else {
++                strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
++                strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
++        }
++
++        return 1;
++}
++#else
++static int inline ar231x_use__image_cmdline(void) { return 0; }
++#endif
++
+ void __init prom_init(void)
+ {
++	ar231x_use__image_cmdline();
++
+ 	ar5312_prom_init();
+ 	ar2315_prom_init();
+ }
+diff -urN a/arch/mips/Kconfig b/arch/mips/Kconfig
+--- a/arch/mips/Kconfig	2010-10-24 15:33:04.157474056 +0700
++++ b/arch/mips/Kconfig	2010-10-24 15:08:48.681423282 +0700
+@@ -95,6 +95,7 @@
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select GENERIC_GPIO
+ 	select SYS_HAS_EARLY_PRINTK
++	select MIPS_MACHINE
+ 	help
+ 	  Support for AR231x and AR531x based boards
+ 
Index: target/linux/atheros/patches-2.6.33/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch
===================================================================
--- target/linux/atheros/patches-2.6.33/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
+++ target/linux/atheros/patches-2.6.33/300-mips_machine_support+image_cmdline_hack+mach_dir_300_a1.patch	(revision 0)
@@ -0,0 +1,575 @@
+diff -urN a/arch/mips/ar231x/ar2315.c b/arch/mips/ar231x/ar2315.c
+--- a/arch/mips/ar231x/ar2315.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/ar2315.c	2010-10-24 15:42:23.673791281 +0700
+@@ -22,7 +22,6 @@
+ #include <linux/kernel.h>
+ #include <linux/reboot.h>
+ #include <linux/delay.h>
+-#include <linux/leds.h>
+ #include <asm/bootinfo.h>
+ #include <asm/reboot.h>
+ #include <asm/time.h>
+@@ -481,52 +480,6 @@
+ 	return (u8 *) ar2315_spiflash_res[0].end + 1;
+ }
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar2315_leds[6];
+-static struct gpio_led_platform_data ar2315_led_data = {
+-	.leds = (void *) ar2315_leds,
+-};
+-
+-static struct platform_device ar2315_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev = {
+-		.platform_data = (void *) &ar2315_led_data,
+-	}
+-};
+-
+-static void __init
+-ar2315_init_gpio(void)
+-{
+-	static char led_names[6][6];
+-	int i, led = 0;
+-
+-	ar2315_led_data.num_leds = 0;
+-	for(i = 1; i < 8; i++)
+-	{
+-		if((i == AR2315_RESET_GPIO) ||
+-		   (i == ar231x_board.config->resetConfigGpio))
+-			continue;
+-
+-		if(i == ar231x_board.config->sysLedGpio)
+-			strcpy(led_names[led], "wlan");
+-		else
+-			sprintf(led_names[led], "gpio%d", i);
+-
+-		ar2315_leds[led].name = led_names[led];
+-		ar2315_leds[led].gpio = i;
+-		ar2315_leds[led].active_low = 0;
+-		led++;
+-	}
+-	ar2315_led_data.num_leds = led;
+-	platform_device_register(&ar2315_gpio_leds);
+-}
+-#else
+-static inline void ar2315_init_gpio(void)
+-{
+-}
+-#endif
+-
+ int __init
+ ar2315_init_devices(void)
+ {
+@@ -537,7 +490,6 @@
+ 	ar231x_find_config(ar2315_flash_limit());
+ 	ar2315_eth_data.macaddr = ar231x_board.config->enet0_mac;
+ 
+-	ar2315_init_gpio();
+ 	platform_device_register(&ar2315_wdt);
+ 	platform_device_register(&ar2315_spiflash);
+ 	ar231x_add_ethernet(0, AR2315_ENET0, AR2315_IRQ_ENET0_INTRS,
+diff -urN a/arch/mips/ar231x/ar5312.c b/arch/mips/ar231x/ar5312.c
+--- a/arch/mips/ar231x/ar5312.c	2010-10-24 15:33:03.865423290 +0700
++++ b/arch/mips/ar231x/ar5312.c	2010-10-24 15:08:48.354041241 +0700
+@@ -245,23 +245,6 @@
+ 	.num_resources = 1,
+ };
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-static struct gpio_led ar5312_leds[] = {
+-	{ .name = "wlan", .gpio = 0, .active_low = 1, },
+-};
+-
+-static const struct gpio_led_platform_data ar5312_led_data = {
+-	.num_leds = ARRAY_SIZE(ar5312_leds),
+-	.leds = (void *) ar5312_leds,
+-};
+-
+-static struct platform_device ar5312_gpio_leds = {
+-	.name = "leds-gpio",
+-	.id = -1,
+-	.dev.platform_data = (void *) &ar5312_led_data,
+-};
+-#endif
+-
+ /*
+  * NB: This mapping size is larger than the actual flash size,
+  * but this shouldn't be a problem here, because the flash
+@@ -350,11 +333,6 @@
+ 
+ 	platform_device_register(&ar5312_physmap_flash);
+ 
+-#ifdef CONFIG_LEDS_GPIO
+-	ar5312_leds[0].gpio = config->sysLedGpio;
+-	platform_device_register(&ar5312_gpio_leds);
+-#endif
+-
+ 	/* Fix up MAC addresses if necessary */
+ 	if (!memcmp(config->enet0_mac, "\xff\xff\xff\xff\xff\xff", 6))
+ 		memcpy(config->enet0_mac, config->enet1_mac, 6);
+diff -urN a/arch/mips/ar231x/devices.c b/arch/mips/ar231x/devices.c
+--- a/arch/mips/ar231x/devices.c	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/devices.c	2010-10-24 20:48:48.011645424 +0700
+@@ -1,14 +1,31 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
+ #include <linux/serial.h>
+ #include <linux/serial_core.h>
+ #include <linux/serial_8250.h>
+ #include <linux/platform_device.h>
+ #include <ar231x_platform.h>
+ #include <ar231x.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
+ #include "devices.h"
+ #include "ar5312.h"
+ #include "ar2315.h"
++#include "machtype.h"
++#include "gpio.h"
+ 
+ struct ar231x_board_config ar231x_board;
+ int ar231x_devtype = DEV_TYPE_UNKNOWN;
+@@ -159,6 +176,38 @@
+ 	return platform_device_register(&ar231x_wmac[nr]);
+ }
+ 
++static int board_init = 0;
++
++static void __init
++ar231x_set_default_mach(void)
++{
++        mips_machtype = AR231X_MACH_GENERIC;
++}
++
++static int __init
++ar231x_machtype_setup(char *board)
++{
++	int machtype  = mips_machtype_setup(board);
++	/* Use generic if board not detected */
++	if (machtype) {
++		ar231x_set_default_mach();
++	}
++	board_init = 1;
++
++	return 0;
++}
++
++__setup("board=", ar231x_machtype_setup);
++
++int __init
++ar231x_machine_setup(void)
++{
++	if (!board_init) ar231x_set_default_mach();
++	mips_machine_setup();
++
++	return 0;
++}
++
+ static int __init ar231x_register_devices(void)
+ {
+ 	static struct resource res = {
+@@ -169,7 +218,39 @@
+ 	ar5312_init_devices();
+ 	ar2315_init_devices();
+ 
++	ar231x_machine_setup();
++	ar231x_register_gpio();
++
+ 	return 0;
+ }
+ 
+ device_initcall(ar231x_register_devices);
++
++void __init
++ar231x_generic_gpio_setup(void)
++{
++#ifdef CONFIG_LEDS_GPIO
++#define LED_NAME_SZ 7
++	int i, n;
++        char *led_name;
++        n = is_2315() ? AR2315_NUM_GPIO : AR531X_NUM_GPIO;
++
++        for (i = 1; i <= n; i++)
++        {
++                if((i == AR2315_RESET_GPIO && is_2315()) ||
++                   (i == ar231x_board.config->resetConfigGpio))
++                        continue;
++
++                led_name = (char *) kmalloc(LED_NAME_SZ, GFP_KERNEL);
++		if(led_name == NULL) continue;
++		if(i == ar231x_board.config->sysLedGpio)
++                        strcpy(led_name, "wlan");
++                else
++                        sprintf(led_name, "gpio%d", i);
++                ar231x_add_led(led_name, i);
++        }
++#endif
++}
++
++MIPS_MACHINE(AR231X_MACH_GENERIC, "GENERIC", "Atheros AR231X Generic Board",
++                ar231x_generic_gpio_setup);
+diff -urN a/arch/mips/ar231x/gpio.c b/arch/mips/ar231x/gpio.c
+--- a/arch/mips/ar231x/gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.c	2010-10-24 22:20:32.859506793 +0700
+@@ -0,0 +1,167 @@
++/*
++ * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved.
++ * Copyright (C) 2006 FON Technology, SL.
++ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ */
++
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/leds.h>
++#include <linux/gpio_buttons.h>
++#include <linux/input.h>
++#include <ar231x_platform.h>
++#include <ar2315_regs.h>
++#include <ar5312_regs.h>
++
++#include "devices.h"
++
++#define AR231X_MAX_LEDS 6 
++
++static struct gpio_led ar231x_leds[AR231X_MAX_LEDS];
++static int led = 0, led_default_active_low = 0;
++
++void __init
++ar231x_set_led_default_active_low(int active_low)
++{
++	led_default_active_low = active_low;
++}
++
++void __init
++ar231x_add_led(char *name, int gpio)
++{
++        if (led >= AR231X_MAX_LEDS) return;
++        ar231x_leds[led].name = name;
++        ar231x_leds[led].gpio = gpio;
++        ar231x_leds[led].active_low = led_default_active_low;
++        led++;
++}
++
++void __init
++ar231x_register_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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_leds:
++        kfree(p);
++}
++
++#define AR231X_MAX_BUTTONS              2
++#define AR231X_BUTTONS_POLL_INTERVAL    20
++
++static struct gpio_button ar231x_buttons[AR231X_MAX_BUTTONS];
++static int button = 0, button_default_threshold = 3, button_default_active_low = 0;
++
++void __init
++ar231x_set_button_default_active_low(int active_low)
++{
++	button_default_active_low = active_low;
++}
++
++void __init
++ar231x_set_button_default_threshold(int threshold)
++{
++	button_default_threshold = threshold;
++}
++
++void __init
++ar231x_add_button(char *desc, int code, int gpio)
++{
++        if (button >= AR231X_MAX_BUTTONS) return;
++        ar231x_buttons[button].desc = desc;
++        ar231x_buttons[button].type = EV_KEY;
++        ar231x_buttons[button].code = code;
++        ar231x_buttons[button].gpio = gpio;
++        ar231x_buttons[button].threshold = button_default_threshold;
++        ar231x_buttons[button].active_low = button_default_active_low;
++        button++;
++}
++
++void __init
++ar231x_register_gpio_buttons(int id, unsigned poll_interval, unsigned nbuttons,
++		struct gpio_button *buttons)
++{
++        struct platform_device *pdev;
++        struct gpio_buttons_platform_data pdata;
++        struct gpio_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-buttons", id);
++        if (!pdev)
++                goto err_free_buttons;
++
++        memset(&pdata, 0, sizeof(pdata));
++        pdata.poll_interval = poll_interval;
++        pdata.nbuttons = nbuttons;
++        pdata.buttons = 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;
++
++err_put_pdev:
++        platform_device_put(pdev);
++
++err_free_buttons:
++        kfree(p);
++}
++
++void __init
++ar231x_register_gpio(void)
++{
++        if (button) {
++                ar231x_register_gpio_buttons(-1, AR231X_BUTTONS_POLL_INTERVAL, button, ar231x_buttons);
++        }
++        if (led) {
++		ar231x_register_leds_gpio(-1, led, ar231x_leds);
++        }
++}
+diff -urN a/arch/mips/ar231x/gpio.h b/arch/mips/ar231x/gpio.h
+--- a/arch/mips/ar231x/gpio.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/gpio.h	2010-10-24 21:01:53.108447507 +0700
+@@ -0,0 +1,25 @@
++#ifndef __GPIO_H
++#define __GPIO_H
++
++#ifdef CONFIG_ATHEROS_AR231X_GPIO
++
++extern void ar231x_register_gpio(void);
++extern void ar231x_set_led_default_active_low(int active_low);
++extern void ar231x_add_led(char *name, int gpio);
++extern void ar231x_set_button_default_active_low(int active_low);
++extern void ar231x_set_button_default_threshold(int threshold);
++extern void ar231x_add_button(char *desc, int code, int gpio);
++
++#else
++
++static inline void ar231x_register_gpio(void) {}
++static inline void ar231x_set_led_default_active_low(int active_low) {}
++static inline void ar231x_add_led(char *name, int gpio) {}
++static inline void ar231x_set_button_default_active_low(int active_low) {}
++static inline void ar231x_set_button_default_threshold(int threshold) {}
++static inline void ar231x_add_button(char *desc, int code, int gpio) {}
++
++#endif
++
++
++#endif
+diff -urN a/arch/mips/ar231x/Kconfig b/arch/mips/ar231x/Kconfig
+--- a/arch/mips/ar231x/Kconfig	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/Kconfig	2010-10-24 21:10:13.655611973 +0700
+@@ -25,3 +25,13 @@
+ 	select USB_ARCH_HAS_OHCI
+ 	select USB_ARCH_HAS_EHCI
+ 	default y
++
++config ATHEROS_AR231X_GPIO
++	bool "Atheros 231X GPIO support"
++	depends on ATHEROS_AR231X
++	default y
++
++config ATHEROS_AR231X_MACH_DIR_300_A1
++	bool "D-LINK DIR-300 rev. A1 GPIO support"
++	depends on ATHEROS_AR231X
++	default n
+diff -urN a/arch/mips/ar231x/mach-dir-300-a1-gpio.c b/arch/mips/ar231x/mach-dir-300-a1-gpio.c
+--- a/arch/mips/ar231x/mach-dir-300-a1-gpio.c	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/mach-dir-300-a1-gpio.c	2010-10-24 15:08:48.345675857 +0700
+@@ -0,0 +1,36 @@
++/*
++ *  D-Link DIR-300 rev. A1 GPIO support
++ *
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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/input.h>
++#include "machtype.h"
++#include "gpio.h"
++
++#define DIR_300_A1_GPIO_LED_SYSTEM	7
++#define DIR_300_A1_GPIO_LED_WLAN	2
++#define DIR_300_A1_GPIO_LED_WPS_BLUE	1
++#define DIR_300_A1_GPIO_LED_WPS_RED	3
++
++#define DIR_300_A1_GPIO_BUTTON_RESET	6
++#define DIR_300_A1_GPIO_BUTTON_WPS	4
++
++static void __init dir_300_a1_gpio_setup(void)
++{
++	ar231x_add_button("reset", KEY_RESTART, DIR_300_A1_GPIO_BUTTON_RESET);
++	ar231x_add_button("wps", KEY_WPS_BUTTON, DIR_300_A1_GPIO_BUTTON_WPS);
++	
++	ar231x_add_led("dir300:green:system", DIR_300_A1_GPIO_LED_SYSTEM);
++	ar231x_add_led("dir300:green:wlan", DIR_300_A1_GPIO_LED_WLAN);
++	ar231x_add_led("dir300:blue:wps", DIR_300_A1_GPIO_LED_WPS_BLUE);
++	ar231x_add_led("dir300:red:wps", DIR_300_A1_GPIO_LED_WPS_RED);
++}
++
++MIPS_MACHINE(AR231X_MACH_DIR_300_A1, "DIR-300-A1", "D-Link DIR-300 rev. A1",
++	     dir_300_a1_gpio_setup);
+diff -urN a/arch/mips/ar231x/machtype.h b/arch/mips/ar231x/machtype.h
+--- a/arch/mips/ar231x/machtype.h	1970-01-01 07:00:00.000000000 +0700
++++ b/arch/mips/ar231x/machtype.h	2010-10-24 15:08:48.354041241 +0700
+@@ -0,0 +1,23 @@
++/*
++ *  Atheros AR231X machine type definitions
++ *
++ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
++ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
++ *  Copyright (C) 2010 Toha <tohenk@yahoo.com>
++ *
++ *  This program is free software; you can 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 _AR231X_MACHTYPE_H
++#define _AR231X_MACHTYPE_H
++
++#include <asm/mips_machine.h>
++
++enum ar231x_mach_type {
++	AR231X_MACH_GENERIC = 0,
++	AR231X_MACH_DIR_300_A1,	/* D-Link DIR-300 rev. A1 */
++};
++
++#endif /* _AR231X_MACHTYPE_H */
+diff -urN a/arch/mips/ar231x/Makefile b/arch/mips/ar231x/Makefile
+--- a/arch/mips/ar231x/Makefile	2010-10-24 15:33:03.857402034 +0700
++++ b/arch/mips/ar231x/Makefile	2010-10-24 20:59:31.735693794 +0700
+@@ -15,3 +15,5 @@
+ obj-$(CONFIG_ATHEROS_AR5312) += ar5312.o
+ obj-$(CONFIG_ATHEROS_AR2315) += ar2315.o
+ obj-$(CONFIG_ATHEROS_AR2315_PCI) += pci.o
++obj-$(CONFIG_ATHEROS_AR231X_GPIO) += gpio.o
++obj-$(CONFIG_ATHEROS_AR231X_MACH_DIR_300_A1) += mach-dir-300-a1-gpio.o
+diff -urN a/arch/mips/ar231x/prom.c b/arch/mips/ar231x/prom.c
+--- a/arch/mips/ar231x/prom.c	2010-10-24 15:33:03.861449400 +0700
++++ b/arch/mips/ar231x/prom.c	2010-10-24 23:38:31.312244791 +0700
+@@ -26,8 +26,42 @@
+ #include "ar5312.h"
+ #include "ar2315.h"
+ 
++#ifdef CONFIG_IMAGE_CMDLINE_HACK
++extern char __image_cmdline[];
++
++static int __init ar231x_use__image_cmdline(void)
++{
++        char *p = __image_cmdline;
++        int replace = 0;
++
++        if (*p == '-') {
++                replace = 1;
++                p++;
++        }
++
++        if (*p == '\0')
++                return 0;
++
++	if (strlen(arcs_cmdline) == 0)
++		replace = 1;
++
++        if (replace) {
++                strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline));
++        } else {
++                strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
++                strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
++        }
++
++        return 1;
++}
++#else
++static int inline ar231x_use__image_cmdline(void) { return 0; }
++#endif
++
+ void __init prom_init(void)
+ {
++	ar231x_use__image_cmdline();
++
+ 	ar5312_prom_init();
+ 	ar2315_prom_init();
+ }
+diff -urN a/arch/mips/Kconfig b/arch/mips/Kconfig
+--- a/arch/mips/Kconfig	2010-10-24 15:33:04.157474056 +0700
++++ b/arch/mips/Kconfig	2010-10-24 15:08:48.681423282 +0700
+@@ -95,6 +95,7 @@
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select GENERIC_GPIO
+ 	select SYS_HAS_EARLY_PRINTK
++	select MIPS_MACHINE
+ 	help
+ 	  Support for AR231x and AR531x based boards
+ 
Index: package/swconfig/files/switch.sh
===================================================================
--- package/swconfig/files/switch.sh	(revision 23620)
+++ package/swconfig/files/switch.sh	(working copy)
@@ -4,11 +4,18 @@
 setup_switch_dev() {
 	config_get name "$1" name
 	name="${name:-$1}"
-	[ -d "/sys/class/net/$name" ] && ifconfig "$name" up
-	swconfig dev "$name" load network
+	[ ! -f "/var/run/switch-${name}.lock" ] && {
+		touch "/var/run/switch-${name}.lock"
+		[ -d "/sys/class/net/$name" ] && ifconfig "$name" up
+		swconfig dev "$name" load network
+	}
 }
 
 setup_switch() {
 	config_load network
 	config_foreach setup_switch_dev switch
 }
+
+reset_switch() {
+	rm -f "/var/run/switch-*.lock"
+}
Index: package/hostapd/files/hostapd-full.config
===================================================================
--- package/hostapd/files/hostapd-full.config	(revision 23620)
+++ package/hostapd/files/hostapd-full.config	(working copy)
@@ -107,7 +107,7 @@
 #CONFIG_EAP_FAST=y
 
 # Wi-Fi Protected Setup (WPS)
-#CONFIG_WPS=y
+CONFIG_WPS=y
 # Enable UPnP support for external WPS Registrars
 #CONFIG_WPS_UPNP=y
 
@@ -156,5 +156,3 @@
 CONFIG_INTERNAL_LIBTOMMATH=y
 CONFIG_INTERNAL_AES=y
 NEED_AES_DEC=y
-
-CONFIG_WPS=y
Index: package/hostapd/files/hostapd.sh
===================================================================
--- package/hostapd/files/hostapd.sh	(revision 23620)
+++ package/hostapd/files/hostapd.sh	(working copy)
@@ -1,7 +1,7 @@
 hostapd_set_bss_options() {
 	local var="$1"
 	local vif="$2"
-	local enc wpa_group_rekey wps_possible
+	local enc wpa_group_rekey wps_possible wpa_psk_file wps_pin_file
 
 	config_get enc "$vif" encryption
 	config_get wpa_group_rekey "$vif" wpa_group_rekey
@@ -120,10 +120,35 @@
 
 	config_get_bool wps_pbc "$vif" wps_pushbutton 0
 	[ -n "$wps_possible" -a "$wps_pbc" -gt 0 ] && {
+		wpa_psk_file="/etc/hostapd.psk"
+		wps_pin_file="/var/run/hostapd-$ifname.pin"
+		[ ! -f "$wpa_psk_file" ] && touch "$wpa_psk_file"
+		[ ! -f "$wps_pin_file" ] && touch "$wps_pin_file"
+
+		config_get wps_dev_name "$vif" wps_device_name "Wireless AP"
+		config_get wps_manuf "$vif" wps_manufacturer "OpenWrt"
+		config_get wps_model_name "$vif" wps_model_name "Generic"
+		config_get wps_model_number "$vif" wps_model_number "000"
+		config_get wps_sn "$vif" wps_serial_number "00000"
+		config_get wps_dev_type "$vif" wps_device_type "6-0050F204-1"
+		config_get wps_os_ver "$vif" wps_os_version "00000000"
+		config_get wps_pin "$vif" wps_pin "12345678"
+
+		append "$var" "wpa_psk_file=$wpa_psk_file" "$N"
+		append "$var" "wps_pin_requests=$wps_pin_file" "$N"
 		append "$var" "eap_server=1" "$N"
 		append "$var" "wps_state=2" "$N"
 		append "$var" "ap_setup_locked=1" "$N"
-		append "$var" "config_methods=push_button" "$N"
+		append "$var" "config_methods=label display push_button keypad" "$N"
+		append "$var" "ap_pin=$wps_pin" "$N"
+		
+		append "$var" "device_name=$wps_dev_name" "$N"
+		append "$var" "manufacturer=$wps_manuf" "$N"
+		append "$var" "model_name=$wps_model_name" "$N"
+		append "$var" "model_number=$wps_model_number" "$N"
+		append "$var" "serial_number=$wps_sn" "$N"
+		append "$var" "device_type=$wps_dev_type" "$N"
+		append "$var" "os_version=$wps_os_ver" "$N"
 	}
 
 	append "$var" "ssid=$ssid" "$N"
Index: package/base-files/files/etc/init.d/network
===================================================================
--- package/base-files/files/etc/init.d/network	(revision 23620)
+++ package/base-files/files/etc/init.d/network	(working copy)
@@ -45,5 +45,9 @@
 }
 
 restart() {
+	reset_switch() { return 0; }
+	
+	include /lib/network
+	reset_switch
 	start
 }
Index: package/libnl-tiny/Makefile
===================================================================
--- package/libnl-tiny/Makefile	(revision 23620)
+++ package/libnl-tiny/Makefile	(working copy)
@@ -47,6 +47,7 @@
 define Package/libnl-tiny/install
 	$(INSTALL_DIR) $(1)/usr/lib
 	$(CP) $(PKG_BUILD_DIR)/libnl-tiny.so $(1)/usr/lib/
+	cd $(1)/usr/lib/; ln -sf libnl-tiny.so libnl.so.1
 endef
 
 $(eval $(call BuildPackage,libnl-tiny))
Index: package/button-hotplug/Makefile
===================================================================
--- package/button-hotplug/Makefile	(revision 23620)
+++ package/button-hotplug/Makefile	(working copy)
@@ -18,6 +18,7 @@
   TITLE:=Button Hotplug driver
   FILES:=$(PKG_BUILD_DIR)/button-hotplug.ko
   KCONFIG:=
+  AUTOLOAD:=$(call AutoLoad,63,button-hotplug)
 endef
 
 define KernelPackage/button-hotplug/description

