diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 8e2a3b8..2039051 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -189,7 +189,7 @@ static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type)
 			int_reg);
 
 	/* Configure the line as an input */
-	gpio_line_config(irq2gpio[d->irq], IXP4XX_GPIO_IN);
+	gpio_direction_input(line);
 
 	return 0;
 }
@@ -401,7 +401,8 @@ EXPORT_SYMBOL(ixp4xx_exp_bus_size);
 
 static int ixp4xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 {
-	gpio_line_config(gpio, IXP4XX_GPIO_IN);
+	writel_relaxed(readl_relaxed(IXP4XX_GPIO_GPOER) | (1 << gpio),
+		       IXP4XX_GPIO_GPOER);
 
 	return 0;
 }
@@ -409,25 +410,33 @@ static int ixp4xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 static int ixp4xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
 					int level)
 {
-	gpio_line_set(gpio, level);
-	gpio_line_config(gpio, IXP4XX_GPIO_OUT);
+	u32 outval = readl_relaxed(IXP4XX_GPIO_GPOUTR) & ~(1 << gpio);
+
+	if (level)
+		outval |= 1 << gpio;
+
+	writel_relaxed(outval, IXP4XX_GPIO_GPOUTR);
+
+	writel_relaxed(readl_relaxed(IXP4XX_GPIO_GPOER) & ~(1 << gpio),
+		       IXP4XX_GPIO_GPOER);
 
 	return 0;
 }
 
 static int ixp4xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
 {
-	int value;
-
-	gpio_line_get(gpio, &value);
-
-	return value;
+	return !!(readl_relaxed(IXP4XX_GPIO_GPINR) & (1 << gpio));
 }
 
 static void ixp4xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
 				  int value)
 {
-	gpio_line_set(gpio, value);
+	u32 outval = readl_relaxed(IXP4XX_GPIO_GPOUTR) & ~(1 << gpio);
+
+	if (value)
+		outval |= 1 << gpio;
+
+	writel_relaxed(outval, IXP4XX_GPIO_GPOUTR);
 }
 
 static struct gpio_chip ixp4xx_gpio_chip = {
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index 2f24df1..f6a80dc 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -161,10 +161,7 @@ static struct platform_device *dsmg600_devices[] __initdata = {
 static void dsmg600_power_off(void)
 {
 	/* enable the pwr cntl gpio */
-	gpio_line_config(DSMG600_PO_GPIO, IXP4XX_GPIO_OUT);
-
-	/* poweroff */
-	gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH);
+	gpio_direction_output(DSMG600_PO_GPIO, 1);
 }
 
 /* This is used to make sure the power-button pusher is serious.  The button
@@ -201,7 +198,7 @@ static void dsmg600_power_handler(unsigned long data)
 			ctrl_alt_del();
 
 			/* Change the state of the power LED to "blink" */
-			gpio_line_set(DSMG600_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
+			gpio_set_value(DSMG600_LED_PWR_GPIO, 0);
 		} else {
 			power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
 		}
@@ -269,7 +266,7 @@ static void __init dsmg600_init(void)
 	 */
 
 	/* Make sure that the power button GPIO is set up as an input */
-	gpio_line_config(DSMG600_PB_GPIO, IXP4XX_GPIO_IN);
+	gpio_direction_input(DSMG600_PB_GPIO);
 
 	/* Set the initial value for the power button IRQ handler */
 	power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c
index b81aa79..b80a256 100644
--- a/arch/arm/mach-ixp4xx/goramo_mlr.c
+++ b/arch/arm/mach-ixp4xx/goramo_mlr.c
@@ -8,6 +8,7 @@
 #include <linux/i2c-gpio.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/serial_8250.h>
@@ -80,19 +81,19 @@ static u8 control_value;
 
 static void set_scl(u8 value)
 {
-	gpio_line_set(GPIO_SCL, !!value);
+	gpio_set_value(GPIO_SCL, value);
 	udelay(3);
 }
 
 static void set_sda(u8 value)
 {
-	gpio_line_set(GPIO_SDA, !!value);
+	gpio_set_value(GPIO_SDA, value);
 	udelay(3);
 }
 
 static void set_str(u8 value)
 {
-	gpio_line_set(GPIO_STR, !!value);
+	gpio_set_value(GPIO_STR, value);
 	udelay(3);
 }
 
@@ -109,8 +110,8 @@ static void output_control(void)
 {
 	int i;
 
-	gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);
-	gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);
+	gpio_direction_output(GPIO_SCL, 1);
+	gpio_direction_output(GPIO_SDA, 1);
 
 	for (i = 0; i < 8; i++) {
 		set_scl(0);
@@ -153,7 +154,7 @@ static int hss_set_clock(int port, unsigned int clock_type)
 static irqreturn_t hss_dcd_irq(int irq, void *pdev)
 {
 	int i, port = (irq == IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N));
-	gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);
+	i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
 	set_carrier_cb_tab[port](pdev, !i);
 	return IRQ_HANDLED;
 }
