#include <linux/i2c/pca953x.h>
 #include <linux/apm-emulation.h>
 #include <linux/can/platform/mcp251x.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 
 #include <asm/mach-types.h>
 #include <asm/suspend.h>
 };
 
 /* CAN bus on SPI */
-static int zeus_mcp2515_setup(struct spi_device *sdev)
-{
-       int err;
-
-       err = gpio_request(ZEUS_CAN_SHDN_GPIO, "CAN shutdown");
-       if (err)
-               return err;
+static struct regulator_consumer_supply can_regulator_consumer =
+       REGULATOR_SUPPLY("vdd", "spi3.0");
 
-       err = gpio_direction_output(ZEUS_CAN_SHDN_GPIO, 1);
-       if (err) {
-               gpio_free(ZEUS_CAN_SHDN_GPIO);
-               return err;
-       }
+static struct regulator_init_data can_regulator_init_data = {
+       .constraints    = {
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+       },
+       .consumer_supplies      = &can_regulator_consumer,
+       .num_consumer_supplies  = 1,
+};
 
-       return 0;
-}
+static struct fixed_voltage_config can_regulator_pdata = {
+       .supply_name    = "CAN_SHDN",
+       .microvolts     = 3300000,
+       .gpio           = ZEUS_CAN_SHDN_GPIO,
+       .init_data      = &can_regulator_init_data,
+};
 
-static int zeus_mcp2515_transceiver_enable(int enable)
-{
-       gpio_set_value(ZEUS_CAN_SHDN_GPIO, !enable);
-       return 0;
-}
+static struct platform_device can_regulator_device = {
+       .name   = "reg-fixed-volage",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &can_regulator_pdata,
+       },
+};
 
 static struct mcp251x_platform_data zeus_mcp2515_pdata = {
        .oscillator_frequency   = 16*1000*1000,
-       .board_specific_setup   = zeus_mcp2515_setup,
-       .power_enable           = zeus_mcp2515_transceiver_enable,
 };
 
 static struct spi_board_info zeus_spi_board_info[] = {
        &zeus_leds_device,
        &zeus_pcmcia_device,
        &zeus_max6369_device,
+       &can_regulator_device,
 };
 
 /* AC'97 */
 
  *
  * static struct mcp251x_platform_data mcp251x_info = {
  *         .oscillator_frequency = 8000000,
- *         .board_specific_setup = &mcp251x_setup,
- *         .power_enable = mcp251x_power_enable,
- *         .transceiver_enable = NULL,
  * };
  *
  * static struct spi_board_info spi_board_info[] = {
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/uaccess.h>
+#include <linux/regulator/consumer.h>
 
 /* SPI interface instruction set */
 #define INSTRUCTION_WRITE      0x02
 #define AFTER_SUSPEND_POWER 4
 #define AFTER_SUSPEND_RESTART 8
        int restart_tx;
+       struct regulator *power;
+       struct regulator *transceiver;
 };
 
 #define MCP251X_IS(_model) \
        return (st1 == 0x80 && st2 == 0x07) ? 1 : 0;
 }
 
+static int mcp251x_power_enable(struct regulator *reg, int enable)
+{
+       if (IS_ERR(reg))
+               return 0;
+
+       if (enable)
+               return regulator_enable(reg);
+       else
+               return regulator_disable(reg);
+}
+
 static void mcp251x_open_clean(struct net_device *net)
 {
        struct mcp251x_priv *priv = netdev_priv(net);
        struct spi_device *spi = priv->spi;
-       struct mcp251x_platform_data *pdata = spi->dev.platform_data;
 
        free_irq(spi->irq, priv);
        mcp251x_hw_sleep(spi);
-       if (pdata->transceiver_enable)
-               pdata->transceiver_enable(0);
+       mcp251x_power_enable(priv->transceiver, 0);
        close_candev(net);
 }
 
 {
        struct mcp251x_priv *priv = netdev_priv(net);
        struct spi_device *spi = priv->spi;
-       struct mcp251x_platform_data *pdata = spi->dev.platform_data;
 
        close_candev(net);
 
 
        mcp251x_hw_sleep(spi);
 
-       if (pdata->transceiver_enable)
-               pdata->transceiver_enable(0);
+       mcp251x_power_enable(priv->transceiver, 0);
 
        priv->can.state = CAN_STATE_STOPPED;
 
        }
 
        mutex_lock(&priv->mcp_lock);
-       if (pdata->transceiver_enable)
-               pdata->transceiver_enable(1);
+       mcp251x_power_enable(priv->transceiver, 1);
 
        priv->force_quit = 0;
        priv->tx_skb = NULL;
                                   flags, DEVICE_NAME, priv);
        if (ret) {
                dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
-               if (pdata->transceiver_enable)
-                       pdata->transceiver_enable(0);
+               mcp251x_power_enable(priv->transceiver, 0);
                close_candev(net);
                goto open_unlock;
        }
                CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
        priv->model = spi_get_device_id(spi)->driver_data;
        priv->net = net;
