struct i2c_adapter *parent;
        struct i2c_adapter **adap; /* child busses */
        struct i2c_mux_gpio_platform_data data;
+       unsigned gpio_base;
 };
 
 static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
        int i;
 
        for (i = 0; i < mux->data.n_gpios; i++)
-               gpio_set_value(mux->data.gpios[i], val & (1 << i));
+               gpio_set_value(mux->gpio_base + mux->data.gpios[i],
+                              val & (1 << i));
 }
 
 static int i2c_mux_gpio_select(struct i2c_adapter *adap, void *data, u32 chan)
        return 0;
 }
 
+static int __devinit match_gpio_chip_by_label(struct gpio_chip *chip,
+                                             void *data)
+{
+       return !strcmp(chip->label, data);
+}
+
 static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
 {
        struct gpiomux *mux;
        struct i2c_mux_gpio_platform_data *pdata;
        struct i2c_adapter *parent;
        int (*deselect) (struct i2c_adapter *, void *, u32);
-       unsigned initial_state;
+       unsigned initial_state, gpio_base;
        int i, ret;
 
        pdata = pdev->dev.platform_data;
                return -ENODEV;
        }
 
+       /*
+        * If a GPIO chip name is provided, the GPIO pin numbers provided are
+        * relative to its base GPIO number. Otherwise they are absolute.
+        */
+       if (pdata->gpio_chip) {
+               struct gpio_chip *gpio;
+
+               gpio = gpiochip_find(pdata->gpio_chip,
+                                    match_gpio_chip_by_label);
+               if (!gpio)
+                       return -EPROBE_DEFER;
+
+               gpio_base = gpio->base;
+       } else {
+               gpio_base = 0;
+       }
+
        parent = i2c_get_adapter(pdata->parent);
        if (!parent) {
                dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
 
        mux->parent = parent;
        mux->data = *pdata;
+       mux->gpio_base = gpio_base;
        mux->adap = devm_kzalloc(&pdev->dev,
                                 sizeof(*mux->adap) * pdata->n_values,
                                 GFP_KERNEL);
        }
 
        for (i = 0; i < pdata->n_gpios; i++) {
-               ret = gpio_request(pdata->gpios[i], "i2c-mux-gpio");
+               ret = gpio_request(gpio_base + pdata->gpios[i], "i2c-mux-gpio");
                if (ret)
                        goto err_request_gpio;
-               gpio_direction_output(pdata->gpios[i],
+               gpio_direction_output(gpio_base + pdata->gpios[i],
                                      initial_state & (1 << i));
        }
 
        i = pdata->n_gpios;
 err_request_gpio:
        for (; i > 0; i--)
-               gpio_free(pdata->gpios[i - 1]);
+               gpio_free(gpio_base + pdata->gpios[i - 1]);
 alloc_failed:
        i2c_put_adapter(parent);
 
                i2c_del_mux_adapter(mux->adap[i]);
 
        for (i = 0; i < mux->data.n_gpios; i++)
-               gpio_free(mux->data.gpios[i]);
+               gpio_free(mux->gpio_base + mux->data.gpios[i]);
 
        platform_set_drvdata(pdev, NULL);
        i2c_put_adapter(mux->parent);