@@ -169,7 +170,7 @@ static int hss_open(int port, void *pdev,
 	else
 		irq = IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N);
 
-	gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);
+	i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
 	set_carrier_cb(pdev, !i);
 
 	set_carrier_cb_tab[!!port] = set_carrier_cb;
@@ -182,7 +183,7 @@ static int hss_open(int port, void *pdev,
 
 	set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 0);
 	output_control();
-	gpio_line_set(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 0);
+	gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 0);
 	return 0;
 }
 
@@ -194,7 +195,7 @@ static void hss_close(int port, void *pdev)
 
 	set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 1);
 	output_control();
-	gpio_line_set(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 1);
+	gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 1);
 }
 
 
@@ -414,13 +415,11 @@ static void __init gmlr_init(void)
 	if (hw_bits & CFG_HW_HAS_EEPROM)
 		device_tab[devices++] = &device_i2c; /* max index 6 */
 
-	gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);
-	gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);
-	gpio_line_config(GPIO_STR, IXP4XX_GPIO_OUT);
-	gpio_line_config(GPIO_HSS0_RTS_N, IXP4XX_GPIO_OUT);
-	gpio_line_config(GPIO_HSS1_RTS_N, IXP4XX_GPIO_OUT);
-	gpio_line_config(GPIO_HSS0_DCD_N, IXP4XX_GPIO_IN);
-	gpio_line_config(GPIO_HSS1_DCD_N, IXP4XX_GPIO_IN);
+	gpio_direction_output(GPIO_SCL, 1);
+	gpio_direction_output(GPIO_SDA, 1);
+	gpio_direction_output(GPIO_STR, 1);
+	gpio_direction_output(GPIO_HSS0_RTS_N, 0);
+	gpio_direction_output(GPIO_HSS1_RTS_N, 0);
 	irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
 	irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
 
diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h
index 2d3e3f1..7fef868 100644
--- a/arch/arm/mach-ixp4xx/include/mach/platform.h
+++ b/arch/arm/mach-ixp4xx/include/mach/platform.h
@@ -132,47 +132,9 @@ struct pci_sys_data;
 extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
 extern struct pci_ops ixp4xx_ops;
 
-/*
- * GPIO-functions
- */
-/*
- * The following converted to the real HW bits the gpio_line_config
- */
-/* GPIO pin types */
-#define IXP4XX_GPIO_OUT 		0x1
-#define IXP4XX_GPIO_IN  		0x2
-
-/* GPIO signal types */
-#define IXP4XX_GPIO_LOW			0
-#define IXP4XX_GPIO_HIGH		1
-
 /* GPIO Clocks */
 #define IXP4XX_GPIO_CLK_0		14
 #define IXP4XX_GPIO_CLK_1		15
 
