diff options
Diffstat (limited to 'packages/kexecboot/linux-kexecboot-2.6.24/tosa/0045-Update-tmio_ohci.patch')
-rw-r--r-- | packages/kexecboot/linux-kexecboot-2.6.24/tosa/0045-Update-tmio_ohci.patch | 416 |
1 files changed, 0 insertions, 416 deletions
diff --git a/packages/kexecboot/linux-kexecboot-2.6.24/tosa/0045-Update-tmio_ohci.patch b/packages/kexecboot/linux-kexecboot-2.6.24/tosa/0045-Update-tmio_ohci.patch deleted file mode 100644 index 10f483b89d..0000000000 --- a/packages/kexecboot/linux-kexecboot-2.6.24/tosa/0045-Update-tmio_ohci.patch +++ /dev/null @@ -1,416 +0,0 @@ -From fe3c05491370965eb821aedc95f771b86ebab3ab Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov <dbaryshkov@gmail.com> -Date: Wed, 9 Jan 2008 02:01:44 +0300 -Subject: [PATCH 45/64] Update tmio_ohci: - Ports management. - Basic support for ohci suspend/resume. - -Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> ---- - drivers/mfd/tc6393xb.c | 40 ++++++++ - drivers/usb/host/ohci-tmio.c | 206 +++++++++++++++++++++++++++++++++++++++--- - 2 files changed, 235 insertions(+), 11 deletions(-) - -diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c -index 9439f39..5d17687 100644 ---- a/drivers/mfd/tc6393xb.c -+++ b/drivers/mfd/tc6393xb.c -@@ -224,6 +224,44 @@ static int tc6393xb_ohci_enable(struct platform_device *ohci) - return 0; - } - -+static int tc6393xb_ohci_suspend(struct platform_device *ohci) -+{ -+ struct platform_device *dev = to_platform_device(ohci->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.usbcken = 0; -+ iowrite16(ccr.raw, &scr->ccr); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ -+static int tc6393xb_ohci_resume(struct platform_device *ohci) -+{ -+ struct platform_device *dev = to_platform_device(ohci->dev.parent); -+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev); -+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr; -+ union tc6393xb_scr_ccr ccr; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tc6393xb->lock, flags); -+ -+ ccr.raw = ioread16(&scr->ccr); -+ ccr.bits.usbcken = 1; -+ iowrite16(ccr.raw, &scr->ccr); -+ -+ spin_unlock_irqrestore(&tc6393xb->lock, flags); -+ -+ return 0; -+} -+ - static int tc6393xb_fb_disable(struct platform_device *fb) - { - struct platform_device *dev = to_platform_device(fb->dev.parent); -@@ -423,6 +461,8 @@ static struct mfd_cell tc6393xb_cells[] = { - .name = "tmio-ohci", - .enable = tc6393xb_ohci_enable, - .disable = tc6393xb_ohci_disable, -+ .suspend = tc6393xb_ohci_suspend, -+ .resume = tc6393xb_ohci_resume, - .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources), - .resources = tc6393xb_ohci_resources, - }, -diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c -index be609f3..65e3cd3 100644 ---- a/drivers/usb/host/ohci-tmio.c -+++ b/drivers/usb/host/ohci-tmio.c -@@ -75,10 +75,13 @@ struct tmio_uhccr { - u8 x07[3]; - } __attribute__((packed)); - -+#define MAX_TMIO_OHCI_PORTS 3 -+ - #define UHCCR_PM_GKEN 0x0001 - #define UHCCR_PM_CKRNEN 0x0002 - #define UHCCR_PM_USBPW1 0x0004 - #define UHCCR_PM_USBPW2 0x0008 -+#define UHCCR_PM_USBPW3 0x0008 - #define UHCCR_PM_PMEE 0x0100 - #define UHCCR_PM_PMES 0x8000 - -@@ -86,44 +89,96 @@ struct tmio_uhccr { - - struct tmio_hcd { - struct tmio_uhccr __iomem *ccr; -+ spinlock_t lock; /* protects RMW cycles and disabled_ports data */ -+ bool disabled_ports[MAX_TMIO_OHCI_PORTS]; - }; - - #define hcd_to_tmio(hcd) ((struct tmio_hcd *)(hcd_to_ohci(hcd) + 1)) - #define ohci_to_tmio(ohci) ((struct tmio_hcd *)(ohci + 1)) - -+struct indexed_device_attribute{ -+ struct device_attribute dev_attr; -+ int index; -+}; -+#define to_indexed_dev_attr(_dev_attr) \ -+ container_of(_dev_attr, struct indexed_device_attribute, dev_attr) -+ -+#define INDEXED_ATTR(_name, _mode, _show, _store, _index) \ -+ { .dev_attr = __ATTR(_name ## _index, _mode, _show, _store), \ -+ .index = _index } -+ -+#define INDEXED_DEVICE_ATTR(_name, _mode, _show, _store, _index) \ -+struct indexed_device_attribute dev_attr_##_name ## _index \ -+ = INDEXED_ATTR(_name, _mode, _show, _store, _index) -+ -+static bool disabled_tmio_ports[MAX_TMIO_OHCI_PORTS]; -+module_param_array(disabled_tmio_ports, bool, NULL, 0644); -+MODULE_PARM_DESC(disabled_tmio_ports, -+ "disable specified TC6393 usb ports (default: all enabled)"); -+ - /*-------------------------------------------------------------------------*/ - -+static void tmio_write_pm(struct platform_device *dev) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ struct tmio_uhccr __iomem *ccr = tmio->ccr; -+ u16 pm; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tmio->lock, flags); -+ -+ pm = UHCCR_PM_GKEN | UHCCR_PM_CKRNEN | -+ UHCCR_PM_PMEE | UHCCR_PM_PMES; -+ -+ if (tmio->disabled_ports[0]) -+ pm |= UHCCR_PM_USBPW1; -+ if (tmio->disabled_ports[1]) -+ pm |= UHCCR_PM_USBPW2; -+ if (tmio->disabled_ports[2]) -+ pm |= UHCCR_PM_USBPW3; -+ -+ iowrite16(pm, &ccr->pm); -+ spin_unlock_irqrestore(&tmio->lock, flags); -+} -+ - static void tmio_stop_hc(struct platform_device *dev) - { - struct mfd_cell *cell = mfd_get_cell(dev); - struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct ohci_hcd *ohci = hcd_to_ohci(hcd); - struct tmio_hcd *tmio = hcd_to_tmio(hcd); - struct tmio_uhccr __iomem *ccr = tmio->ccr; - u16 pm; - -- pm = UHCCR_PM_GKEN | UHCCR_PM_CKRNEN | UHCCR_PM_USBPW1 | UHCCR_PM_USBPW2; -+ pm = UHCCR_PM_GKEN | UHCCR_PM_CKRNEN; -+ switch (ohci->num_ports) { -+ default: -+ dev_err(&dev->dev, "Unsupported amount of ports: %d\n", ohci->num_ports); -+ case 3: -+ pm |= UHCCR_PM_USBPW3; -+ case 2: -+ pm |= UHCCR_PM_USBPW2; -+ case 1: -+ pm |= UHCCR_PM_USBPW1; -+ } - iowrite8(0, &ccr->intc); - iowrite8(0, &ccr->ilme); - iowrite16(0, &ccr->basel); - iowrite16(0, &ccr->baseh); -- iowrite16(pm, &ccr->pm); -+ iowrite16(pm, &ccr->pm); - - cell->disable(dev); - } - - static void tmio_start_hc(struct platform_device *dev) - { -- struct mfd_cell *cell = mfd_get_cell(dev); - struct usb_hcd *hcd = platform_get_drvdata(dev); - struct tmio_hcd *tmio = hcd_to_tmio(hcd); - struct tmio_uhccr __iomem *ccr = tmio->ccr; -- u16 pm; - unsigned long base = hcd->rsrc_start; - -- pm = UHCCR_PM_CKRNEN | UHCCR_PM_GKEN | UHCCR_PM_PMEE | UHCCR_PM_PMES; -- cell->enable(dev); -- -- iowrite16(pm, &ccr->pm); -+ tmio_write_pm(dev); - iowrite16(base, &ccr->basel); - iowrite16(base >> 16, &ccr->baseh); - iowrite8(1, &ccr->ilme); -@@ -133,9 +188,56 @@ static void tmio_start_hc(struct platform_device *dev) - ioread8(&ccr->revid), hcd->rsrc_start, hcd->irq); - } - -+static ssize_t tmio_disabled_port_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct usb_hcd *hcd = dev_get_drvdata(dev); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ int index = to_indexed_dev_attr(attr)->index; -+ return snprintf(buf, PAGE_SIZE, "%c", -+ tmio->disabled_ports[index-1]? 'Y': 'N'); -+} -+ -+static ssize_t tmio_disabled_port_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct usb_hcd *hcd = dev_get_drvdata(dev); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ int index = to_indexed_dev_attr(attr)->index; -+ -+ if (!count) -+ return -EINVAL; -+ -+ switch (buf[0]) { -+ case 'y': case 'Y': case '1': -+ tmio->disabled_ports[index-1] = true; -+ break; -+ case 'n': case 'N': case '0': -+ tmio->disabled_ports[index-1] = false; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ tmio_write_pm(to_platform_device(dev)); -+ -+ return 1; -+} -+ -+ -+static INDEXED_DEVICE_ATTR(disabled_usb_port, S_IRUGO | S_IWUSR, -+ tmio_disabled_port_show, tmio_disabled_port_store, 1); -+static INDEXED_DEVICE_ATTR(disabled_usb_port, S_IRUGO | S_IWUSR, -+ tmio_disabled_port_show, tmio_disabled_port_store, 2); -+static INDEXED_DEVICE_ATTR(disabled_usb_port, S_IRUGO | S_IWUSR, -+ tmio_disabled_port_show, tmio_disabled_port_store, 3); -+ - static int usb_hcd_tmio_probe(const struct hc_driver *driver, - struct platform_device *dev) - { -+ struct mfd_cell *cell = mfd_get_cell(dev); - struct resource *config = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_CONFIG); - struct resource *regs = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_CONTROL); - struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM); -@@ -159,6 +261,12 @@ static int usb_hcd_tmio_probe(const struct hc_driver *driver, - - tmio = hcd_to_tmio(hcd); - -+ spin_lock_init(&tmio->lock); -+ -+ memcpy(tmio->disabled_ports, -+ disabled_tmio_ports, -+ sizeof(disabled_tmio_ports)); -+ - tmio->ccr = ioremap(config->start, config->end - config->start + 1); - if (!tmio->ccr) { - retval = -ENOMEM; -@@ -183,17 +291,46 @@ static int usb_hcd_tmio_probe(const struct hc_driver *driver, - if (retval) - goto err_dmabounce_register_dev; - -+ retval = cell->enable(dev); -+ if (retval) -+ goto err_enable; -+ - tmio_start_hc(dev); - ohci = hcd_to_ohci(hcd); - ohci_hcd_init(ohci); - - retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); -+ if (retval) -+ goto err_add_hcd; -+ -+ switch (ohci->num_ports) { -+ default: -+ dev_err(&dev->dev, "Unsupported amount of ports: %d\n", -+ ohci->num_ports); -+ case 3: -+ retval |= device_create_file(&dev->dev, -+ &dev_attr_disabled_usb_port3.dev_attr); -+ case 2: -+ retval |= device_create_file(&dev->dev, -+ &dev_attr_disabled_usb_port2.dev_attr); -+ case 1: -+ retval |= device_create_file(&dev->dev, -+ &dev_attr_disabled_usb_port1.dev_attr); -+ } - - if (retval == 0) - return retval; - -- tmio_stop_hc(dev); -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port3.dev_attr); -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port2.dev_attr); -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port1.dev_attr); -+ -+ usb_remove_hcd(hcd); - -+err_add_hcd: -+ tmio_stop_hc(dev); -+ cell->disable(dev); -+err_enable: - dmabounce_unregister_dev(&dev->dev); - err_dmabounce_register_dev: - dma_release_declared_memory(&dev->dev); -@@ -212,6 +349,9 @@ static void usb_hcd_tmio_remove(struct usb_hcd *hcd, struct platform_device *dev - { - struct tmio_hcd *tmio = hcd_to_tmio(hcd); - -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port3.dev_attr); -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port2.dev_attr); -+ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port1.dev_attr); - usb_remove_hcd(hcd); - tmio_stop_hc(dev); - dmabounce_unregister_dev(&dev->dev); -@@ -297,13 +437,22 @@ static u64 dma_mask = DMA_32BIT_MASK; - static int ohci_hcd_tmio_drv_probe(struct platform_device *dev) - { - struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM); -+ int retval; - - dev->dev.dma_mask = &dma_mask; - dev->dev.coherent_dma_mask = DMA_32BIT_MASK; - -+ /* FIXME: move dmabounce checkers to tc6393xb core? */ - dmabounce_register_checker(tmio_dmabounce_check, sram); - -- return usb_hcd_tmio_probe(&ohci_tmio_hc_driver, dev); -+ retval = usb_hcd_tmio_probe(&ohci_tmio_hc_driver, dev); -+ -+ if (retval == 0) -+ return retval; -+ -+ dmabounce_remove_checker(tmio_dmabounce_check, sram); -+ -+ return retval; - } - - static int ohci_hcd_tmio_drv_remove(struct platform_device *dev) -@@ -323,14 +472,31 @@ static int ohci_hcd_tmio_drv_remove(struct platform_device *dev) - #ifdef CONFIG_PM - static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state) - { -+ struct mfd_cell *cell = mfd_get_cell(dev); - struct usb_hcd *hcd = platform_get_drvdata(dev); - struct ohci_hcd *ohci = hcd_to_ohci(hcd); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ struct tmio_uhccr __iomem *ccr = tmio->ccr; -+ unsigned long flags; -+ u8 misc; -+ int ret; - - if (time_before(jiffies, ohci->next_statechange)) - msleep(5); - ohci->next_statechange = jiffies; - -- tmio_stop_hc(dev); -+ spin_lock_irqsave(&tmio->lock, flags); -+ -+ misc = ioread8(&ccr->misc); -+ misc |= 1 << 3; /* USSUSP */ -+ iowrite8(misc, &ccr->misc); -+ -+ spin_unlock_irqrestore(&tmio->lock, flags); -+ -+ ret = cell->suspend(dev); -+ if (ret) -+ return ret; -+ - hcd->state = HC_STATE_SUSPENDED; - dev->dev.power.power_state = PMSG_SUSPEND; - -@@ -339,15 +505,33 @@ static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t s - - static int ohci_hcd_tmio_drv_resume(struct platform_device *dev) - { -+ struct mfd_cell *cell = mfd_get_cell(dev); - struct usb_hcd *hcd = platform_get_drvdata(dev); - struct ohci_hcd *ohci = hcd_to_ohci(hcd); -+ struct tmio_hcd *tmio = hcd_to_tmio(hcd); -+ struct tmio_uhccr __iomem *ccr = tmio->ccr; -+ unsigned long flags; -+ u8 misc; -+ int ret; - - if (time_before(jiffies, ohci->next_statechange)) - msleep(5); - ohci->next_statechange = jiffies; - -+ ret = cell->resume(dev); -+ if (ret) -+ return ret; -+ - tmio_start_hc(dev); - -+ spin_lock_irqsave(&tmio->lock, flags); -+ -+ misc = ioread8(&ccr->misc); -+ misc &= ~(1 << 3); /* USSUSP */ -+ iowrite8(misc, &ccr->misc); -+ -+ spin_unlock_irqrestore(&tmio->lock, flags); -+ - dev->dev.power.power_state = PMSG_ON; - usb_hcd_resume_root_hub(hcd); - --- -1.5.3.8 - |