#include <linux/io.h>
#include <linux/slab.h>
#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#define DMA_ADDR_INVALID (~((dma_addr_t)0))
+static const char * const s3c_hsotg_supply_names[] = {
+ "vusb_d", /* digital USB supply, 1.2V */
+ "vusb_a", /* analog USB supply, 1.1V */
+};
+
/* EP0_MPS_LIMIT
*
* Unfortunately there seems to be a limit of the amount of data that can
* @regs: The memory area mapped for accessing registers.
* @regs_res: The resource that was allocated when claiming register space.
* @irq: The IRQ number we are using
+ * @supplies: Definition of USB power supplies
* @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos.
* @debug_root: root directrory for debugfs.
* @debug_file: main status file for debugfs.
int irq;
struct clk *clk;
+ struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)];
+
unsigned int dedicated_fifos:1;
struct dentry *debug_root;
struct resource *res;
int epnum;
int ret;
+ int i;
plat = pdev->dev.platform_data;
if (!plat) {
clk_enable(hsotg->clk);
+ /* regulators */
+
+ for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
+ hsotg->supplies[i].supply = s3c_hsotg_supply_names[i];
+
+ ret = regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies),
+ hsotg->supplies);
+ if (ret) {
+ dev_err(dev, "failed to request supplies: %d\n", ret);
+ goto err_supplies;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
+ hsotg->supplies);
+
+ if (ret) {
+ dev_err(hsotg->dev, "failed to enable supplies: %d\n", ret);
+ goto err_supplies;
+ }
+
/* usb phy enable */
s3c_hsotg_phy_enable(hsotg);
ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget);
if (ret)
- goto err_add_udc;
+ goto err_supplies;
s3c_hsotg_create_debug(hsotg);
our_hsotg = hsotg;
return 0;
-err_add_udc:
+err_supplies:
s3c_hsotg_phy_disable(hsotg);
+ regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
+ regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
+
clk_disable(hsotg->clk);
clk_put(hsotg->clk);
s3c_hsotg_phy_disable(hsotg);
+
+ regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
+ regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
+
clk_disable(hsotg->clk);
clk_put(hsotg->clk);