-/* using macros here to work around circular dependency with asm/io.h */
-#define gpio_line_config(line, direction)	\
-do {						\
-	u8 __line = (line);			\
-	if ((direction) == IXP4XX_GPIO_IN)	\
-		writel_relaxed(readl_relaxed(IXP4XX_GPIO_GPOER) | (1 << __line), IXP4XX_GPIO_GPOER); \
-	else					\
-		writel_relaxed(readl_relaxed(IXP4XX_GPIO_GPOER) & ~(1 << __line), IXP4XX_GPIO_GPOER); \
-} while (0)
-
-#define gpio_line_get(line, value)	\
-do {					\
-	*(value) = (readl_relaxed(IXP4XX_GPIO_GPINR) >> (line)) & 0x1; \
-} while(0)
-
-#define gpio_line_set(line, value)		\
-do {						\
-	u8 __line = (line);			\
-	if ((value) == IXP4XX_GPIO_HIGH)	\
-		writel_relaxed(readl_relaxed(IXP4XX_GPIO_GPOUTR) | (1 << __line), IXP4XX_GPIO_GPOUTR); \
-	else if ((value) == IXP4XX_GPIO_LOW)	\
-		writel_relaxed(readl_relaxed(IXP4XX_GPIO_GPOUTR) & ~(1 << __line), IXP4XX_GPIO_GPOUTR); \
-} while (0)
-
 #endif // __ASSEMBLY__
 
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index 399c5e3..736900a 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -80,10 +80,10 @@ ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 
 	if (ctrl & NAND_CTRL_CHANGE) {
 		if (ctrl & NAND_NCE) {
-			gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_LOW);
+			gpio_set_value(IXDP425_NAND_NCE_PIN, 0);
 			udelay(5);
 		} else
-			gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_HIGH);
+			gpio_set_value(IXDP425_NAND_NCE_PIN, 1);
 
 		offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0;
 		offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0;
@@ -227,7 +227,7 @@ static void __init ixdp425_init(void)
 	ixdp425_flash_nand_resource.start = IXP4XX_EXP_BUS_BASE(3),
 	ixdp425_flash_nand_resource.end   = IXP4XX_EXP_BUS_BASE(3) + 0x10 - 1;
 
-	gpio_line_config(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_OUT);
+	gpio_direction_output(IXDP425_NAND_NCE_PIN, 1);
 
 	/* Configure expansion bus for NAND Flash */
 	*IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN |
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
index 647d377..373cbd2 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -185,10 +185,7 @@ static void nas100d_power_off(void)
 	/* This causes the box to drop the power and go dead. */
 
 	/* enable the pwr cntl gpio */
-	gpio_line_config(NAS100D_PO_GPIO, IXP4XX_GPIO_OUT);
-
-	/* do the deed */
-	gpio_line_set(NAS100D_PO_GPIO, IXP4XX_GPIO_HIGH);
+	gpio_direction_output(NAS100D_PO_GPIO, 1);
 }
 
 /* This is used to make sure the power-button pusher is serious.  The button
@@ -225,7 +222,7 @@ static void nas100d_power_handler(unsigned long data)
 			ctrl_alt_del();
 
 			/* Change the state of the power LED to "blink" */
-			gpio_line_set(NAS100D_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
+			gpio_set_value(NAS100D_LED_PWR_GPIO, 0);
 		} else {
 			power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
 		}
@@ -284,7 +281,7 @@ static void __init nas100d_init(void)
 	 */
 
 	/* Make sure that the power button GPIO is set up as an input */
-	gpio_line_config(NAS100D_PB_GPIO, IXP4XX_GPIO_IN);
+	gpio_direction_input(NAS100D_PB_GPIO);
 
 	/* Set the initial value for the power button IRQ handler */
 	power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
index ada1175..6272e16 100644
--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -198,10 +198,7 @@ static void nslu2_power_off(void)
 	/* This causes the box to drop the power and go dead. */
 
 	/* enable the pwr cntl gpio */
-	gpio_line_config(NSLU2_PO_GPIO, IXP4XX_GPIO_OUT);
-
-	/* do the deed */
-	gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
+	gpio_direction_output(NSLU2_PO_GPIO, 1);
 }
 
 static irqreturn_t nslu2_power_handler(int irq, void *dev_id)
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c
index 6b40950..07f75b2 100644
--- a/drivers/input/misc/ixp4xx-beeper.c
+++ b/drivers/input/misc/ixp4xx-beeper.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <mach/hardware.h>
@@ -35,14 +36,12 @@ static void ixp4xx_spkr_control(unsigned int pin, unsigned int count)
 
 	spin_lock_irqsave(&beep_lock, flags);
 
