source: trunk/target/linux/brcm63xx/patches-2.6.37/010-add_bcm63xx_ohci_controller.patch @ 25629

Last change on this file since 25629 was 25629, checked in by florian, 6 years ago

[brcm63xx] add support for 2.6.37, patches from KanjiMonster

File size: 5.4 KB
  • new file drivers/usb/host/ohci-bcm63xx.c

    Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
    ---
     drivers/usb/host/ohci-bcm63xx.c |  166 +++++++++++++++++++++++++++++++++++++++
     drivers/usb/host/ohci-hcd.c     |    5 +
     drivers/usb/host/ohci.h         |    2 +-
     3 files changed, 172 insertions(+), 1 deletions(-)
     create mode 100644 drivers/usb/host/ohci-bcm63xx.c
    
    - +  
     1/* 
     2 * This file is subject to the terms and conditions of the GNU General Public 
     3 * License.  See the file "COPYING" in the main directory of this archive 
     4 * for more details. 
     5 * 
     6 * Copyright (C) 2010 Maxime Bizon <mbizon@freebox.fr> 
     7 */ 
     8 
     9#include <linux/init.h> 
     10#include <linux/clk.h> 
     11#include <linux/platform_device.h> 
     12#include <bcm63xx_cpu.h> 
     13#include <bcm63xx_regs.h> 
     14#include <bcm63xx_io.h> 
     15 
     16static struct clk *usb_host_clock; 
     17 
     18static int __devinit ohci_bcm63xx_start(struct usb_hcd *hcd) 
     19{ 
     20        struct ohci_hcd *ohci = hcd_to_ohci(hcd); 
     21        int ret; 
     22 
     23        /* 
     24         * port 2 can be shared with USB slave, but all boards seem to 
     25         * have only one host port populated, so we can hardcode it 
     26         */ 
     27        ohci->num_ports = 1; 
     28 
     29        ret = ohci_init(ohci); 
     30        if (ret < 0) 
     31                return ret; 
     32 
     33        ret = ohci_run(ohci); 
     34        if (ret < 0) { 
     35                err("can't start %s", hcd->self.bus_name); 
     36                ohci_stop(hcd); 
     37                return ret; 
     38        } 
     39        return 0; 
     40} 
     41 
     42static const struct hc_driver ohci_bcm63xx_hc_driver = { 
     43        .description =          hcd_name, 
     44        .product_desc =         "BCM63XX integrated OHCI controller", 
     45        .hcd_priv_size =        sizeof(struct ohci_hcd), 
     46 
     47        .irq =                  ohci_irq, 
     48        .flags =                HCD_USB11 | HCD_MEMORY, 
     49        .start =                ohci_bcm63xx_start, 
     50        .stop =                 ohci_stop, 
     51        .shutdown =             ohci_shutdown, 
     52        .urb_enqueue =          ohci_urb_enqueue, 
     53        .urb_dequeue =          ohci_urb_dequeue, 
     54        .endpoint_disable =     ohci_endpoint_disable, 
     55        .get_frame_number =     ohci_get_frame, 
     56        .hub_status_data =      ohci_hub_status_data, 
     57        .hub_control =          ohci_hub_control, 
     58        .start_port_reset =     ohci_start_port_reset, 
     59}; 
     60 
     61static int __devinit ohci_hcd_bcm63xx_drv_probe(struct platform_device *pdev) 
     62{ 
     63        struct resource *res_mem; 
     64        struct usb_hcd *hcd; 
     65        struct ohci_hcd *ohci; 
     66        u32 reg; 
     67        int ret, irq; 
     68 
     69        res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 
     70        irq = platform_get_irq(pdev, 0); 
     71        if (!res_mem || irq < 0) 
     72                return -ENODEV; 
     73 
     74        if (BCMCPU_IS_6348()) { 
     75                struct clk *clk; 
     76                /* enable USB host clock */ 
     77                clk = clk_get(&pdev->dev, "usbh"); 
     78                if (IS_ERR(clk)) 
     79                        return -ENODEV; 
     80 
     81                clk_enable(clk); 
     82                usb_host_clock = clk; 
     83                bcm_rset_writel(RSET_OHCI_PRIV, 0, OHCI_PRIV_REG); 
     84 
     85        } else if (BCMCPU_IS_6358()) { 
     86                reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_REG); 
     87                reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK; 
     88                reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK; 
     89                bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_REG); 
     90                /* 
     91                 * The magic value comes for the original vendor BSP 
     92                 * and is needed for USB to work. Datasheet does not 
     93                 * help, so the magic value is used as-is. 
     94                 */ 
     95                bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020, USBH_PRIV_TEST_REG); 
     96        } else 
     97                return 0; 
     98 
     99        hcd = usb_create_hcd(&ohci_bcm63xx_hc_driver, &pdev->dev, "bcm63xx"); 
     100        if (!hcd) 
     101                return -ENOMEM; 
     102        hcd->rsrc_start = res_mem->start; 
     103        hcd->rsrc_len = res_mem->end - res_mem->start + 1; 
     104 
     105        if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { 
     106                pr_debug("request_mem_region failed\n"); 
     107                ret = -EBUSY; 
     108                goto out; 
     109        } 
     110 
     111        hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); 
     112        if (!hcd->regs) { 
     113                pr_debug("ioremap failed\n"); 
     114                ret = -EIO; 
     115                goto out1; 
     116        } 
     117 
     118        ohci = hcd_to_ohci(hcd); 
     119        ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC | 
     120                OHCI_QUIRK_FRAME_NO; 
     121        ohci_hcd_init(ohci); 
     122 
     123        ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); 
     124        if (ret) 
     125                goto out2; 
     126 
     127        platform_set_drvdata(pdev, hcd); 
     128        return 0; 
     129 
     130out2: 
     131        iounmap(hcd->regs); 
     132out1: 
     133        release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 
     134out: 
     135        usb_put_hcd(hcd); 
     136        return ret; 
     137} 
     138 
     139static int __devexit ohci_hcd_bcm63xx_drv_remove(struct platform_device *pdev) 
     140{ 
     141        struct usb_hcd *hcd; 
     142 
     143        hcd = platform_get_drvdata(pdev); 
     144        usb_remove_hcd(hcd); 
     145        iounmap(hcd->regs); 
     146        usb_put_hcd(hcd); 
     147        release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 
     148        if (usb_host_clock) { 
     149                clk_disable(usb_host_clock); 
     150                clk_put(usb_host_clock); 
     151        } 
     152        platform_set_drvdata(pdev, NULL); 
     153        return 0; 
     154} 
     155 
     156static struct platform_driver ohci_hcd_bcm63xx_driver = { 
     157        .probe          = ohci_hcd_bcm63xx_drv_probe, 
     158        .remove         = __devexit_p(ohci_hcd_bcm63xx_drv_remove), 
     159        .shutdown       = usb_hcd_platform_shutdown, 
     160        .driver         = { 
     161                .name   = "bcm63xx_ohci", 
     162                .owner  = THIS_MODULE, 
     163        }, 
     164}; 
     165 
     166MODULE_ALIAS("platform:bcm63xx_ohci"); 
  • drivers/usb/host/ohci-hcd.c

    a b MODULE_LICENSE ("GPL"); 
    10671067#define PLATFORM_DRIVER         ohci_hcd_da8xx_driver 
    10681068#endif 
    10691069 
     1070#ifdef CONFIG_BCM63XX 
     1071#include "ohci-bcm63xx.c" 
     1072#define PLATFORM_DRIVER         ohci_hcd_bcm63xx_driver 
     1073#endif 
     1074 
    10701075#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 
    10711076    defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 
    10721077    defined(CONFIG_CPU_SUBTYPE_SH7763) || \ 
  • drivers/usb/host/ohci.h

    a b static inline u32 hc32_to_cpup (const st 
    656656 * some big-endian SOC implementations.  Same thing happens with PSW access. 
    657657 */ 
    658658 
    659 #ifdef CONFIG_PPC_MPC52xx 
     659#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_BCM63XX) 
    660660#define big_endian_frame_no_quirk(ohci) (ohci->flags & OHCI_QUIRK_FRAME_NO) 
    661661#else 
    662662#define big_endian_frame_no_quirk(ohci) 0 
Note: See TracBrowser for help on using the repository browser.