--- a/ath/if_ath_ahb.c
+++ b/ath/if_ath_ahb.c
@@ -33,20 +33,15 @@
 #include "if_ath_ahb.h"
 #include "ah_soc.h"
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-#error "Kernel versions older than 2.6.19 are not supported!"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+#include <ar231x_platform.h>
 #endif
 
 struct ath_ahb_softc {
 	struct ath_softc	aps_sc;
-#ifdef CONFIG_PM
-	u32 aps_pmstate[16];
-#endif
+	struct ar531x_config aps_config;
 };
 
-static struct ath_ahb_softc *sclist[2] = {NULL, NULL};
-static u_int8_t num_activesc = 0;
-
 /*
  * Module glue.
  */
@@ -101,13 +96,13 @@ ahb_enable_wmac(u_int16_t devid, u_int16
 		while (REG_READ(AR5315_PCI_MAC_PCICFG) & AR5315_PCI_MAC_PCICFG_SPWR_DN);
 	} else {
 		switch (wlanNum) {
-		case AR531X_WLAN0_NUM:
+		case 0:
 			reset = (AR531X_RESET_WLAN0 |
 				AR531X_RESET_WARM_WLAN0_MAC |
 				AR531X_RESET_WARM_WLAN0_BB);
 			enable = AR531X_ENABLE_WLAN0;
 			break;
-		case AR531X_WLAN1_NUM:
+		case 1:
 			reset = (AR531X_RESET_WLAN1 |
 				AR531X_RESET_WARM_WLAN1_MAC |
 				AR531X_RESET_WARM_WLAN1_BB);
@@ -144,10 +139,10 @@ ahb_disable_wmac(u_int16_t devid, u_int1
 		*en &= ~AR5315_ARB_WLAN;
 	} else {
 		switch (wlanNum) {
-		case AR531X_WLAN0_NUM:
+		case 0:
 			enable = AR531X_ENABLE_WLAN0;
 			break;
-		case AR531X_WLAN1_NUM:
+		case 1:
 			enable = AR531X_ENABLE_WLAN1;
 			break;
 		default:
@@ -159,29 +154,6 @@ ahb_disable_wmac(u_int16_t devid, u_int1
 }
 
 
-static int
-exit_ath_wmac(u_int16_t wlanNum, struct ar531x_config *config)
-{
-	struct ath_ahb_softc *sc = sclist[wlanNum];
-	struct net_device *dev;
-	u_int16_t devid;
-
-	if (sc == NULL)
-		return -ENODEV; /* XXX: correct return value? */
-
-	dev = sc->aps_sc.sc_dev;
-	ath_detach(dev);
-	if (dev->irq)
-		free_irq(dev->irq, dev);
-	devid = sc->aps_sc.devid;
-	config->tag = (void *)((unsigned long) devid);
-
-	ahb_disable_wmac(devid, wlanNum);
-	free_netdev(dev);
-	sclist[wlanNum] = NULL;
-	return 0;
-}
-
 static const char ubnt[] = "Ubiquiti Networks";
 /* { vendorname, cardname, vendorid, cardid, subsys vendorid, subsys id, poweroffset } */
 static const struct ath_hw_detect cards[] = {
@@ -201,6 +173,114 @@ static const struct ath_hw_detect cards[
 	{ ubnt, "Bullet5",             PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc205 },
 };
 
+static void
+ahb_hw_detect(struct ath_ahb_softc *sc, const char *radio)
+{
+	u16 *radio_data = (u16 *) radio;
+	if (radio_data) {
+		u16 vendor, id, subvendor, subid;
+		vendor = radio_data[1];
+		id = radio_data[0];
+		subvendor = radio_data[8];
+		subid = radio_data[7];
+		ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards), vendor, id, subvendor, subid);
+	}
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+
+static int ahb_wmac_probe(struct platform_device *pdev)
+{
+	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+	struct ath_ahb_softc *sc;
+	struct net_device *dev;
+	struct resource *res;
+	const char *athname;
+	int err;
+
+	ahb_enable_wmac(bcfg->devid, pdev->id);
+	dev = alloc_netdev(sizeof(struct ath_ahb_softc), "wifi%d", ether_setup);
+	if (!dev)
+		return -ENOMEM;
+
+	sc = dev->priv;
+	sc->aps_sc.sc_dev = dev;
+
+	dev->irq = platform_get_irq(pdev, 0);
+	if (dev->irq <= 0) {
+		printk("%s: Cannot find IRQ resource\n", dev->name);
+		goto error;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		printk("%s: Cannot find MMIO resource\n", dev->name);
+		goto error;
+	}
+
+	dev->mem_start = KSEG1ADDR(res->start);
+	dev->mem_end = KSEG1ADDR(res->end);
+	sc->aps_sc.sc_iobase = (void __iomem *) dev->mem_start;
+	sc->aps_sc.sc_bdev = NULL;
+
+	/* bus information for the HAL */
+	sc->aps_config.board = (const struct ar531x_boarddata *) bcfg->config;
+	sc->aps_config.radio = bcfg->radio;
+	sc->aps_config.unit = pdev->id;
+	sc->aps_config.tag = NULL;
+
+	err = ath_attach(bcfg->devid, dev, &sc->aps_config);
+	if (err != 0) {
+		printk("%s: ath_attach failed: %d\n", dev->name, err);
+		goto error;
+	}
+
+	athname = ath_hal_probe(ATHEROS_VENDOR_ID, bcfg->devid);
+	printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
+		dev_info, dev->name, athname ? athname : "Atheros ???", dev->mem_start, dev->irq);
+
+	if (request_irq(dev->irq, ath_intr, IRQF_SHARED|IRQF_DISABLED, dev->name, dev)) {
+		printk(KERN_WARNING "%s: %s: request_irq failed\n", dev_info, dev->name);
+		goto error;
+	}
+
+	sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
+	sc->aps_sc.sc_ledpin = bcfg->config->sysLedGpio;
+	sc->aps_sc.sc_invalid = 0;
+	ahb_hw_detect(sc, bcfg->radio);
+	platform_set_drvdata(pdev, dev);
+	return 0;
+
+error_dev:
+	free_irq(dev->irq, dev);
+error:
+	free_netdev(dev);
+
+	return -ENODEV;
+}
+
+
+static int ahb_wmac_remove(struct platform_device *pdev)
+{
+	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+	struct net_device *dev;
+
+	dev = platform_get_drvdata(pdev);
+	ath_detach(dev);
+
+	if (dev->irq)
+		free_irq(dev->irq, dev);
+
+	ahb_disable_wmac(bcfg->devid, pdev->id);
+	free_netdev(dev);
+
+	return 0;
+}
+
+#else
+
+static struct ath_ahb_softc *sclist[2] = {NULL, NULL};
+
 static int
 init_ath_wmac(u_int16_t devid, u_int16_t wlanNum, struct ar531x_config *config)
 {
@@ -253,7 +333,7 @@ init_ath_wmac(u_int16_t devid, u_int16_t
 	sc->aps_sc.sc_iobase = (void __iomem *) dev->mem_start;
 	sc->aps_sc.sc_bdev = NULL;
 
-	if (request_irq(dev->irq, ath_intr, IRQF_SHARED, dev->name, dev)) {
+	if (request_irq(dev->irq, ath_intr, IRQF_SHARED|IRQF_DISABLED, dev->name, dev)) {
 		printk(KERN_WARNING "%s: %s: request_irq failed\n", dev_info, dev->name);
 		goto bad3;
 	}
@@ -263,21 +343,12 @@ init_ath_wmac(u_int16_t devid, u_int16_t
 	athname = ath_hal_probe(ATHEROS_VENDOR_ID, devid);
 	printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
 		dev_info, dev->name, athname ? athname : "Atheros ???", dev->mem_start, dev->irq);
-	num_activesc++;
 	/* Ready to process interrupts */
 
 	sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
 	sc->aps_sc.sc_ledpin = config->board->sysLedGpio;
 	sc->aps_sc.sc_invalid = 0;
-	radio_data = (u16 *) config->radio;
-	if (radio_data) {
-		u16 vendor, id, subvendor, subid;
-		vendor = radio_data[1];
-		id = radio_data[0];
-		subvendor = radio_data[8];
-		subid = radio_data[7];
-		ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards), vendor, id, subvendor, subid);
-	}
+	ahb_hw_detect(sc, config->radio);
 
 	return 0;
 
@@ -292,6 +363,29 @@ init_ath_wmac(u_int16_t devid, u_int16_t
 	return -ENODEV;
 }
 
+static int
+exit_ath_wmac(u_int16_t wlanNum, struct ar531x_config *config)
+{
+	struct ath_ahb_softc *sc = sclist[wlanNum];
+	struct net_device *dev;
+	u_int16_t devid;
+
+	if (sc == NULL)
+		return -ENODEV; /* XXX: correct return value? */
+
+	dev = sc->aps_sc.sc_dev;
+	ath_detach(dev);
+	if (dev->irq)
+		free_irq(dev->irq, dev);
+	devid = sc->aps_sc.devid;
+	config->tag = (void *)((unsigned long) devid);
+
+	ahb_disable_wmac(devid, wlanNum);
+	free_netdev(dev);
+	sclist[wlanNum] = NULL;
+	return 0;
+}
+
 static int ahb_wmac_probe(struct platform_device *pdev)
 {
 	u_int16_t devid;
@@ -312,11 +406,18 @@ static int ahb_wmac_remove(struct platfo
 	return 0;
 }
 
+#endif
+
 static struct platform_driver ahb_wmac_driver = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+	.driver.name = "ar231x-wmac",
+#else
 	.driver.name = "ar531x-wmac",
+#endif
 	.probe = ahb_wmac_probe,
 	.remove = ahb_wmac_remove
 };
+
 int
 ath_ioctl_ethtool(struct ath_softc *sc, int cmd, void __user *addr)
 {