-	 if (count) {
-		gpio_line_config(pin, IXP4XX_GPIO_OUT);
-		gpio_line_set(pin, IXP4XX_GPIO_LOW);
+	if (count) {
+		gpio_direction_output(pin, 0);
 
 		writel_relaxed((count & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE, IXP4XX_OSRT2);
 	} else {
-		gpio_line_config(pin, IXP4XX_GPIO_IN);
-		gpio_line_set(pin, IXP4XX_GPIO_HIGH);
+		gpio_direction_input(pin);
 
 		writel_relaxed(0, IXP4XX_OSRT2);
 	}
@@ -52,7 +51,7 @@ static void ixp4xx_spkr_control(unsigned int pin, unsigned int count)
 
 static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
-	unsigned int pin = (unsigned int) input_get_drvdata(dev);
+	unsigned int pin = (unsigned int)input_get_drvdata(dev);
 	unsigned int count = 0;
 
 	if (type != EV_SND)
@@ -78,13 +77,15 @@ static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned
 
 static irqreturn_t ixp4xx_spkr_interrupt(int irq, void *dev_id)
 {
-	/* flip the beeper output */
-	writel_relaxed(readl_relaxed(IXP4XX_GPIO_GPOUTR) ^ (1 << (unsigned int) dev_id), IXP4XX_GPIO_GPOUTR);
+	unsigned int pin = (unsigned int)dev_id;
+
+	/* Flip the beeper output */
+	gpio_set_value(pin, gpio_get_value(pin));
 
 	return IRQ_HANDLED;
 }
 
-static int ixp4xx_spkr_probe(struct platform_device *dev)
+static int ixp4xx_spkr_probe(struct platform_device *pdev)
 {
 	struct input_dev *input_dev;
 	int err;
@@ -93,7 +94,10 @@ static int ixp4xx_spkr_probe(struct platform_device *dev)
 	if (!input_dev)
 		return -ENOMEM;
 
-	input_set_drvdata(input_dev, (void *) dev->id);
+	WARN_ON(devm_gpio_request_one(&pdev->dev, pdev->id, GPIOF_IN,
+				      dev_name(&pdev->dev)));
+
+	input_set_drvdata(input_dev, (void *)pdev->id);
 
 	input_dev->name = "ixp4xx beeper",
 	input_dev->phys = "ixp4xx/gpio";
@@ -101,7 +105,7 @@ static int ixp4xx_spkr_probe(struct platform_device *dev)
 	input_dev->id.vendor  = 0x001f;
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
-	input_dev->dev.parent = &dev->dev;
+	input_dev->dev.parent = &pdev->dev;
 
 	input_dev->evbit[0] = BIT_MASK(EV_SND);
 	input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
@@ -109,7 +113,7 @@ static int ixp4xx_spkr_probe(struct platform_device *dev)
 
 	err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt,
 			  IRQF_NO_SUSPEND, "ixp4xx-beeper",
-			  (void *) dev->id);
+			  (void *)pdev->id);
 	if (err)
 		goto err_free_device;
 
@@ -117,39 +121,39 @@ static int ixp4xx_spkr_probe(struct platform_device *dev)
 	if (err)
 		goto err_free_irq;
 
-	platform_set_drvdata(dev, input_dev);
+	platform_set_drvdata(pdev, input_dev);
 
 	return 0;
 
  err_free_irq:
-	free_irq(IRQ_IXP4XX_TIMER2, dev);
+	free_irq(IRQ_IXP4XX_TIMER2, (void *)pdev->id);
  err_free_device:
 	input_free_device(input_dev);
 
 	return err;
 }
 