+
+       priv->power = devm_regulator_get(&spi->dev, "vdd");
+       priv->transceiver = devm_regulator_get(&spi->dev, "xceiver");
+       if ((PTR_ERR(priv->power) == -EPROBE_DEFER) ||
+           (PTR_ERR(priv->transceiver) == -EPROBE_DEFER)) {
+               ret = -EPROBE_DEFER;
+               goto error_power;
+       }
+
+       ret = mcp251x_power_enable(priv->power, 1);
+       if (ret)
+               goto error_power;
+
        spi_set_drvdata(spi, priv);
 
        priv->spi = spi;
                }
        }
 
-       if (pdata->power_enable)
-               pdata->power_enable(1);
-
-       /* Call out to platform specific setup */
-       if (pdata->board_specific_setup)
-               pdata->board_specific_setup(spi);
-
        SET_NETDEV_DEV(net, &spi->dev);
 
        /* Configure the SPI bus */
 
        /* Here is OK to not lock the MCP, no one knows about it yet */
        if (!mcp251x_hw_probe(spi)) {
-               dev_info(&spi->dev, "Probe failed\n");
+               ret = -ENODEV;
                goto error_probe;
        }
        mcp251x_hw_sleep(spi);
 
-       if (pdata->transceiver_enable)
-               pdata->transceiver_enable(0);
-
        ret = register_candev(net);
        if (ret)
                goto error_probe;
        if (!mcp251x_enable_dma)
                kfree(priv->spi_tx_buf);
 error_tx_buf:
-       free_candev(net);
        if (mcp251x_enable_dma)
                dma_free_coherent(&spi->dev, PAGE_SIZE,
                                  priv->spi_tx_buf, priv->spi_tx_dma);
+       mcp251x_power_enable(priv->power, 0);
+error_power:
+       free_candev(net);
 error_alloc:
-       if (pdata->power_enable)
-               pdata->power_enable(0);
        dev_err(&spi->dev, "probe failed\n");
 error_out:
        return ret;
 
 static int mcp251x_can_remove(struct spi_device *spi)
 {
-       struct mcp251x_platform_data *pdata = spi->dev.platform_data;
        struct mcp251x_priv *priv = spi_get_drvdata(spi);
        struct net_device *net = priv->net;
 
        unregister_candev(net);
-       free_candev(net);
 
        if (mcp251x_enable_dma) {
                dma_free_coherent(&spi->dev, PAGE_SIZE,
                kfree(priv->spi_rx_buf);
        }
 
-       if (pdata->power_enable)
-               pdata->power_enable(0);
+       mcp251x_power_enable(priv->power, 0);
+
+       free_candev(net);
 
        return 0;
 }
 static int mcp251x_can_suspend(struct device *dev)
 {
        struct spi_device *spi = to_spi_device(dev);
-       struct mcp251x_platform_data *pdata = spi->dev.platform_data;
        struct mcp251x_priv *priv = spi_get_drvdata(spi);
        struct net_device *net = priv->net;
 
                netif_device_detach(net);
 
                mcp251x_hw_sleep(spi);
-               if (pdata->transceiver_enable)
-                       pdata->transceiver_enable(0);
+               mcp251x_power_enable(priv->transceiver, 0);
                priv->after_suspend = AFTER_SUSPEND_UP;
        } else {
                priv->after_suspend = AFTER_SUSPEND_DOWN;
        }
 
-       if (pdata->power_enable) {
-               pdata->power_enable(0);
+       if (!IS_ERR(priv->power)) {
+               regulator_disable(priv->power);
                priv->after_suspend |= AFTER_SUSPEND_POWER;
        }
 
 static int mcp251x_can_resume(struct device *dev)
 {
        struct spi_device *spi = to_spi_device(dev);
-       struct mcp251x_platform_data *pdata = spi->dev.platform_data;
        struct mcp251x_priv *priv = spi_get_drvdata(spi);
 
        if (priv->after_suspend & AFTER_SUSPEND_POWER) {
-               pdata->power_enable(1);
+               mcp251x_power_enable(priv->power, 1);
                queue_work(priv->wq, &priv->restart_work);
        } else {
                if (priv->after_suspend & AFTER_SUSPEND_UP) {
-                       if (pdata->transceiver_enable)
-                               pdata->transceiver_enable(1);
+                       mcp251x_power_enable(priv->transceiver, 1);
                        queue_work(priv->wq, &priv->restart_work);
                } else {
                        priv->after_suspend = 0;