summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/ec.c22
-rw-r--r--drivers/acpi/internal.h5
-rw-r--r--drivers/acpi/processor_idle.c17
-rw-r--r--drivers/acpi/sleep.c57
-rw-r--r--drivers/char/Kconfig1
-rw-r--r--drivers/misc/vmware_balloon.c18
-rw-r--r--drivers/mmc/host/omap.c1
-rw-r--r--drivers/rtc/rtc-s3c.c9
-rw-r--r--drivers/sfi/sfi_core.c4
-rw-r--r--drivers/usb/class/cdc-acm.c6
-rw-r--r--drivers/usb/core/driver.c2
-rw-r--r--drivers/usb/gadget/Kconfig1
-rw-r--r--drivers/usb/gadget/f_audio.c4
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c57
-rw-r--r--drivers/usb/host/ehci-hcd.c20
-rw-r--r--drivers/usb/host/isp1362.h2
-rw-r--r--drivers/usb/host/xhci-pci.c2
-rw-r--r--drivers/usb/host/xhci-ring.c31
-rw-r--r--drivers/usb/host/xhci.c57
-rw-r--r--drivers/usb/host/xhci.h12
-rw-r--r--drivers/usb/serial/digi_acceleport.c3
-rw-r--r--drivers/usb/serial/ftdi_sio.c4
-rw-r--r--drivers/usb/serial/mos7840.c1
-rw-r--r--drivers/video/Kconfig6
-rw-r--r--drivers/video/fb_defio.c52
25 files changed, 283 insertions, 111 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index e61d4f8..5f2027d 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -79,7 +79,7 @@ enum {
EC_FLAGS_GPE_STORM, /* GPE storm detected */
EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and
* OpReg are installed */
- EC_FLAGS_FROZEN, /* Transactions are suspended */
+ EC_FLAGS_BLOCKED, /* Transactions are blocked */
};
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -293,7 +293,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
if (t->rdata)
memset(t->rdata, 0, t->rlen);
mutex_lock(&ec->lock);
- if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) {
+ if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) {
status = -EINVAL;
goto unlock;
}
@@ -459,7 +459,7 @@ int ec_transaction(u8 command,
EXPORT_SYMBOL(ec_transaction);
-void acpi_ec_suspend_transactions(void)
+void acpi_ec_block_transactions(void)
{
struct acpi_ec *ec = first_ec;
@@ -468,11 +468,11 @@ void acpi_ec_suspend_transactions(void)
mutex_lock(&ec->lock);
/* Prevent transactions from being carried out */
- set_bit(EC_FLAGS_FROZEN, &ec->flags);
+ set_bit(EC_FLAGS_BLOCKED, &ec->flags);
mutex_unlock(&ec->lock);
}
-void acpi_ec_resume_transactions(void)
+void acpi_ec_unblock_transactions(void)
{
struct acpi_ec *ec = first_ec;
@@ -481,10 +481,20 @@ void acpi_ec_resume_transactions(void)
mutex_lock(&ec->lock);
/* Allow transactions to be carried out again */
- clear_bit(EC_FLAGS_FROZEN, &ec->flags);
+ clear_bit(EC_FLAGS_BLOCKED, &ec->flags);
mutex_unlock(&ec->lock);
}
+void acpi_ec_unblock_transactions_early(void)
+{
+ /*
+ * Allow transactions to happen again (this function is called from
+ * atomic context during wakeup, so we don't need to acquire the mutex).
+ */
+ if (first_ec)
+ clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags);
+}
+
static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
{
int result;
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index e284113..f8f190e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -49,8 +49,9 @@ void acpi_early_processor_set_pdc(void);
int acpi_ec_init(void);
int acpi_ec_ecdt_probe(void);
int acpi_boot_ec_enable(void);
-void acpi_ec_suspend_transactions(void);
-void acpi_ec_resume_transactions(void);
+void acpi_ec_block_transactions(void);
+void acpi_ec_unblock_transactions(void);
+void acpi_ec_unblock_transactions_early(void);
/*--------------------------------------------------------------------------
Suspend/Resume
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 2e8c27d..b1b3856 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -80,7 +80,7 @@ module_param(nocst, uint, 0000);
static unsigned int latency_factor __read_mostly = 2;
module_param(latency_factor, uint, 0644);
-static s64 us_to_pm_timer_ticks(s64 t)
+static u64 us_to_pm_timer_ticks(s64 t)
{
return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
}
@@ -731,10 +731,10 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
seq_puts(seq, "demotion[--] ");
- seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n",
+ seq_printf(seq, "latency[%03d] usage[%08d] duration[%020Lu]\n",
pr->power.states[i].latency,
pr->power.states[i].usage,
- (unsigned long long)pr->power.states[i].time);
+ us_to_pm_timer_ticks(pr->power.states[i].time));
}
end:
@@ -861,7 +861,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
ktime_t kt1, kt2;
s64 idle_time_ns;
s64 idle_time;
- s64 sleep_ticks = 0;
pr = __get_cpu_var(processors);
@@ -906,8 +905,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
idle_time = idle_time_ns;
do_div(idle_time, NSEC_PER_USEC);
- sleep_ticks = us_to_pm_timer_ticks(idle_time);
-
/* Tell the scheduler how much we idled: */
sched_clock_idle_wakeup_event(idle_time_ns);
@@ -918,7 +915,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
cx->usage++;
lapic_timer_state_broadcast(pr, cx, 0);
- cx->time += sleep_ticks;
+ cx->time += idle_time;
return idle_time;
}
@@ -940,7 +937,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
ktime_t kt1, kt2;
s64 idle_time_ns;
s64 idle_time;
- s64 sleep_ticks = 0;
pr = __get_cpu_var(processors);
@@ -1022,11 +1018,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
spin_unlock(&c3_lock);
}
kt2 = ktime_get_real();
- idle_time_ns = ktime_to_us(ktime_sub(kt2, kt1));
+ idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
idle_time = idle_time_ns;
do_div(idle_time, NSEC_PER_USEC);
- sleep_ticks = us_to_pm_timer_ticks(idle_time);
/* Tell the scheduler how much we idled: */
sched_clock_idle_wakeup_event(idle_time_ns);
@@ -1037,7 +1032,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
cx->usage++;
lapic_timer_state_broadcast(pr, cx, 0);
- cx->time += sleep_ticks;
+ cx->time += idle_time;
return idle_time;
}
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 4ab2275..3fb4bde 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -94,11 +94,13 @@ void __init acpi_old_suspend_ordering(void)
}
/**
- * acpi_pm_disable_gpes - Disable the GPEs.
+ * acpi_pm_freeze - Disable the GPEs and suspend EC transactions.
*/
-static int acpi_pm_disable_gpes(void)
+static int acpi_pm_freeze(void)
{
acpi_disable_all_gpes();
+ acpi_os_wait_events_complete(NULL);
+ acpi_ec_block_transactions();
return 0;
}
@@ -126,7 +128,8 @@ static int acpi_pm_prepare(void)
int error = __acpi_pm_prepare();
if (!error)
- acpi_disable_all_gpes();
+ acpi_pm_freeze();
+
return error;
}
@@ -256,6 +259,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
* acpi_leave_sleep_state will reenable specific GPEs later
*/
acpi_disable_all_gpes();
+ /* Allow EC transactions to happen. */
+ acpi_ec_unblock_transactions_early();
local_irq_restore(flags);
printk(KERN_DEBUG "Back to C!\n");
@@ -267,6 +272,12 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
return ACPI_SUCCESS(status) ? 0 : -EFAULT;
}
+static void acpi_suspend_finish(void)
+{
+ acpi_ec_unblock_transactions();
+ acpi_pm_finish();
+}
+
static int acpi_suspend_state_valid(suspend_state_t pm_state)
{
u32 acpi_state;
@@ -288,7 +299,7 @@ static struct platform_suspend_ops acpi_suspend_ops = {
.begin = acpi_suspend_begin,
.prepare_late = acpi_pm_prepare,
.enter = acpi_suspend_enter,
- .wake = acpi_pm_finish,
+ .wake = acpi_suspend_finish,
.end = acpi_pm_end,
};
@@ -314,9 +325,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
static struct platform_suspend_ops acpi_suspend_ops_old = {
.valid = acpi_suspend_state_valid,
.begin = acpi_suspend_begin_old,
- .prepare_late = acpi_pm_disable_gpes,
+ .prepare_late = acpi_pm_freeze,
.enter = acpi_suspend_enter,
- .wake = acpi_pm_finish,
+ .wake = acpi_suspend_finish,
.end = acpi_pm_end,
.recover = acpi_pm_finish,
};
@@ -433,6 +444,7 @@ static int acpi_hibernation_enter(void)
static void acpi_hibernation_finish(void)
{
hibernate_nvs_free();
+ acpi_ec_unblock_transactions();
acpi_pm_finish();
}
@@ -453,19 +465,13 @@ static void acpi_hibernation_leave(void)
}
/* Restore the NVS memory area */
hibernate_nvs_restore();
+ /* Allow EC transactions to happen. */
+ acpi_ec_unblock_transactions_early();
}
-static int acpi_pm_pre_restore(void)
-{
- acpi_disable_all_gpes();
- acpi_os_wait_events_complete(NULL);
- acpi_ec_suspend_transactions();
- return 0;
-}
-
-static void acpi_pm_restore_cleanup(void)
+static void acpi_pm_thaw(void)
{
- acpi_ec_resume_transactions();
+ acpi_ec_unblock_transactions();
acpi_enable_all_runtime_gpes();
}
@@ -477,8 +483,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
.prepare = acpi_pm_prepare,
.enter = acpi_hibernation_enter,
.leave = acpi_hibernation_leave,
- .pre_restore = acpi_pm_pre_restore,
- .restore_cleanup = acpi_pm_restore_cleanup,
+ .pre_restore = acpi_pm_freeze,
+ .restore_cleanup = acpi_pm_thaw,
};
/**
@@ -510,12 +516,9 @@ static int acpi_hibernation_begin_old(void)
static int acpi_hibernation_pre_snapshot_old(void)
{
- int error = acpi_pm_disable_gpes();
-
- if (!error)
- hibernate_nvs_save();
-
- return error;
+ acpi_pm_freeze();
+ hibernate_nvs_save();
+ return 0;
}
/*
@@ -527,11 +530,11 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = {
.end = acpi_pm_end,
.pre_snapshot = acpi_hibernation_pre_snapshot_old,
.finish = acpi_hibernation_finish,
- .prepare = acpi_pm_disable_gpes,
+ .prepare = acpi_pm_freeze,
.enter = acpi_hibernation_enter,
.leave = acpi_hibernation_leave,
- .pre_restore = acpi_pm_pre_restore,
- .restore_cleanup = acpi_pm_restore_cleanup,
+ .pre_restore = acpi_pm_freeze,
+ .restore_cleanup = acpi_pm_thaw,
.recover = acpi_pm_finish,
};
#endif /* CONFIG_HIBERNATION */
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index f09fc0e..7cfcc62 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -1123,6 +1123,7 @@ source "drivers/s390/char/Kconfig"
config RAMOOPS
tristate "Log panic/oops to a RAM buffer"
+ depends on HAS_IOMEM
default n
help
This enables panic and oops messages to be logged to a circular
diff --git a/drivers/misc/vmware_balloon.c b/drivers/misc/vmware_balloon.c
index db9cd02..2a1e804 100644
--- a/drivers/misc/vmware_balloon.c
+++ b/drivers/misc/vmware_balloon.c
@@ -45,7 +45,7 @@
MODULE_AUTHOR("VMware, Inc.");
MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver");
-MODULE_VERSION("1.2.1.0-K");
+MODULE_VERSION("1.2.1.1-k");
MODULE_ALIAS("dmi:*:svnVMware*:*");
MODULE_ALIAS("vmware_vmmemctl");
MODULE_LICENSE("GPL");
@@ -101,6 +101,8 @@ MODULE_LICENSE("GPL");
/* Maximum number of page allocations without yielding processor */
#define VMW_BALLOON_YIELD_THRESHOLD 1024
+/* Maximum number of refused pages we accumulate during inflation cycle */
+#define VMW_BALLOON_MAX_REFUSED 16
/*
* Hypervisor communication port definitions.
@@ -183,6 +185,7 @@ struct vmballoon {
/* transient list of non-balloonable pages */
struct list_head refused_pages;
+ unsigned int n_refused_pages;
/* balloon size in pages */
unsigned int size;
@@ -428,14 +431,21 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
/* inform monitor */
locked = vmballoon_send_lock_page(b, page_to_pfn(page));
if (!locked) {
+ STATS_INC(b->stats.refused_alloc);
+
if (b->reset_required) {
__free_page(page);
return -EIO;
}
- /* place on list of non-balloonable pages, retry allocation */
+ /*
+ * Place page on the list of non-balloonable pages
+ * and retry allocation, unless we already accumulated
+ * too many of them, in which case take a breather.
+ */
list_add(&page->lru, &b->refused_pages);
- STATS_INC(b->stats.refused_alloc);
+ if (++b->n_refused_pages >= VMW_BALLOON_MAX_REFUSED)
+ return -EIO;
}
} while (!locked);
@@ -483,6 +493,8 @@ static void vmballoon_release_refused_pages(struct vmballoon *b)
__free_page(page);
STATS_INC(b->stats.refused_free);
}
+
+ b->n_refused_pages = 0;
}
/*
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 2b28168..d98ddcf 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1157,7 +1157,6 @@ static void mmc_omap_start_request(struct mmc_omap_host *host,
mmc_omap_start_command(host, req->cmd);
if (host->dma_in_use)
omap_start_dma(host->dma_ch);
- BUG_ON(irqs_disabled());
}
static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req)
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index e5972b2..70b68d3 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -495,8 +495,6 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
pr_debug("s3c2410_rtc: RTCCON=%02x\n",
readb(s3c_rtc_base + S3C2410_RTCCON));
- s3c_rtc_setfreq(&pdev->dev, 1);
-
device_init_wakeup(&pdev->dev, 1);
/* register RTC and exit */
@@ -510,14 +508,17 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
goto err_nortc;
}
+ s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
+
if (s3c_rtc_cpu_type == TYPE_S3C64XX)
rtc->max_user_freq = 32768;
else
rtc->max_user_freq = 128;
- s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
-
platform_set_drvdata(pdev, rtc);
+
+ s3c_rtc_setfreq(&pdev->dev, 1);
+
return 0;
err_nortc:
diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c
index 0051959..ceba593 100644
--- a/drivers/sfi/sfi_core.c
+++ b/drivers/sfi/sfi_core.c
@@ -441,8 +441,10 @@ struct sfi_table_attr __init *sfi_sysfs_install_table(u64 pa)
ret = sysfs_create_bin_file(tables_kobj,
&tbl_attr->attr);
- if (ret)
+ if (ret) {
kfree(tbl_attr);
+ tbl_attr = NULL;
+ }
sfi_unmap_table(th);
return tbl_attr;
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 0c2f14f..61d7550 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1201,7 +1201,7 @@ made_compressed_probe:
if (rcv->urb == NULL) {
dev_dbg(&intf->dev,
"out of memory (read urbs usb_alloc_urb)\n");
- goto alloc_fail7;
+ goto alloc_fail6;
}
rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -1225,7 +1225,7 @@ made_compressed_probe:
if (snd->urb == NULL) {
dev_dbg(&intf->dev,
"out of memory (write urbs usb_alloc_urb)");
- goto alloc_fail7;
+ goto alloc_fail8;
}
if (usb_endpoint_xfer_int(epwrite))
@@ -1264,6 +1264,7 @@ made_compressed_probe:
i = device_create_file(&intf->dev,
&dev_attr_iCountryCodeRelDate);
if (i < 0) {
+ device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
kfree(acm->country_codes);
goto skip_countries;
}
@@ -1300,6 +1301,7 @@ alloc_fail8:
usb_free_urb(acm->wb[i].urb);
alloc_fail7:
acm_read_buffers_free(acm);
+alloc_fail6:
for (i = 0; i < num_rx_buf; i++)
usb_free_urb(acm->ru[i].urb);
usb_free_urb(acm->ctrlurb);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index ded550e..de98a94 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1328,6 +1328,7 @@ int usb_resume(struct device *dev, pm_message_t msg)
/* For all other calls, take the device back to full power and
* tell the PM core in case it was autosuspended previously.
+ * Unbind the interfaces that will need rebinding later.
*/
} else {
status = usb_resume_both(udev, msg);
@@ -1336,6 +1337,7 @@ int usb_resume(struct device *dev, pm_message_t msg)
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
udev->last_busy = jiffies;
+ do_unbind_rebind(udev, DO_REBIND);
}
}
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 649c0c5..591ae9f 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -295,6 +295,7 @@ config USB_GADGET_S3C_HSOTG
boolean "S3C HS/OtG USB Device controller"
depends on S3C_DEV_USB_HSOTG
select USB_GADGET_S3C_HSOTG_PIO
+ select USB_GADGET_DUALSPEED
help
The Samsung S3C64XX USB2.0 high-speed gadget controller
integrated into the S3C64XX series SoC.
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c
index 43bf445..b91115f 100644
--- a/drivers/usb/gadget/f_audio.c
+++ b/drivers/usb/gadget/f_audio.c
@@ -101,7 +101,7 @@ static struct uac_feature_unit_descriptor_0 feature_unit_desc = {
static struct usb_audio_control mute_control = {
.list = LIST_HEAD_INIT(mute_control.list),
.name = "Mute Control",
- .type = UAC_MUTE_CONTROL,
+ .type = UAC_FU_MUTE,
/* Todo: add real Mute control code */
.set = generic_set_cmd,
.get = generic_get_cmd,
@@ -110,7 +110,7 @@ static struct usb_audio_control mute_control = {
static struct usb_audio_control volume_control = {
.list = LIST_HEAD_INIT(volume_control.list),
.name = "Volume Control",
- .type = UAC_VOLUME_CONTROL,
+ .type = UAC_FU_VOLUME,
/* Todo: add real Volume control code */
.set = generic_set_cmd,
.get = generic_get_cmd,
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 1f73b48..26193ec 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -297,6 +297,12 @@ static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg,
*/
static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
{
+ unsigned int ep;
+ unsigned int addr;
+ unsigned int size;
+ int timeout;
+ u32 val;
+
/* the ryu 2.6.24 release ahs
writel(0x1C0, hsotg->regs + S3C_GRXFSIZ);
writel(S3C_GNPTXFSIZ_NPTxFStAddr(0x200) |
@@ -310,6 +316,51 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
writel(S3C_GNPTXFSIZ_NPTxFStAddr(2048) |
S3C_GNPTXFSIZ_NPTxFDep(0x1C0),
hsotg->regs + S3C_GNPTXFSIZ);
+
+ /* arange all the rest of the TX FIFOs, as some versions of this
+ * block have overlapping default addresses. This also ensures
+ * that if the settings have been changed, then they are set to
+ * known values. */
+
+ /* start at the end of the GNPTXFSIZ, rounded up */
+ addr = 2048 + 1024;
+ size = 768;
+
+ /* currently we allocate TX FIFOs for all possible endpoints,
+ * and assume that they are all the same size. */
+
+ for (ep = 0; ep <= 15; ep++) {
+ val = addr;
+ val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;
+ addr += size;
+
+ writel(val, hsotg->regs + S3C_DPTXFSIZn(ep));
+ }
+
+ /* according to p428 of the design guide, we need to ensure that
+ * all fifos are flushed before continuing */
+
+ writel(S3C_GRSTCTL_TxFNum(0x10) | S3C_GRSTCTL_TxFFlsh |
+ S3C_GRSTCTL_RxFFlsh, hsotg->regs + S3C_GRSTCTL);
+
+ /* wait until the fifos are both flushed */
+ timeout = 100;
+ while (1) {
+ val = readl(hsotg->regs + S3C_GRSTCTL);
+
+ if ((val & (S3C_GRSTCTL_TxFFlsh | S3C_GRSTCTL_RxFFlsh)) == 0)
+ break;
+
+ if (--timeout == 0) {
+ dev_err(hsotg->dev,
+ "%s: timeout flushing fifos (GRSTCTL=%08x)\n",
+ __func__, val);
+ }
+
+ udelay(1);
+ }
+
+ dev_dbg(hsotg->dev, "FIFOs reset, timeout at %d\n", timeout);
}
/**
@@ -2574,6 +2625,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK,
hsotg->regs + S3C_DCTL);
+ /* must be at-least 3ms to allow bus to see disconnect */
+ msleep(3);
+
/* remove the soft-disconnect and let's go */
__bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon);
@@ -2730,6 +2784,9 @@ static void s3c_hsotg_init(struct s3c_hsotg *hsotg)
writel(0, hsotg->regs + S3C_DAINTMSK);
+ /* Be in disconnected state until gadget is registered */
+ __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon);
+
if (0) {
/* post global nak until we're ready */
writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak,
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index ef3e88f..a3ef2a9 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1135,7 +1135,7 @@ MODULE_LICENSE ("GPL");
#ifdef CONFIG_XPS_USB_HCD_XILINX
#include "ehci-xilinx-of.c"
-#define OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver
+#define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver
#endif
#ifdef CONFIG_PLAT_ORION
@@ -1159,7 +1159,8 @@ MODULE_LICENSE ("GPL");
#endif
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
- !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER)
+ !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
+ !defined(XILINX_OF_PLATFORM_DRIVER)
#error "missing bus glue for ehci-hcd"
#endif
@@ -1213,10 +1214,20 @@ static int __init ehci_hcd_init(void)
if (retval < 0)
goto clean3;
#endif
+
+#ifdef XILINX_OF_PLATFORM_DRIVER
+ retval = of_register_platform_driver(&XILINX_OF_PLATFORM_DRIVER);
+ if (retval < 0)
+ goto clean4;
+#endif
return retval;
+#ifdef XILINX_OF_PLATFORM_DRIVER
+ /* of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); */
+clean4:
+#endif
#ifdef OF_PLATFORM_DRIVER
- /* of_unregister_platform_driver(&OF_PLATFORM_DRIVER); */
+ of_unregister_platform_driver(&OF_PLATFORM_DRIVER);
clean3:
#endif
#ifdef PS3_SYSTEM_BUS_DRIVER
@@ -1243,6 +1254,9 @@ module_init(ehci_hcd_init);
static void __exit ehci_hcd_cleanup(void)
{
+#ifdef XILINX_OF_PLATFORM_DRIVER
+ of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER);
+#endif
#ifdef OF_PLATFORM_DRIVER
of_unregister_platform_driver(&OF_PLATFORM_DRIVER);
#endif
diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h
index 5151516..d995351 100644
--- a/drivers/usb/host/isp1362.h
+++ b/drivers/usb/host/isp1362.h
@@ -65,7 +65,7 @@ static inline void delayed_insw(unsigned int addr, void *buf, int len)
unsigned short *bp = (unsigned short *)buf;
while (len--) {
DUMMY_DELAY_ACCESS;
- *bp++ = inw((void *)addr);
+ *bp++ = inw(addr);
}
}
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index edffd81..11482b6 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -78,6 +78,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
" endpoint cmd after reset endpoint\n");
}
+ if (pdev->vendor == PCI_VENDOR_ID_NEC)
+ xhci->quirks |= XHCI_NEC_HOST;
/* Make sure the HC is halted. */
retval = xhci_halt(xhci);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 36c858e..9012098 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1071,6 +1071,15 @@ bandwidth_change:
xhci_warn(xhci, "Reset device command completion "
"for disabled slot %u\n", slot_id);
break;
+ case TRB_TYPE(TRB_NEC_GET_FW):
+ if (!(xhci->quirks & XHCI_NEC_HOST)) {
+ xhci->error_bitmask |= 1 << 6;
+ break;
+ }
+ xhci_dbg(xhci, "NEC firmware version %2x.%02x\n",
+ NEC_FW_MAJOR(event->status),
+ NEC_FW_MINOR(event->status));
+ break;
default:
/* Skip over unknown commands on the event ring */
xhci->error_bitmask |= 1 << 6;
@@ -1079,6 +1088,17 @@ bandwidth_change:
inc_deq(xhci, xhci->cmd_ring, false);
}
+static void handle_vendor_event(struct xhci_hcd *xhci,
+ union xhci_trb *event)
+{
+ u32 trb_type;
+
+ trb_type = TRB_FIELD_TO_TYPE(event->generic.field[3]);
+ xhci_dbg(xhci, "Vendor specific event TRB type = %u\n", trb_type);
+ if (trb_type == TRB_NEC_CMD_COMP && (xhci->quirks & XHCI_NEC_HOST))
+ handle_cmd_completion(xhci, &event->event_cmd);
+}
+
static void handle_port_status(struct xhci_hcd *xhci,
union xhci_trb *event)
{
@@ -1659,7 +1679,10 @@ void xhci_handle_event(struct xhci_hcd *xhci)
update_ptrs = 0;
break;
default:
- xhci->error_bitmask |= 1 << 3;
+ if ((event->event_cmd.flags & TRB_TYPE_BITMASK) >= TRB_TYPE(48))
+ handle_vendor_event(xhci, event);
+ else
+ xhci->error_bitmask |= 1 << 3;
}
/* Any of the above functions may drop and re-acquire the lock, so check
* to make sure a watchdog timer didn't mark the host as non-responsive.
@@ -2378,6 +2401,12 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
false);
}
+int xhci_queue_vendor_command(struct xhci_hcd *xhci,
+ u32 field1, u32 field2, u32 field3, u32 field4)
+{
+ return queue_command(xhci, field1, field2, field3, field4, false);
+}
+
/* Queue a reset device command TRB */
int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id)
{
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 40e0a0c..27345cd 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -106,6 +106,33 @@ int xhci_halt(struct xhci_hcd *xhci)
}
/*
+ * Set the run bit and wait for the host to be running.
+ */
+int xhci_start(struct xhci_hcd *xhci)
+{
+ u32 temp;
+ int ret;
+
+ temp = xhci_readl(xhci, &xhci->op_regs->command);
+ temp |= (CMD_RUN);
+ xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n",
+ temp);
+ xhci_writel(xhci, temp, &xhci->op_regs->command);
+
+ /*
+ * Wait for the HCHalted Status bit to be 0 to indicate the host is
+ * running.
+ */
+ ret = handshake(xhci, &xhci->op_regs->status,
+ STS_HALT, 0, XHCI_MAX_HALT_USEC);
+ if (ret == -ETIMEDOUT)
+ xhci_err(xhci, "Host took too long to start, "
+ "waited %u microseconds.\n",
+ XHCI_MAX_HALT_USEC);
+ return ret;
+}
+
+/*
* Reset a halted HC, and set the internal HC state to HC_STATE_HALT.
*
* This resets pipelines, timers, counters, state machines, etc.
@@ -116,6 +143,7 @@ int xhci_reset(struct xhci_hcd *xhci)
{
u32 command;
u32 state;
+ int ret;
state = xhci_readl(xhci, &xhci->op_regs->status);
if ((state & STS_HALT) == 0) {
@@ -130,7 +158,17 @@ int xhci_reset(struct xhci_hcd *xhci)
/* XXX: Why does EHCI set this here? Shouldn't other code do this? */
xhci_to_hcd(xhci)->state = HC_STATE_HALT;
- return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000);
+ ret = handshake(xhci, &xhci->op_regs->command,
+ CMD_RESET, 0, 250 * 1000);
+ if (ret)
+ return ret;
+
+ xhci_dbg(xhci, "Wait for controller to be ready for doorbell rings\n");
+ /*
+ * xHCI cannot write to any doorbells or operational registers other
+ * than status until the "Controller Not Ready" flag is cleared.
+ */
+ return handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000);
}
@@ -448,17 +486,20 @@ int xhci_run(struct usb_hcd *hcd)
if (NUM_TEST_NOOPS > 0)
doorbell = xhci_setup_one_noop(xhci);
+ if (xhci->quirks & XHCI_NEC_HOST)
+ xhci_queue_vendor_command(xhci, 0, 0, 0,
+ TRB_TYPE(TRB_NEC_GET_FW));
+
+ if (xhci_start(xhci)) {
+ xhci_halt(xhci);
+ return -ENODEV;
+ }
- temp = xhci_readl(xhci, &xhci->op_regs->command);
- temp |= (CMD_RUN);
- xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n",
- temp);
- xhci_writel(xhci, temp, &xhci->op_regs->command);
- /* Flush PCI posted writes */
- temp = xhci_readl(xhci, &xhci->op_regs->command);
xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp);
if (doorbell)
(*doorbell)(xhci);
+ if (xhci->quirks & XHCI_NEC_HOST)
+ xhci_ring_cmd_db(xhci);
xhci_dbg(xhci, "Finished xhci_run\n");
return 0;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index dada2fb..8b4b7d3 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -925,6 +925,7 @@ union xhci_trb {
/* TRB bit mask */
#define TRB_TYPE_BITMASK (0xfc00)
#define TRB_TYPE(p) ((p) << 10)
+#define TRB_FIELD_TO_TYPE(p) (((p) & TRB_TYPE_BITMASK) >> 10)
/* TRB type IDs */
/* bulk, interrupt, isoc scatter/gather, and control data stage */
#define TRB_NORMAL 1
@@ -992,6 +993,14 @@ union xhci_trb {
#define TRB_MFINDEX_WRAP 39
/* TRB IDs 40-47 reserved, 48-63 is vendor-defined */
+/* Nec vendor-specific command completion event. */
+#define TRB_NEC_CMD_COMP 48
+/* Get NEC firmware revision. */
+#define TRB_NEC_GET_FW 49
+
+#define NEC_FW_MINOR(p) (((p) >> 0) & 0xff)
+#define NEC_FW_MAJOR(p) (((p) >> 8) & 0xff)
+
/*
* TRBS_PER_SEGMENT must be a multiple of 4,
* since the command ring is 64-byte aligned.
@@ -1172,6 +1181,7 @@ struct xhci_hcd {
unsigned int quirks;
#define XHCI_LINK_TRB_QUIRK (1 << 0)
#define XHCI_RESET_EP_QUIRK (1 << 1)
+#define XHCI_NEC_HOST (1 << 2)
};
/* For testing purposes */
@@ -1379,6 +1389,8 @@ void xhci_set_hc_event_deq(struct xhci_hcd *xhci);
int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id);
int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
u32 slot_id);
+int xhci_queue_vendor_command(struct xhci_hcd *xhci,
+ u32 field1, u32 field2, u32 field3, u32 field4);
int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id,
unsigned int ep_index);
int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 3edda3e..fd35f73 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -1239,8 +1239,7 @@ static void digi_write_bulk_callback(struct urb *urb)
/* port and serial sanity check */
if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) {
- dev_err(&port->dev,
- "%s: port or port->private is NULL, status=%d\n",
+ pr_err("%s: port or port->private is NULL, status=%d\n",
__func__, status);
return;
}
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 050211a..79dd1ae 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -2005,6 +2005,8 @@ static void ftdi_set_termios(struct tty_struct *tty,
"urb failed to set to rts/cts flow control\n");
}
+ /* raise DTR/RTS */
+ set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
} else {
/*
* Xon/Xoff code
@@ -2052,6 +2054,8 @@ static void ftdi_set_termios(struct tty_struct *tty,
}
}
+ /* lower DTR/RTS */
+ clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
}
return;
}
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index f8424d1..585b7e6 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -730,7 +730,6 @@ static void mos7840_bulk_in_callback(struct urb *urb)
mos7840_port = urb->context;
if (!mos7840_port) {
dbg("%s", "NULL mos7840_port pointer");
- mos7840_port->read_urb_busy = false;
return;
}
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 1e6fec4..3d94a14 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -8,6 +8,9 @@ menu "Graphics support"
config HAVE_FB_ATMEL
bool
+config HAVE_FB_IMX
+ bool
+
source "drivers/char/agp/Kconfig"
source "drivers/gpu/vga/Kconfig"
@@ -400,9 +403,6 @@ config FB_SA1100
If you plan to use the LCD display with your SA-1100 system, say
Y here.
-config HAVE_FB_IMX
- bool
-
config FB_IMX
tristate "Motorola i.MX LCD support"
depends on FB && (HAVE_FB_IMX || ARCH_MX1 || ARCH_MX2)
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 073c9b4..6b93ef9 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -100,6 +100,16 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
/* protect against the workqueue changing the page list */
mutex_lock(&fbdefio->lock);
+ /*
+ * We want the page to remain locked from ->page_mkwrite until
+ * the PTE is marked dirty to avoid page_mkclean() being called
+ * before the PTE is updated, which would leave the page ignored
+ * by defio.
+ * Do this by locking the page here and informing the caller
+ * about it with VM_FAULT_LOCKED.
+ */
+ lock_page(page);
+
/* we loop through the pagelist before adding in order
to keep the pagelist sorted */
list_for_each_entry(cur, &fbdefio->pagelist, lru) {
@@ -121,7 +131,7 @@ page_already_added:
/* come back after delay to process the deferred IO */
schedule_delayed_work(&info->deferred_work, fbdefio->delay);
- return 0;
+ return VM_FAULT_LOCKED;
}
static const struct vm_operations_struct fb_deferred_io_vm_ops = {
@@ -155,41 +165,25 @@ static void fb_deferred_io_work(struct work_struct *work)
{
struct fb_info *info = container_of(work, struct fb_info,
deferred_work.work);
+ struct list_head *node, *next;
+ struct page *cur;
struct fb_deferred_io *fbdefio = info->fbdefio;
- struct page *page, *tmp_page;
- struct list_head *node, *tmp_node;
- struct list_head non_dirty;
-
- INIT_LIST_HEAD(&non_dirty);
/* here we mkclean the pages, then do all deferred IO */
mutex_lock(&fbdefio->lock);
- list_for_each_entry_safe(page, tmp_page, &fbdefio->pagelist, lru) {
- lock_page(page);
- /*
- * The workqueue callback can be triggered after a
- * ->page_mkwrite() call but before the PTE has been marked
- * dirty. In this case page_mkclean() won't "rearm" the page.
- *
- * To avoid this, remove those "non-dirty" pages from the
- * pagelist before calling the driver's callback, then add
- * them back to get processed on the next work iteration.
- * At that time, their PTEs will hopefully be dirty for real.
- */
- if (!page_mkclean(page))
- list_move_tail(&page->lru, &non_dirty);
- unlock_page(page);
+ list_for_each_entry(cur, &fbdefio->pagelist, lru) {
+ lock_page(cur);
+ page_mkclean(cur);
+ unlock_page(cur);
}
/* driver's callback with pagelist */
fbdefio->deferred_io(info, &fbdefio->pagelist);
- /* clear the list... */
- list_for_each_safe(node, tmp_node, &fbdefio->pagelist) {
+ /* clear the list */
+ list_for_each_safe(node, next, &fbdefio->pagelist) {
list_del(node);
}
- /* ... and add back the "non-dirty" pages to the list */
- list_splice_tail(&non_dirty, &fbdefio->pagelist);
mutex_unlock(&fbdefio->lock);
}
@@ -218,7 +212,6 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_open);
void fb_deferred_io_cleanup(struct fb_info *info)
{
struct fb_deferred_io *fbdefio = info->fbdefio;
- struct list_head *node, *tmp_node;
struct page *page;
int i;
@@ -226,13 +219,6 @@ void fb_deferred_io_cleanup(struct fb_info *info)
cancel_delayed_work(&info->deferred_work);
flush_scheduled_work();
- /* the list may have still some non-dirty pages at this point */
- mutex_lock(&fbdefio->lock);
- list_for_each_safe(node, tmp_node, &fbdefio->pagelist) {
- list_del(node);
- }
- mutex_unlock(&fbdefio->lock);
-
/* clear out the mapping that we setup */
for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
page = fb_deferred_io_page(info, i);