-static int ixp4xx_spkr_remove(struct platform_device *dev)
+static int ixp4xx_spkr_remove(struct platform_device *pdev)
 {
-	struct input_dev *input_dev = platform_get_drvdata(dev);
-	unsigned int pin = (unsigned int) input_get_drvdata(input_dev);
+	struct input_dev *input_dev = platform_get_drvdata(pdev);
+	unsigned int pin = (unsigned int)input_get_drvdata(input_dev);
 
 	input_unregister_device(input_dev);
-	platform_set_drvdata(dev, NULL);
+	platform_set_drvdata(pdev, NULL);
 
 	/* turn the speaker off */
 	disable_irq(IRQ_IXP4XX_TIMER2);
 	ixp4xx_spkr_control(pin, 0);
 
-	free_irq(IRQ_IXP4XX_TIMER2, dev);
+	free_irq(IRQ_IXP4XX_TIMER2, (void *)pdev->id);
 
 	return 0;
 }
 
-static void ixp4xx_spkr_shutdown(struct platform_device *dev)
+static void ixp4xx_spkr_shutdown(struct platform_device *pdev)
 {
-	struct input_dev *input_dev = platform_get_drvdata(dev);
-	unsigned int pin = (unsigned int) input_get_drvdata(input_dev);
+	struct input_dev *input_dev = platform_get_drvdata(pdev);
+	unsigned int pin = (unsigned int)input_get_drvdata(input_dev);
 
 	/* turn off the speaker */
 	disable_irq(IRQ_IXP4XX_TIMER2);
@@ -166,4 +170,3 @@ static struct platform_driver ixp4xx_spkr_platform_driver = {
 	.shutdown	= ixp4xx_spkr_shutdown,
 };
 module_platform_driver(ixp4xx_spkr_platform_driver);
-
diff --git a/drivers/ptp/ptp_ixp46x.c b/drivers/ptp/ptp_ixp46x.c
index d49b851..84ac0d2 100644
--- a/drivers/ptp/ptp_ixp46x.c
+++ b/drivers/ptp/ptp_ixp46x.c
@@ -260,8 +260,6 @@ static int setup_interrupt(int gpio)
 {
 	int irq;
 
-	gpio_line_config(gpio, IXP4XX_GPIO_IN);
-
 	irq = gpio_to_irq(gpio);
 
 	if (NO_IRQ == irq)
@@ -280,14 +278,6 @@ static int setup_interrupt(int gpio)
 	return irq;
 }
 
-static void __exit ptp_ixp_exit(void)
-{
-	free_irq(MASTER_IRQ, &ixp_clock);
-	free_irq(SLAVE_IRQ, &ixp_clock);
-	ixp46x_phc_index = -1;
-	ptp_clock_unregister(ixp_clock.ptp_clock);
-}
-
 static int __init ptp_ixp_init(void)
 {
 	if (!cpu_is_ixp46x())
@@ -310,6 +300,9 @@ static int __init ptp_ixp_init(void)
 	__raw_writel(0, &ixp_clock.regs->trgt_hi);
 	__raw_writel(TTIPEND, &ixp_clock.regs->event);
 
+	gpio_request_one(MASTER_GPIO, GPIOF_IN, "PTP Master");
+	gpio_request_one(SLAVE_GPIO, GPIOF_IN, "PTP Slave");
+
 	if (MASTER_IRQ != setup_interrupt(MASTER_GPIO)) {
 		pr_err("failed to setup gpio %d as irq\n", MASTER_GPIO);
 		goto no_master;
@@ -320,13 +313,31 @@ static int __init ptp_ixp_init(void)
 	}
 
 	return 0;
+
 no_slave:
 	free_irq(MASTER_IRQ, &ixp_clock);
+
 no_master:
+	gpio_free(MASTER_GPIO);
+	gpio_free(SLAVE_GPIO);
+
 	ptp_clock_unregister(ixp_clock.ptp_clock);
+
 	return -ENODEV;
 }
 
+static void __exit ptp_ixp_exit(void)
+{
+	free_irq(MASTER_IRQ, &ixp_clock);
+	free_irq(SLAVE_IRQ, &ixp_clock);
+
+	gpio_free(MASTER_GPIO);
+	gpio_free(SLAVE_GPIO);
+
+	ixp46x_phc_index = -1;
+	ptp_clock_unregister(ixp_clock.ptp_clock);
+}
+
 module_init(ptp_ixp_init);
 module_exit(ptp_ixp_exit);
 
