|
@@ -91,43 +91,43 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
|
|
|
u16 tmp;
|
|
|
int i = 0;
|
|
|
|
|
|
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
|
|
-#if defined(CONFIG_HAVE_CLK)
|
|
|
- clk_enable(r8a66597->clk);
|
|
|
+ if (r8a66597->pdata->on_chip) {
|
|
|
+#ifdef CONFIG_HAVE_CLK
|
|
|
+ clk_enable(r8a66597->clk);
|
|
|
#endif
|
|
|
- do {
|
|
|
- r8a66597_write(r8a66597, SCKE, SYSCFG0);
|
|
|
- tmp = r8a66597_read(r8a66597, SYSCFG0);
|
|
|
- if (i++ > 1000) {
|
|
|
- printk(KERN_ERR "r8a66597: register access fail.\n");
|
|
|
- return -ENXIO;
|
|
|
- }
|
|
|
- } while ((tmp & SCKE) != SCKE);
|
|
|
- r8a66597_write(r8a66597, 0x04, 0x02);
|
|
|
-#else
|
|
|
- do {
|
|
|
- r8a66597_write(r8a66597, USBE, SYSCFG0);
|
|
|
- tmp = r8a66597_read(r8a66597, SYSCFG0);
|
|
|
- if (i++ > 1000) {
|
|
|
- printk(KERN_ERR "r8a66597: register access fail.\n");
|
|
|
- return -ENXIO;
|
|
|
- }
|
|
|
- } while ((tmp & USBE) != USBE);
|
|
|
- r8a66597_bclr(r8a66597, USBE, SYSCFG0);
|
|
|
- r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata), XTAL,
|
|
|
- SYSCFG0);
|
|
|
+ do {
|
|
|
+ r8a66597_write(r8a66597, SCKE, SYSCFG0);
|
|
|
+ tmp = r8a66597_read(r8a66597, SYSCFG0);
|
|
|
+ if (i++ > 1000) {
|
|
|
+ printk(KERN_ERR "r8a66597: reg access fail.\n");
|
|
|
+ return -ENXIO;
|
|
|
+ }
|
|
|
+ } while ((tmp & SCKE) != SCKE);
|
|
|
+ r8a66597_write(r8a66597, 0x04, 0x02);
|
|
|
+ } else {
|
|
|
+ do {
|
|
|
+ r8a66597_write(r8a66597, USBE, SYSCFG0);
|
|
|
+ tmp = r8a66597_read(r8a66597, SYSCFG0);
|
|
|
+ if (i++ > 1000) {
|
|
|
+ printk(KERN_ERR "r8a66597: reg access fail.\n");
|
|
|
+ return -ENXIO;
|
|
|
+ }
|
|
|
+ } while ((tmp & USBE) != USBE);
|
|
|
+ r8a66597_bclr(r8a66597, USBE, SYSCFG0);
|
|
|
+ r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata),
|
|
|
+ XTAL, SYSCFG0);
|
|
|
|
|
|
- i = 0;
|
|
|
- r8a66597_bset(r8a66597, XCKE, SYSCFG0);
|
|
|
- do {
|
|
|
- msleep(1);
|
|
|
- tmp = r8a66597_read(r8a66597, SYSCFG0);
|
|
|
- if (i++ > 500) {
|
|
|
- printk(KERN_ERR "r8a66597: register access fail.\n");
|
|
|
- return -ENXIO;
|
|
|
- }
|
|
|
- } while ((tmp & SCKE) != SCKE);
|
|
|
-#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
|
|
|
+ i = 0;
|
|
|
+ r8a66597_bset(r8a66597, XCKE, SYSCFG0);
|
|
|
+ do {
|
|
|
+ msleep(1);
|
|
|
+ tmp = r8a66597_read(r8a66597, SYSCFG0);
|
|
|
+ if (i++ > 500) {
|
|
|
+ printk(KERN_ERR "r8a66597: reg access fail.\n");
|
|
|
+ return -ENXIO;
|
|
|
+ }
|
|
|
+ } while ((tmp & SCKE) != SCKE);
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -136,15 +136,16 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597)
|
|
|
{
|
|
|
r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
|
|
|
udelay(1);
|
|
|
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
|
|
-#if defined(CONFIG_HAVE_CLK)
|
|
|
- clk_disable(r8a66597->clk);
|
|
|
-#endif
|
|
|
-#else
|
|
|
- r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
|
|
|
- r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
|
|
|
- r8a66597_bclr(r8a66597, USBE, SYSCFG0);
|
|
|
+
|
|
|
+ if (r8a66597->pdata->on_chip) {
|
|
|
+#ifdef CONFIG_HAVE_CLK
|
|
|
+ clk_disable(r8a66597->clk);
|
|
|
#endif
|
|
|
+ } else {
|
|
|
+ r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
|
|
|
+ r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
|
|
|
+ r8a66597_bclr(r8a66597, USBE, SYSCFG0);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port)
|
|
@@ -205,7 +206,7 @@ static int enable_controller(struct r8a66597 *r8a66597)
|
|
|
|
|
|
r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1);
|
|
|
|
|
|
- for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
|
|
|
+ for (port = 0; port < r8a66597->max_root_hub; port++)
|
|
|
r8a66597_enable_port(r8a66597, port);
|
|
|
|
|
|
return 0;
|
|
@@ -218,7 +219,7 @@ static void disable_controller(struct r8a66597 *r8a66597)
|
|
|
r8a66597_write(r8a66597, 0, INTENB0);
|
|
|
r8a66597_write(r8a66597, 0, INTSTS0);
|
|
|
|
|
|
- for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
|
|
|
+ for (port = 0; port < r8a66597->max_root_hub; port++)
|
|
|
r8a66597_disable_port(r8a66597, port);
|
|
|
|
|
|
r8a66597_clock_disable(r8a66597);
|
|
@@ -249,11 +250,12 @@ static int is_hub_limit(char *devpath)
|
|
|
return ((strlen(devpath) >= 4) ? 1 : 0);
|
|
|
}
|
|
|
|
|
|
-static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port)
|
|
|
+static void get_port_number(struct r8a66597 *r8a66597,
|
|
|
+ char *devpath, u16 *root_port, u16 *hub_port)
|
|
|
{
|
|
|
if (root_port) {
|
|
|
*root_port = (devpath[0] & 0x0F) - 1;
|
|
|
- if (*root_port >= R8A66597_MAX_ROOT_HUB)
|
|
|
+ if (*root_port >= r8a66597->max_root_hub)
|
|
|
printk(KERN_ERR "r8a66597: Illegal root port number.\n");
|
|
|
}
|
|
|
if (hub_port)
|
|
@@ -355,7 +357,8 @@ static int make_r8a66597_device(struct r8a66597 *r8a66597,
|
|
|
INIT_LIST_HEAD(&dev->device_list);
|
|
|
list_add_tail(&dev->device_list, &r8a66597->child_device);
|
|
|
|
|
|
- get_port_number(urb->dev->devpath, &dev->root_port, &dev->hub_port);
|
|
|
+ get_port_number(r8a66597, urb->dev->devpath,
|
|
|
+ &dev->root_port, &dev->hub_port);
|
|
|
if (!is_child_device(urb->dev->devpath))
|
|
|
r8a66597->root_hub[dev->root_port].dev = dev;
|
|
|
|
|
@@ -420,7 +423,7 @@ static void free_usb_address(struct r8a66597 *r8a66597,
|
|
|
list_del(&dev->device_list);
|
|
|
kfree(dev);
|
|
|
|
|
|
- for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
|
|
|
+ for (port = 0; port < r8a66597->max_root_hub; port++) {
|
|
|
if (r8a66597->root_hub[port].dev == dev) {
|
|
|
r8a66597->root_hub[port].dev = NULL;
|
|
|
break;
|
|
@@ -495,10 +498,20 @@ static void r8a66597_pipe_toggle(struct r8a66597 *r8a66597,
|
|
|
r8a66597_bset(r8a66597, SQCLR, pipe->pipectr);
|
|
|
}
|
|
|
|
|
|
+static inline unsigned short mbw_value(struct r8a66597 *r8a66597)
|
|
|
+{
|
|
|
+ if (r8a66597->pdata->on_chip)
|
|
|
+ return MBW_32;
|
|
|
+ else
|
|
|
+ return MBW_16;
|
|
|
+}
|
|
|
+
|
|
|
/* this function must be called with interrupt disabled */
|
|
|
static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
|
|
|
{
|
|
|
- r8a66597_mdfy(r8a66597, MBW | pipenum, MBW | CURPIPE, CFIFOSEL);
|
|
|
+ unsigned short mbw = mbw_value(r8a66597);
|
|
|
+
|
|
|
+ r8a66597_mdfy(r8a66597, mbw | pipenum, mbw | CURPIPE, CFIFOSEL);
|
|
|
r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, pipenum);
|
|
|
}
|
|
|
|
|
@@ -506,11 +519,13 @@ static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
|
|
|
static inline void fifo_change_from_pipe(struct r8a66597 *r8a66597,
|
|
|
struct r8a66597_pipe *pipe)
|
|
|
{
|
|
|
+ unsigned short mbw = mbw_value(r8a66597);
|
|
|
+
|
|
|
cfifo_change(r8a66597, 0);
|
|
|
- r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D0FIFOSEL);
|
|
|
- r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D1FIFOSEL);
|
|
|
+ r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D0FIFOSEL);
|
|
|
+ r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D1FIFOSEL);
|
|
|
|
|
|
- r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum, MBW | CURPIPE,
|
|
|
+ r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum, mbw | CURPIPE,
|
|
|
pipe->fifosel);
|
|
|
r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE, pipe->info.pipenum);
|
|
|
}
|
|
@@ -742,9 +757,13 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
|
|
|
struct r8a66597_pipe *pipe,
|
|
|
struct urb *urb)
|
|
|
{
|
|
|
-#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
|
|
int i;
|
|
|
struct r8a66597_pipe_info *info = &pipe->info;
|
|
|
+ unsigned short mbw = mbw_value(r8a66597);
|
|
|
+
|
|
|
+ /* pipe dma is only for external controlles */
|
|
|
+ if (r8a66597->pdata->on_chip)
|
|
|
+ return;
|
|
|
|
|
|
if ((pipe->info.pipenum != 0) && (info->type != R8A66597_INT)) {
|
|
|
for (i = 0; i < R8A66597_MAX_DMA_CHANNEL; i++) {
|
|
@@ -763,8 +782,8 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
|
|
|
set_pipe_reg_addr(pipe, i);
|
|
|
|
|
|
cfifo_change(r8a66597, 0);
|
|
|
- r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum,
|
|
|
- MBW | CURPIPE, pipe->fifosel);
|
|
|
+ r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum,
|
|
|
+ mbw | CURPIPE, pipe->fifosel);
|
|
|
|
|
|
r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE,
|
|
|
pipe->info.pipenum);
|
|
@@ -772,7 +791,6 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
-#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
|
|
|
}
|
|
|
|
|
|
/* this function must be called with interrupt disabled */
|
|
@@ -1769,7 +1787,7 @@ static void r8a66597_timer(unsigned long _r8a66597)
|
|
|
|
|
|
spin_lock_irqsave(&r8a66597->lock, flags);
|
|
|
|
|
|
- for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
|
|
|
+ for (port = 0; port < r8a66597->max_root_hub; port++)
|
|
|
r8a66597_root_hub_control(r8a66597, port);
|
|
|
|
|
|
spin_unlock_irqrestore(&r8a66597->lock, flags);
|
|
@@ -1807,7 +1825,7 @@ static void set_address_zero(struct r8a66597 *r8a66597, struct urb *urb)
|
|
|
u16 root_port, hub_port;
|
|
|
|
|
|
if (usb_address == 0) {
|
|
|
- get_port_number(urb->dev->devpath,
|
|
|
+ get_port_number(r8a66597, urb->dev->devpath,
|
|
|
&root_port, &hub_port);
|
|
|
set_devadd_reg(r8a66597, 0,
|
|
|
get_r8a66597_usb_speed(urb->dev->speed),
|
|
@@ -2082,7 +2100,7 @@ static int r8a66597_hub_status_data(struct usb_hcd *hcd, char *buf)
|
|
|
|
|
|
*buf = 0; /* initialize (no change) */
|
|
|
|
|
|
- for (i = 0; i < R8A66597_MAX_ROOT_HUB; i++) {
|
|
|
+ for (i = 0; i < r8a66597->max_root_hub; i++) {
|
|
|
if (r8a66597->root_hub[i].port & 0xffff0000)
|
|
|
*buf |= 1 << (i + 1);
|
|
|
}
|
|
@@ -2097,11 +2115,11 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597,
|
|
|
{
|
|
|
desc->bDescriptorType = 0x29;
|
|
|
desc->bHubContrCurrent = 0;
|
|
|
- desc->bNbrPorts = R8A66597_MAX_ROOT_HUB;
|
|
|
+ desc->bNbrPorts = r8a66597->max_root_hub;
|
|
|
desc->bDescLength = 9;
|
|
|
desc->bPwrOn2PwrGood = 0;
|
|
|
desc->wHubCharacteristics = cpu_to_le16(0x0011);
|
|
|
- desc->bitmap[0] = ((1 << R8A66597_MAX_ROOT_HUB) - 1) << 1;
|
|
|
+ desc->bitmap[0] = ((1 << r8a66597->max_root_hub) - 1) << 1;
|
|
|
desc->bitmap[1] = ~0;
|
|
|
}
|
|
|
|
|
@@ -2129,7 +2147,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|
|
}
|
|
|
break;
|
|
|
case ClearPortFeature:
|
|
|
- if (wIndex > R8A66597_MAX_ROOT_HUB)
|
|
|
+ if (wIndex > r8a66597->max_root_hub)
|
|
|
goto error;
|
|
|
if (wLength != 0)
|
|
|
goto error;
|
|
@@ -2162,12 +2180,12 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|
|
*buf = 0x00;
|
|
|
break;
|
|
|
case GetPortStatus:
|
|
|
- if (wIndex > R8A66597_MAX_ROOT_HUB)
|
|
|
+ if (wIndex > r8a66597->max_root_hub)
|
|
|
goto error;
|
|
|
*(__le32 *)buf = cpu_to_le32(rh->port);
|
|
|
break;
|
|
|
case SetPortFeature:
|
|
|
- if (wIndex > R8A66597_MAX_ROOT_HUB)
|
|
|
+ if (wIndex > r8a66597->max_root_hub)
|
|
|
goto error;
|
|
|
if (wLength != 0)
|
|
|
goto error;
|
|
@@ -2216,7 +2234,7 @@ static int r8a66597_bus_suspend(struct usb_hcd *hcd)
|
|
|
|
|
|
dbg("%s", __func__);
|
|
|
|
|
|
- for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
|
|
|
+ for (port = 0; port < r8a66597->max_root_hub; port++) {
|
|
|
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
|
|
|
unsigned long dvstctr_reg = get_dvstctr_reg(port);
|
|
|
|
|
@@ -2247,7 +2265,7 @@ static int r8a66597_bus_resume(struct usb_hcd *hcd)
|
|
|
|
|
|
dbg("%s", __func__);
|
|
|
|
|
|
- for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
|
|
|
+ for (port = 0; port < r8a66597->max_root_hub; port++) {
|
|
|
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
|
|
|
unsigned long dvstctr_reg = get_dvstctr_reg(port);
|
|
|
|
|
@@ -2314,7 +2332,7 @@ static int r8a66597_suspend(struct device *dev)
|
|
|
|
|
|
disable_controller(r8a66597);
|
|
|
|
|
|
- for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
|
|
|
+ for (port = 0; port < r8a66597->max_root_hub; port++) {
|
|
|
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
|
|
|
|
|
|
rh->port = 0x00000000;
|
|
@@ -2354,8 +2372,9 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
|
|
|
del_timer_sync(&r8a66597->rh_timer);
|
|
|
usb_remove_hcd(hcd);
|
|
|
iounmap((void *)r8a66597->reg);
|
|
|
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
|
|
|
- clk_put(r8a66597->clk);
|
|
|
+#ifdef CONFIG_HAVE_CLK
|
|
|
+ if (r8a66597->pdata->on_chip)
|
|
|
+ clk_put(r8a66597->clk);
|
|
|
#endif
|
|
|
usb_put_hcd(hcd);
|
|
|
return 0;
|
|
@@ -2363,7 +2382,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
|
|
|
|
|
|
static int __devinit r8a66597_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
|
|
|
+#ifdef CONFIG_HAVE_CLK
|
|
|
char clk_name[8];
|
|
|
#endif
|
|
|
struct resource *res = NULL, *ires;
|
|
@@ -2425,15 +2444,20 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
|
|
|
r8a66597->pdata = pdev->dev.platform_data;
|
|
|
r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
|
|
|
|
|
|
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
|
|
|
- snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
|
|
|
- r8a66597->clk = clk_get(&pdev->dev, clk_name);
|
|
|
- if (IS_ERR(r8a66597->clk)) {
|
|
|
- dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
|
|
|
- ret = PTR_ERR(r8a66597->clk);
|
|
|
- goto clean_up2;
|
|
|
- }
|
|
|
+ if (r8a66597->pdata->on_chip) {
|
|
|
+#ifdef CONFIG_HAVE_CLK
|
|
|
+ snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
|
|
|
+ r8a66597->clk = clk_get(&pdev->dev, clk_name);
|
|
|
+ if (IS_ERR(r8a66597->clk)) {
|
|
|
+ dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
|
|
|
+ clk_name);
|
|
|
+ ret = PTR_ERR(r8a66597->clk);
|
|
|
+ goto clean_up2;
|
|
|
+ }
|
|
|
#endif
|
|
|
+ r8a66597->max_root_hub = 1;
|
|
|
+ } else
|
|
|
+ r8a66597->max_root_hub = 2;
|
|
|
|
|
|
spin_lock_init(&r8a66597->lock);
|
|
|
init_timer(&r8a66597->rh_timer);
|
|
@@ -2463,8 +2487,9 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
|
|
|
return 0;
|
|
|
|
|
|
clean_up3:
|
|
|
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
|
|
|
- clk_put(r8a66597->clk);
|
|
|
+#ifdef CONFIG_HAVE_CLK
|
|
|
+ if (r8a66597->pdata->on_chip)
|
|
|
+ clk_put(r8a66597->clk);
|
|
|
clean_up2:
|
|
|
#endif
|
|
|
usb_put_hcd(hcd);
|