goto out_freeirq;
        }
 
+       if (pdata->setup)
+               pdata->setup(tc35892, tc35892_gpio->chip.base);
+
        platform_set_drvdata(pdev, tc35892_gpio);
 
        return 0;
 static int __devexit tc35892_gpio_remove(struct platform_device *pdev)
 {
        struct tc35892_gpio *tc35892_gpio = platform_get_drvdata(pdev);
+       struct tc35892 *tc35892 = tc35892_gpio->tc35892;
+       struct tc35892_gpio_platform_data *pdata = tc35892->pdata->gpio;
        int irq = platform_get_irq(pdev, 0);
        int ret;
 
+       if (pdata->remove)
+               pdata->remove(tc35892, tc35892_gpio->chip.base);
+
        ret = gpiochip_remove(&tc35892_gpio->chip);
        if (ret < 0) {
                dev_err(tc35892_gpio->dev,
 
  * struct tc35892_gpio_platform_data - TC35892 GPIO platform data
  * @gpio_base: first gpio number assigned to TC35892.  A maximum of
  *            %TC35892_NR_GPIOS GPIOs will be allocated.
+ * @setup: callback for board-specific initialization
+ * @remove: callback for board-specific teardown
  */
 struct tc35892_gpio_platform_data {
        int gpio_base;
+       void (*setup)(struct tc35892 *tc35892, unsigned gpio_base);
+       void (*remove)(struct tc35892 *tc35892, unsigned gpio_base);
 };
 
 /**