Commit a829abf8 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Olof Johansson

ARM: pxa: propagate errors from regulator_enable() to pxamci

The em_x270_mci_setpower() and em_x270_usb_hub_init() functions
call regulator_enable(), which may return an error that must
be checked.

This changes the em_x270_usb_hub_init() function to bail out
if it fails, and changes the pxamci_platform_data->setpower
callback so that the a failed em_x270_mci_setpower call
can be propagated by the pxamci driver into the mmc core.
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Cc: Mike Rapoport <mike@compulab.co.il>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Haojian Zhuang <haojian.zhuang@gmail.com>
Acked-by: default avatarChris Ball <cjb@laptop.org>
[olof: fixed order of regulator_enable() and test in em_x270_usb_hub_init]
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parent fe08bf9f
...@@ -477,16 +477,24 @@ static int em_x270_usb_hub_init(void) ...@@ -477,16 +477,24 @@ static int em_x270_usb_hub_init(void)
/* USB Hub power-on and reset */ /* USB Hub power-on and reset */
gpio_direction_output(usb_hub_reset, 1); gpio_direction_output(usb_hub_reset, 1);
gpio_direction_output(GPIO9_USB_VBUS_EN, 0); gpio_direction_output(GPIO9_USB_VBUS_EN, 0);
regulator_enable(em_x270_usb_ldo); err = regulator_enable(em_x270_usb_ldo);
if (err)
goto err_free_rst_gpio;
gpio_set_value(usb_hub_reset, 0); gpio_set_value(usb_hub_reset, 0);
gpio_set_value(usb_hub_reset, 1); gpio_set_value(usb_hub_reset, 1);
regulator_disable(em_x270_usb_ldo); regulator_disable(em_x270_usb_ldo);
regulator_enable(em_x270_usb_ldo); err = regulator_enable(em_x270_usb_ldo);
if (err)
goto err_free_rst_gpio;
gpio_set_value(usb_hub_reset, 0); gpio_set_value(usb_hub_reset, 0);
gpio_set_value(GPIO9_USB_VBUS_EN, 1); gpio_set_value(GPIO9_USB_VBUS_EN, 1);
return 0; return 0;
err_free_rst_gpio:
gpio_free(usb_hub_reset);
err_free_vbus_gpio: err_free_vbus_gpio:
gpio_free(GPIO9_USB_VBUS_EN); gpio_free(GPIO9_USB_VBUS_EN);
err_free_usb_ldo: err_free_usb_ldo:
...@@ -592,7 +600,7 @@ static int em_x270_mci_init(struct device *dev, ...@@ -592,7 +600,7 @@ static int em_x270_mci_init(struct device *dev,
return err; return err;
} }
static void em_x270_mci_setpower(struct device *dev, unsigned int vdd) static int em_x270_mci_setpower(struct device *dev, unsigned int vdd)
{ {
struct pxamci_platform_data* p_d = dev->platform_data; struct pxamci_platform_data* p_d = dev->platform_data;
...@@ -600,10 +608,11 @@ static void em_x270_mci_setpower(struct device *dev, unsigned int vdd) ...@@ -600,10 +608,11 @@ static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
int vdd_uV = (2000 + (vdd - __ffs(MMC_VDD_20_21)) * 100) * 1000; int vdd_uV = (2000 + (vdd - __ffs(MMC_VDD_20_21)) * 100) * 1000;
regulator_set_voltage(em_x270_sdio_ldo, vdd_uV, vdd_uV); regulator_set_voltage(em_x270_sdio_ldo, vdd_uV, vdd_uV);
regulator_enable(em_x270_sdio_ldo); return regulator_enable(em_x270_sdio_ldo);
} else { } else {
regulator_disable(em_x270_sdio_ldo); regulator_disable(em_x270_sdio_ldo);
} }
return 0;
} }
static void em_x270_mci_exit(struct device *dev, void *data) static void em_x270_mci_exit(struct device *dev, void *data)
......
...@@ -408,7 +408,7 @@ static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_in ...@@ -408,7 +408,7 @@ static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_in
return err; return err;
} }
static void mainstone_mci_setpower(struct device *dev, unsigned int vdd) static int mainstone_mci_setpower(struct device *dev, unsigned int vdd)
{ {
struct pxamci_platform_data* p_d = dev->platform_data; struct pxamci_platform_data* p_d = dev->platform_data;
...@@ -420,6 +420,7 @@ static void mainstone_mci_setpower(struct device *dev, unsigned int vdd) ...@@ -420,6 +420,7 @@ static void mainstone_mci_setpower(struct device *dev, unsigned int vdd)
printk(KERN_DEBUG "%s: off\n", __func__); printk(KERN_DEBUG "%s: off\n", __func__);
MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON; MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON;
} }
return 0;
} }
static void mainstone_mci_exit(struct device *dev, void *data) static void mainstone_mci_exit(struct device *dev, void *data)
......
...@@ -335,7 +335,7 @@ static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int, ...@@ -335,7 +335,7 @@ static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
return err; return err;
} }
static void pcm990_mci_setpower(struct device *dev, unsigned int vdd) static int pcm990_mci_setpower(struct device *dev, unsigned int vdd)
{ {
struct pxamci_platform_data *p_d = dev->platform_data; struct pxamci_platform_data *p_d = dev->platform_data;
u8 val; u8 val;
...@@ -348,6 +348,7 @@ static void pcm990_mci_setpower(struct device *dev, unsigned int vdd) ...@@ -348,6 +348,7 @@ static void pcm990_mci_setpower(struct device *dev, unsigned int vdd)
val &= ~PCM990_CTRL_MMC2PWR; val &= ~PCM990_CTRL_MMC2PWR;
pcm990_cpld_writeb(PCM990_CTRL_MMC2PWR, PCM990_CTRL_REG5); pcm990_cpld_writeb(PCM990_CTRL_MMC2PWR, PCM990_CTRL_REG5);
return 0;
} }
static void pcm990_mci_exit(struct device *dev, void *data) static void pcm990_mci_exit(struct device *dev, void *data)
......
...@@ -258,7 +258,7 @@ static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int, ...@@ -258,7 +258,7 @@ static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int,
return err; return err;
} }
static void poodle_mci_setpower(struct device *dev, unsigned int vdd) static int poodle_mci_setpower(struct device *dev, unsigned int vdd)
{ {
struct pxamci_platform_data* p_d = dev->platform_data; struct pxamci_platform_data* p_d = dev->platform_data;
...@@ -270,6 +270,8 @@ static void poodle_mci_setpower(struct device *dev, unsigned int vdd) ...@@ -270,6 +270,8 @@ static void poodle_mci_setpower(struct device *dev, unsigned int vdd)
gpio_set_value(POODLE_GPIO_SD_PWR1, 0); gpio_set_value(POODLE_GPIO_SD_PWR1, 0);
gpio_set_value(POODLE_GPIO_SD_PWR, 0); gpio_set_value(POODLE_GPIO_SD_PWR, 0);
} }
return 0;
} }
static void poodle_mci_exit(struct device *dev, void *data) static void poodle_mci_exit(struct device *dev, void *data)
......
...@@ -598,7 +598,7 @@ static inline void spitz_spi_init(void) {} ...@@ -598,7 +598,7 @@ static inline void spitz_spi_init(void) {}
* NOTE: The card detect interrupt isn't debounced so we delay it by 250ms to * NOTE: The card detect interrupt isn't debounced so we delay it by 250ms to
* give the card a chance to fully insert/eject. * give the card a chance to fully insert/eject.
*/ */
static void spitz_mci_setpower(struct device *dev, unsigned int vdd) static int spitz_mci_setpower(struct device *dev, unsigned int vdd)
{ {
struct pxamci_platform_data* p_d = dev->platform_data; struct pxamci_platform_data* p_d = dev->platform_data;
...@@ -606,6 +606,8 @@ static void spitz_mci_setpower(struct device *dev, unsigned int vdd) ...@@ -606,6 +606,8 @@ static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, SCOOP_CPR_SD_3V); spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, SCOOP_CPR_SD_3V);
else else
spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, 0x0); spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, 0x0);
return 0;
} }
static struct pxamci_platform_data spitz_mci_platform_data = { static struct pxamci_platform_data spitz_mci_platform_data = {
......
...@@ -734,9 +734,10 @@ static int stargate2_mci_init(struct device *dev, ...@@ -734,9 +734,10 @@ static int stargate2_mci_init(struct device *dev,
* *
* Very simple control. Either it is on or off and is controlled by * Very simple control. Either it is on or off and is controlled by
* a gpio pin */ * a gpio pin */
static void stargate2_mci_setpower(struct device *dev, unsigned int vdd) static int stargate2_mci_setpower(struct device *dev, unsigned int vdd)
{ {
gpio_set_value(SG2_SD_POWER_ENABLE, !!vdd); gpio_set_value(SG2_SD_POWER_ENABLE, !!vdd);
return 0;
} }
static void stargate2_mci_exit(struct device *dev, void *data) static void stargate2_mci_exit(struct device *dev, void *data)
......
...@@ -128,7 +128,7 @@ static inline int pxamci_set_power(struct pxamci_host *host, ...@@ -128,7 +128,7 @@ static inline int pxamci_set_power(struct pxamci_host *host,
!!on ^ host->pdata->gpio_power_invert); !!on ^ host->pdata->gpio_power_invert);
} }
if (!host->vcc && host->pdata && host->pdata->setpower) if (!host->vcc && host->pdata && host->pdata->setpower)
host->pdata->setpower(mmc_dev(host->mmc), vdd); return host->pdata->setpower(mmc_dev(host->mmc), vdd);
return 0; return 0;
} }
......
...@@ -12,7 +12,7 @@ struct pxamci_platform_data { ...@@ -12,7 +12,7 @@ struct pxamci_platform_data {
unsigned long detect_delay_ms; /* delay in millisecond before detecting cards after interrupt */ unsigned long detect_delay_ms; /* delay in millisecond before detecting cards after interrupt */
int (*init)(struct device *, irq_handler_t , void *); int (*init)(struct device *, irq_handler_t , void *);
int (*get_ro)(struct device *); int (*get_ro)(struct device *);
void (*setpower)(struct device *, unsigned int); int (*setpower)(struct device *, unsigned int);
void (*exit)(struct device *, void *); void (*exit)(struct device *, void *);
int gpio_card_detect; /* gpio detecting card insertion */ int gpio_card_detect; /* gpio detecting card insertion */
int gpio_card_ro; /* gpio detecting read only toggle */ int gpio_card_ro; /* gpio detecting read only toggle */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment