pte_t *ptep, pte_t pte)
{
if (pte_valid_user(pte)) {
- if (pte_exec(pte))
+ if (!pte_special(pte) && pte_exec(pte))
__sync_icache_dcache(pte, addr);
- if (!pte_dirty(pte))
- pte = pte_wrprotect(pte);
+ if (pte_dirty(pte) && pte_write(pte))
+ pte_val(pte) &= ~PTE_RDONLY;
+ else
+ pte_val(pte) |= PTE_RDONLY;
}
set_pte(ptep, pte);
if (hdev)
hci_uart_close(hdev);
+ cancel_work_sync(&hu->write_work);
+
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
+ hu->proto->close(hu);
if (hdev) {
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
hci_unregister_dev(hdev);
*
* Tries to change the PowerNow! multiplier
*/
-static void powernow_k6_set_state(struct cpufreq_policy *policy,
- unsigned int best_i)
+static void powernow_k6_set_state(unsigned int best_i)
{
- unsigned long outvalue = 0, invalue = 0;
- unsigned long msrval;
struct cpufreq_freqs freqs;
if (clock_ratio[best_i].index > max_multiplier) {
freqs.old = busfreq * powernow_k6_get_cpu_multiplier();
freqs.new = busfreq * clock_ratio[best_i].index;
+ freqs.cpu = 0; /* powernow-k6.c is UP only driver */
- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- /* we now need to transform best_i to the BVC format, see AMD#23446 */
-
- outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5);
-
- msrval = POWERNOW_IOPORT + 0x1;
- wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
- invalue = inl(POWERNOW_IOPORT + 0x8);
- invalue = invalue & 0xf;
- outvalue = outvalue | invalue;
- outl(outvalue , (POWERNOW_IOPORT + 0x8));
- msrval = POWERNOW_IOPORT + 0x0;
- wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
+ powernow_k6_set_cpu_multiplier(best_i);
- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return;
}
{
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
unsigned int cpu, shift = (gic_irq(d) % 4) * 8;
+ struct gic_chip_data *gic = irq_data_get_irq_chip_data(d);
u32 val, mask, bit;
+#ifdef CONFIG_GIC_SET_MULTIPLE_CPUS
+ struct irq_desc *desc = irq_to_desc(d->irq);
+#endif
+
++ if (!force)
++ cpu = cpumask_any_and(mask_val, cpu_online_mask);
++ else
++ cpu = cpumask_first(mask_val);
+
if (!force)
cpu = cpumask_any_and(mask_val, cpu_online_mask);
else
return 0;
}
+static int machine_constraints_current(struct regulator_dev *rdev,
+ struct regulation_constraints *constraints)
+{
+ struct regulator_ops *ops = rdev->desc->ops;
+ int ret;
+
+ if (constraints->ignore_current_constraint_init)
+ return 0;
+ if (!constraints->min_uA && !constraints->max_uA)
+ return 0;
+
+ if (constraints->min_uA > constraints->max_uA) {
+ rdev_err(rdev, "Invalid current constraints\n");
+ return -EINVAL;
+ }
+
+ if (!ops->set_current_limit || !ops->get_current_limit) {
+ rdev_warn(rdev, "Operation of current configuration missing\n");
+ return 0;
+ }
+
+ /* Set regulator current in constraints range */
+ ret = ops->set_current_limit(rdev, constraints->min_uA,
+ constraints->max_uA);
+ if (ret < 0) {
+ rdev_err(rdev, "Failed to set current constraint, %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+ static int _regulator_do_enable(struct regulator_dev *rdev);
/**
* set_machine_constraints - sets regulator constraints
if (_regulator_can_change_status(rdev)) {
ret = _regulator_do_disable(rdev);
if (ret < 0) {
- rdev_err(rdev, "failed to disable\n");
+ rdev_err(rdev, "failed to disable: %d\n", ret);
return ret;
}
+ _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
+ NULL);
}
rdev->use_count = 0;
acm->is_int_ep = usb_endpoint_xfer_int(epread);
if (acm->is_int_ep)
acm->bInterval = epread->bInterval;
+ if (quirks & NO_HANGUP_IN_RESET_RESUME)
+ acm->no_hangup_in_reset_resume = 1;
tty_port_init(&acm->port);
acm->port.ops = &acm_port_ops;
+ init_usb_anchor(&acm->delayed);
buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
if (!buf) {
struct acm *acm = usb_get_intfdata(intf);
struct usb_device *usb_dev = interface_to_usbdev(intf);
struct tty_struct *tty;
++ struct urb *res;
int i;
dev_dbg(&intf->dev, "%s\n", __func__);
struct acm *acm = usb_get_intfdata(intf);
int cnt;
+ if (!acm) {
+ pr_err("%s: !acm\n", __func__);
+ return -ENODEV;
+ }
+
+ spin_lock_irq(&acm->read_lock);
+ spin_lock(&acm->write_lock);
if (PMSG_IS_AUTO(message)) {
- int b;
-
- spin_lock_irq(&acm->write_lock);
- b = acm->transmitting;
- spin_unlock_irq(&acm->write_lock);
- if (b)
+ if (acm->transmitting) {
+ spin_unlock(&acm->write_lock);
+ spin_unlock_irq(&acm->read_lock);
return -EBUSY;
+ }
}
-
- spin_lock_irq(&acm->read_lock);
- spin_lock(&acm->write_lock);
cnt = acm->susp_count++;
spin_unlock(&acm->write_lock);
spin_unlock_irq(&acm->read_lock);
static int acm_resume(struct usb_interface *intf)
{
struct acm *acm = usb_get_intfdata(intf);
- struct acm_wb *wb;
+ struct urb *urb;
int rv = 0;
- int cnt;
+ if (!acm) {
+ pr_err("%s: !acm\n", __func__);
+ return -ENODEV;
+ }
+
spin_lock_irq(&acm->read_lock);
- if (acm->susp_count > 0) {
- acm->susp_count -= 1;
- cnt = acm->susp_count;
- } else {
- spin_unlock_irq(&acm->read_lock);
- return 0;
- }
- spin_unlock_irq(&acm->read_lock);
+ spin_lock(&acm->write_lock);
++ if (acm->susp_count <= 0)
++ goto out;
- if (cnt)
- return 0;
+ if (--acm->susp_count)
+ goto out;
if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {
- rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
-
- spin_lock_irq(&acm->write_lock);
- if (acm->delayed_wb) {
- wb = acm->delayed_wb;
- acm->delayed_wb = NULL;
- spin_unlock_irq(&acm->write_lock);
- acm_start_wb(acm, wb);
- } else {
- spin_unlock_irq(&acm->write_lock);
+ rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);
+
+ for (;;) {
+ urb = usb_get_from_anchor(&acm->delayed);
+ if (!urb)
+ break;
+
+ acm_start_wb(acm, urb->context);
}
/*
unsigned int susp_count; /* number of suspended interfaces */
unsigned int combined_interfaces:1; /* control and data collapsed */
unsigned int is_int_ep:1; /* interrupt endpoints contrary to spec used */
+ unsigned int int_throttled:1; /* internal throttled */
unsigned int throttled:1; /* actually throttled */
unsigned int throttle_req:1; /* throttle requested */
+ unsigned int no_hangup_in_reset_resume:1; /* do not call tty_hangup in acm_reset_resume */
u8 bInterval;
- struct acm_wb *delayed_wb; /* write queued for a device about to be woken */
+ struct usb_anchor delayed; /* writes queued for a device about to be woken */
};
#define CDC_DATA_INTERFACE_TYPE 0x0a
desc = intf->cur_altsetting;
hdev = interface_to_usbdev(intf);
- /* Hubs have proper suspend/resume support. */
- usb_enable_autosuspend(hdev);
- /*
- * Set default autosuspend delay as 0 to speedup bus suspend,
- * based on the below considerations:
- *
- * - Unlike other drivers, the hub driver does not rely on the
- * autosuspend delay to provide enough time to handle a wakeup
- * event, and the submitted status URB is just to check future
- * change on hub downstream ports, so it is safe to do it.
- *
- * - The patch might cause one or more auto supend/resume for
- * below very rare devices when they are plugged into hub
- * first time:
- *
- * devices having trouble initializing, and disconnect
- * themselves from the bus and then reconnect a second
- * or so later
- *
- * devices just for downloading firmware, and disconnects
- * themselves after completing it
- *
- * For these quite rare devices, their drivers may change the
- * autosuspend delay of their parent hub in the probe() to one
- * appropriate value to avoid the subtle problem if someone
- * does care it.
- *
- * - The patch may cause one or more auto suspend/resume on
- * hub during running 'lsusb', but it is probably too
- * infrequent to worry about.
- *
- * - Change autosuspend delay of hub can avoid unnecessary auto
- * suspend timer for hub, also may decrease power consumption
- * of USB bus.
- */
- pm_runtime_set_autosuspend_delay(&hdev->dev, 0);
-
+ /*
+ * Hubs have proper suspend/resume support, except for root hubs
+ * where the controller driver doesn't have bus_suspend and
+ * bus_resume methods.
+ */
+ if (hdev->parent) { /* normal device */
+ usb_enable_autosuspend(hdev);
+ } else { /* root hub */
+ const struct hc_driver *drv = bus_to_hcd(hdev->bus)->driver;
+
+ if (drv->bus_suspend && drv->bus_resume)
+ usb_enable_autosuspend(hdev);
+ }
if (hdev->level == MAX_TOPO_LEVEL) {
dev_err(&intf->dev,
}
memcpy(&saved_cmdlines[idx], tsk->comm, TASK_COMM_LEN);
+ saved_tgids[idx] = tsk->tgid;
arch_spin_unlock(&trace_cmdline_lock);
+
+ return 1;
}
void trace_find_cmdline(int pid, char comm[])