/** * Detects USB cable type and notifies USB driver * * @pdata Pointer to the charger type detection driver data structure * return 0 on success, otherwise error code */ static int pmic_usb_cable_det(struct pmic_usb_det_data *pdata) { u8 reg, val; int ret; int *p_cable_type; enum usb_phy_events event = USB_EVENT_VBUS; if (!pdata || !pdata->pdev) return -EINVAL; p_cable_type = &pdata->cable_type; ret = pmic_reg_read(DEV3, USBSRCDETSTATUS0, ®); if (ret) { dev_err(pdata->pdev, "%s - fail to read DEV3 USBSRCDETSTATUS0\n", __func__); return ret; } /* Check for detection status */ val = get_field(reg, SUSBHWDET_O, SUSBHWDET_W); if (val != 0x2) { dev_err(pdata->pdev, "Detection not completed, status=%d\n", val); return -EIO; } /* Check for detection result */ val = get_field(reg, USBSRCDETRSLT_O, USBSRCDETRSLT_W); switch (val) { case USB_UNKNOWN: *p_cable_type = POWER_SUPPLY_CHARGER_TYPE_NONE; dev_info(pdata->pdev, "USB cable type - Unknown\n"); break; case USB_SDP: *p_cable_type = POWER_SUPPLY_CHARGER_TYPE_USB_SDP; dev_info(pdata->pdev, "USB cable type - SDP\n"); break; case USB_DCP: *p_cable_type = POWER_SUPPLY_CHARGER_TYPE_USB_DCP; dev_info(pdata->pdev, "USB cable type - DCP\n"); break; case USB_CDP: *p_cable_type = POWER_SUPPLY_CHARGER_TYPE_USB_CDP; dev_info(pdata->pdev, "USB cable type - CDP\n"); break; case USB_ACA: if (*p_cable_type == POWER_SUPPLY_CHARGER_TYPE_USB_ACA) { dev_info(pdata->pdev, "ACA charger already reported by USBID\n"); return 0; } *p_cable_type = POWER_SUPPLY_CHARGER_TYPE_USB_ACA; event = USB_EVENT_ID; dev_info(pdata->pdev, "USB cable type - ACA\n"); break; case USB_SE1: /* SE1, report it as DCP at this moment */ *p_cable_type = POWER_SUPPLY_CHARGER_TYPE_USB_DCP; dev_info(pdata->pdev, "USB cable type - SE1, report it as DCP\n"); break; case USB_MHL: /* MHL, report it as NONE at this moment */ *p_cable_type = POWER_SUPPLY_CHARGER_TYPE_NONE; dev_info(pdata->pdev, "USB cable type - MHL, report it as Unknown\n"); break; case USB_FLOAT: /* FLOATING, report it as NONE */ *p_cable_type = POWER_SUPPLY_CHARGER_TYPE_NONE; dev_info(pdata->pdev, "USB cable type - Floating, report it as Unknown\n"); break; default: *p_cable_type = POWER_SUPPLY_CHARGER_TYPE_NONE; dev_info(pdata->pdev, "USB cable type - Unknown\n"); break; } /* Send notification to USB driver */ pdata->cable_props.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_CONNECT; pdata->cable_props.chrg_type = *p_cable_type; pdata->cable_props.ma = 0; /* Disable the internal detection circuit */ ret = pmic_usb_enable_usb_det(pdata, false); if (ret) { dev_err(pdata->pdev, "%s - fail to disable USB detection\n", __func__); return ret; } /* Notify USB driver about the type detection result */ atomic_notifier_call_chain(&pdata->otg_handle->notifier, event, &pdata->cable_props); return 0; }
int dwc3_intel_byt_platform_init(struct dwc_otg2 *otg) { struct intel_dwc_otg_pdata *data; u32 gctl; int id_value; int retval; data = (struct intel_dwc_otg_pdata *)otg->otg_data; if (data) INIT_DELAYED_WORK(&data->suspend_discon_work, dwc_otg_suspend_discon_work); if (data && data->gpio_cs && data->gpio_reset) { retval = gpio_request(data->gpio_cs, "phy_cs"); if (retval < 0) { otg_err(otg, "failed to request CS pin %d\n", data->gpio_cs); return retval; } retval = gpio_request(data->gpio_reset, "phy_reset"); if (retval < 0) { otg_err(otg, "failed to request RESET pin %d\n", data->gpio_reset); return retval; } } if (data && data->gpio_id) { dev_info(otg->dev, "USB ID detection - Enabled - GPIO\n"); /* Set ID default value to 1 Floating */ data->id = 1; retval = gpio_request(data->gpio_id, "gpio_id"); if (retval < 0) { otg_err(otg, "failed to request ID pin %d\n", data->gpio_id); return retval; } retval = gpio_direction_input(data->gpio_id); if (retval < 0) { otg_err(otg, "failed to request ID pin %d\n", data->gpio_id); return retval; } retval = request_threaded_irq(gpio_to_irq(data->gpio_id), NULL, dwc3_gpio_id_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "dwc-gpio-id", otg->dev); if (retval < 0) { otg_err(otg, "failed to request interrupt gpio ID\n"); return retval; } otg_dbg(otg, "GPIO ID request/Interrupt reuqest Done\n"); id_value = dwc3_check_gpio_id(otg); if ((id_value == 0 || id_value == 1) && (data->id != id_value)) { data->id = id_value; dev_info(otg->dev, "ID notification (id = %d)\n", data->id); atomic_notifier_call_chain(&otg->usb2_phy.notifier, USB_EVENT_ID, &id_value); } else otg_dbg(otg, "Get incorrect ID value %d\n", id_value); } /* Don't let phy go to suspend mode, which * will cause FS/LS devices enum failed in host mode. */ set_sus_phy(otg, 0); retval = device_create_file(otg->dev, &dev_attr_otg_id); if (retval < 0) { otg_dbg(otg, "Can't register sysfs attribute: %d\n", retval); return -ENOMEM; } retval = device_create_file(otg->dev, &dev_attr_vbus_evt); if (retval < 0) { otg_dbg(otg, "Can't register sysfs attribute: %d\n", retval); return -ENOMEM; } otg_dbg(otg, "\n"); otg_write(otg, OEVTEN, 0); otg_write(otg, OCTL, 0); gctl = otg_read(otg, GCTL); gctl |= GCTL_PRT_CAP_DIR_OTG << GCTL_PRT_CAP_DIR_SHIFT; otg_write(otg, GCTL, gctl); return 0; }
static void bcmpmu_otg_xceiv_vbus_a_invalid_handler(struct work_struct *work) { struct bcmpmu_otg_xceiv_data *xceiv_data = container_of(work, struct bcmpmu_otg_xceiv_data, bcm_otg_vbus_a_invalid_work); int bcm_hsotgctrl_status; /* dev_info(xceiv_data->dev, "A session invalid\n"); */ fsa9485_vbus_check(0); if ( !(bcm_hsotgctrl_status = bcm_hsotgctrl_get_clk_count()) ) bcm_hsotgctrl_en_clock(true); else if (-ENODEV == bcm_hsotgctrl_status || -EIO == bcm_hsotgctrl_status ) return ; /* Inform the core of session invalid level */ bcm_hsotgctrl_phy_set_vbus_stat(false); if (xceiv_data->otg_enabled) { /* Stop Vbus discharge */ bcmpmu_usb_set(xceiv_data->bcmpmu, BCMPMU_USB_CTRL_DISCHRG_VBUS, 0); if (bcmpmu_otg_xceiv_check_id_gnd(xceiv_data)) { /* Use n-1 method for ADP rise time comparison */ bcmpmu_usb_set(xceiv_data->bcmpmu, BCMPMU_USB_CTRL_SET_ADP_COMP_METHOD, 1); if (xceiv_data->otg_xceiver.otg_vbus_off) schedule_delayed_work(&xceiv_data-> bcm_otg_delayed_adp_work, msecs_to_jiffies (T_NO_ADP_DELAY_MIN_IN_MS)); else bcm_otg_do_adp_probe(xceiv_data, true); } else if (!bcmpmu_otg_xceiv_check_id_rid_a(xceiv_data)) { /* Vbus is off now so don't allow * core to connect */ bcm_hsotgctrl_phy_set_non_driving(true); if (xceiv_data->otg_xceiver.otg_srp_reqd) { /* Start Session End SRP timer */ xceiv_data->otg_xceiver.sess_end_srp_timer.expires = jiffies + msecs_to_jiffies(T_SESS_END_SRP_START_IN_MS); add_timer(&xceiv_data->otg_xceiver.sess_end_srp_timer); } else bcm_otg_do_adp_sense(xceiv_data, true); } } else { bool id_default_host = false; id_default_host = bcmpmu_otg_xceiv_check_id_gnd(xceiv_data) || bcmpmu_otg_xceiv_check_id_rid_a(xceiv_data); if (!id_default_host) { atomic_notifier_call_chain(&xceiv_data->otg_xceiver. xceiver.notifier, USB_EVENT_NONE, NULL); } } }
NORET_TYPE void panic(const char * fmt, ...) { long i; static char buf[1024]; va_list args; #if defined(CONFIG_S390) unsigned long caller = (unsigned long) __builtin_return_address(0); #endif /* * It's possible to come here directly from a panic-assertion and not * have preempt disabled. Some functions called from here want * preempt to be disabled. No point enabling it later though... */ preempt_disable(); bust_spinlocks(1); va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); bust_spinlocks(0); /* * If we have crashed and we have a crash kernel loaded let it handle * everything else. * Do we want to call this before we try to display a message? */ crash_kexec(NULL); #ifdef CONFIG_SMP /* * Note smp_send_stop is the usual smp shutdown function, which * unfortunately means it may not be hardened to work in a panic * situation. */ smp_send_stop(); #endif atomic_notifier_call_chain(&panic_notifier_list, 0, buf); if (!panic_blink) panic_blink = no_blink; if (panic_timeout > 0) { /* * Delay timeout seconds before rebooting the machine. * We can't use the "normal" timers since we just panicked.. */ printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout); for (i = 0; i < panic_timeout*1000; ) { touch_nmi_watchdog(); i += panic_blink(i); mdelay(1); i++; } /* This will not be a clean reboot, with everything * shutting down. But if there is a chance of * rebooting the system it will be rebooted. */ emergency_restart(); } #ifdef __sparc__ { extern int stop_a_enabled; /* Make sure the user can actually press Stop-A (L1-A) */ stop_a_enabled = 1; printk(KERN_EMERG "Press Stop-A (L1-A) to return to the boot prom\n"); } #endif #if defined(CONFIG_S390) disabled_wait(caller); #endif local_irq_enable(); for (i = 0;;) { touch_softlockup_watchdog(); i += panic_blink(i); mdelay(1); i++; } }
/* * Ok, this is the main fork-routine. * * It copies the process, and if successful kick-starts * it and waits for it to finish using the VM if required. */ long do_fork(unsigned long clone_flags, unsigned long stack_start, struct pt_regs *regs, unsigned long stack_size, int __user *parent_tidptr, int __user *child_tidptr) { struct task_struct *p; int trace = 0; long nr; /* * Do some preliminary argument and permissions checking before we * actually start allocating stuff */ if (clone_flags & CLONE_NEWUSER) { if (clone_flags & CLONE_THREAD) return -EINVAL; /* hopefully this check will go away when userns support is * complete */ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SETUID) || !capable(CAP_SETGID)) return -EPERM; } /* * When called from kernel_thread, don't do user tracing stuff. */ if (likely(user_mode(regs))) trace = tracehook_prepare_clone(clone_flags); p = copy_process(clone_flags, stack_start, regs, stack_size, child_tidptr, NULL, trace); /* * Do this prior waking up the new thread - the thread pointer * might get invalid after that point, if the thread exits quickly. */ if (!IS_ERR(p)) { struct completion vfork; trace_sched_process_fork(current, p); atomic_notifier_call_chain(&task_fork_notifier, 0, p); nr = task_pid_vnr(p); if (clone_flags & CLONE_PARENT_SETTID) put_user(nr, parent_tidptr); if (clone_flags & CLONE_VFORK) { p->vfork_done = &vfork; init_completion(&vfork); } audit_finish_fork(p); tracehook_report_clone(regs, clone_flags, nr, p); /* * We set PF_STARTING at creation in case tracing wants to * use this to distinguish a fully live task from one that * hasn't gotten to tracehook_report_clone() yet. Now we * clear it and set the child going. */ p->flags &= ~PF_STARTING; wake_up_new_task(p); tracehook_report_clone_complete(trace, regs, clone_flags, nr, p); if (clone_flags & CLONE_VFORK) { freezer_do_not_count(); wait_for_completion(&vfork); freezer_count(); tracehook_report_vfork_done(p, nr); } } else { nr = PTR_ERR(p); } return nr; }
static inline void etm_save_state(struct etm_ctx *etmdata) { int i, j, count; i = 0; mb(); isb(); ETM_UNLOCK(etmdata); switch (etmdata->arch) { case ETM_ARCH_V4: etm_os_lock(etmdata); /* poll until programmers' model becomes stable */ for (count = TIMEOUT_US; (BVAL(etm_readl(etmdata, TRCSTATR), 1) != 1) && count > 0; count--) udelay(1); if (count == 0) pr_err_ratelimited("programmers model is not stable\n" ); /* main control and configuration registers */ etmdata->state[i++] = etm_readl(etmdata, TRCPROCSELR); etmdata->state[i++] = etm_readl(etmdata, TRCCONFIGR); etmdata->state[i++] = etm_readl(etmdata, TRCAUXCTLR); etmdata->state[i++] = etm_readl(etmdata, TRCEVENTCTL0R); etmdata->state[i++] = etm_readl(etmdata, TRCEVENTCTL1R); etmdata->state[i++] = etm_readl(etmdata, TRCSTALLCTLR); etmdata->state[i++] = etm_readl(etmdata, TRCTSCTLR); etmdata->state[i++] = etm_readl(etmdata, TRCSYNCPR); etmdata->state[i++] = etm_readl(etmdata, TRCCCCTLR); etmdata->state[i++] = etm_readl(etmdata, TRCBBCTLR); etmdata->state[i++] = etm_readl(etmdata, TRCTRACEIDR); etmdata->state[i++] = etm_readl(etmdata, TRCQCTLR); /* filtering control registers */ etmdata->state[i++] = etm_readl(etmdata, TRCVICTLR); etmdata->state[i++] = etm_readl(etmdata, TRCVIIECTLR); etmdata->state[i++] = etm_readl(etmdata, TRCVISSCTLR); etmdata->state[i++] = etm_readl(etmdata, TRCVIPCSSCTLR); etmdata->state[i++] = etm_readl(etmdata, TRCVDCTLR); etmdata->state[i++] = etm_readl(etmdata, TRCVDSACCTLR); etmdata->state[i++] = etm_readl(etmdata, TRCVDARCCTLR); /* derived resource registers */ for (j = 0; j < etmdata->nr_seq_state-1; j++) etmdata->state[i++] = etm_readl(etmdata, TRCSEQEVRn(j)); etmdata->state[i++] = etm_readl(etmdata, TRCSEQRSTEVR); etmdata->state[i++] = etm_readl(etmdata, TRCSEQSTR); etmdata->state[i++] = etm_readl(etmdata, TRCEXTINSELR); for (j = 0; j < etmdata->nr_cntr; j++) { etmdata->state[i++] = etm_readl(etmdata, TRCCNTRLDVRn(j)); etmdata->state[i++] = etm_readl(etmdata, TRCCNTCTLRn(j)); etmdata->state[i++] = etm_readl(etmdata, TRCCNTVRn(j)); } /* resource selection registers */ for (j = 0; j < etmdata->nr_resource; j++) etmdata->state[i++] = etm_readl(etmdata, TRCRSCTLRn(j)); /* comparator registers */ for (j = 0; j < etmdata->nr_addr_cmp * 2; j++) { etmdata->state[i++] = etm_readq(etmdata, TRCACVRn(j)); etmdata->state[i++] = etm_readq(etmdata, TRCACATRn(j)); } for (j = 0; j < etmdata->nr_data_cmp; j++) { etmdata->state[i++] = etm_readq(etmdata, TRCDVCVRn(j)); etmdata->state[i++] = etm_readq(etmdata, TRCDVCMRn(i)); } for (j = 0; j < etmdata->nr_ctxid_cmp; j++) etmdata->state[i++] = etm_readq(etmdata, TRCCIDCVRn(j)); etmdata->state[i++] = etm_readl(etmdata, TRCCIDCCTLR0); etmdata->state[i++] = etm_readl(etmdata, TRCCIDCCTLR1); for (j = 0; j < etmdata->nr_vmid_cmp; j++) etmdata->state[i++] = etm_readq(etmdata, TRCVMIDCVRn(j)); etmdata->state[i++] = etm_readl(etmdata, TRCVMIDCCTLR0); etmdata->state[i++] = etm_readl(etmdata, TRCVMIDCCTLR1); /* single-shot comparator registers */ for (j = 0; j < etmdata->nr_ss_cmp; j++) { etmdata->state[i++] = etm_readl(etmdata, TRCSSCCRn(j)); etmdata->state[i++] = etm_readl(etmdata, TRCSSCSRn(j)); etmdata->state[i++] = etm_readl(etmdata, TRCSSPCICRn(j)); } /* claim tag registers */ etmdata->state[i++] = etm_readl(etmdata, TRCCLAIMCLR); /* program ctrl register */ etmdata->state[i++] = etm_readl(etmdata, TRCPRGCTLR); /* ensure trace unit is idle to be powered down */ for (count = TIMEOUT_US; (BVAL(etm_readl(etmdata, TRCSTATR), 0) != 1) && count > 0; count--) udelay(1); if (count == 0) pr_err_ratelimited("timeout waiting for idle state\n"); atomic_notifier_call_chain(&etm_save_notifier_list, 0, NULL); break; default: pr_err_ratelimited("unsupported etm arch %d in %s\n", etmdata->arch, __func__); } ETM_LOCK(etmdata); }
NORET_TYPE void panic(const char * fmt, ...) { long i; static char buf[1024]; va_list args; #if defined(CONFIG_S390) unsigned long caller = (unsigned long) __builtin_return_address(0); #endif int count,chr_count; /* * It's possible to come here directly from a panic-assertion and not * have preempt disabled. Some functions called from here want * preempt to be disabled. No point enabling it later though... */ preempt_disable(); bust_spinlocks(1); va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); bust_spinlocks(0); #ifdef CONFIG_KERNEL_PANIC_DUMP PANIC_Current += sprintf(PANIC_Current,"Kernel panic - not syncing: %s\n",buf); if (!multiple_panic) { multiple_panic++; printk(KERN_EMERG "PANIC_DUMP Test : \n"); count = PANIC_Current - PANIC_Base; printk("count : %d\n",count); chr_count = 0; while(count) { memset(buf,0x0,1024); if(count > 1024) { memcpy(buf,PANIC_Base+chr_count,1024); printk("%s",buf); chr_count += 1024; count -= 1024; } else { memcpy(buf,PANIC_Base+chr_count,count); printk("%s",buf); chr_count += count; count -= count; } } { mm_segment_t old_fs; struct file *filp; int writelen; loff_t pos =0; fl_owner_t id = current->files; preempt_enable(); old_fs = get_fs(); set_fs(KERNEL_DS); struct timeval val; struct tm *ptm,ptmTemp; char dt[35]; do_gettimeofday(&val); ptm = localtime_r(&val.tv_sec,&ptmTemp); memset(dt , 0x00 , sizeof(dt)); // format : YYMMDDhhmm sprintf(dt, "/data/KERNEL_PANIC%04d%02d%02d%02d%02d.txt" , ptm->tm_year+1900 , ptm->tm_mon+1 , ptm->tm_mday , ptm->tm_hour, ptm->tm_min); printk("Panic log file is %s \n",dt); count = PANIC_Current - PANIC_Base; chr_count = 0; filp = filp_open(dt,O_CREAT|O_WRONLY,0666); if(filp<0) printk("Sorry. Can't creat panic file\n"); else { // vfs_write(filp, PANIC_Base, strlen(PANIC_Base), while(count) { memset(buf,0x0,1024); if(count > 1024) { memcpy(buf,PANIC_Base+chr_count,1024); writelen = filp->f_op->write(filp,buf,1024,&filp->f_pos); if(writelen == 0) printk("Write Error!!\n"); else filp->f_op->flush(filp,id); chr_count += 1024; count -= 1024; } else { memcpy(buf,PANIC_Base+chr_count,count); writelen = filp->f_op->write(filp,buf,count,&filp->f_pos); if(writelen == 0) printk("Write Error\n"); else filp->f_op->flush(filp,id); chr_count += count; count -= count; } } } set_fs(old_fs); preempt_disable(); } count = PANIC_Current - PANIC_Base; printk("\nPanic Dump END, panic message size is : %d\n",count); } else { #if 0 /* Reset Target */ #else while (1); #endif } #endif /* * If we have crashed and we have a crash kernel loaded let it handle * everything else. * Do we want to call this before we try to display a message? */ crash_kexec(NULL); #ifdef CONFIG_SMP /* * Note smp_send_stop is the usual smp shutdown function, which * unfortunately means it may not be hardened to work in a panic * situation. */ smp_send_stop(); #endif atomic_notifier_call_chain(&panic_notifier_list, 0, buf); if (!panic_blink) panic_blink = no_blink; if (panic_timeout > 0) { /* * Delay timeout seconds before rebooting the machine. * We can't use the "normal" timers since we just panicked.. */ printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout); for (i = 0; i < panic_timeout*1000; ) { touch_nmi_watchdog(); i += panic_blink(i); mdelay(1); i++; } /* This will not be a clean reboot, with everything * shutting down. But if there is a chance of * rebooting the system it will be rebooted. */ emergency_restart(); } #ifdef __sparc__ { extern int stop_a_enabled; /* Make sure the user can actually press Stop-A (L1-A) */ stop_a_enabled = 1; printk(KERN_EMERG "Press Stop-A (L1-A) to return to the boot prom\n"); } #endif #if defined(CONFIG_S390) disabled_wait(caller); #endif local_irq_enable(); for (i = 0;;) { touch_softlockup_watchdog(); i += panic_blink(i); mdelay(1); i++; } }
int LGE_ErrorHandler_Main( int crash_side, char * message) { ram_console_setpanic(); if (hidden_reset_enable) { if (crash_side == MODEM_CRASH) { unsigned *temp; printk(KERN_INFO"%s: arm9 has crashed...\n",__func__); printk(KERN_INFO"%s\n", message); atomic_notifier_call_chain(&panic_notifier_list, 0, "arm9 has crashed...\n"); temp = lge_get_fb_copy_virt_addr(); *temp = 0x12345678; printk(KERN_INFO"%s: hidden magic %x\n",__func__, temp[0]); return SMSM_SYSTEM_REBOOT; } return 0; } if(BLUE_ERROR_HANDLER_LEVEL != 0) { if (get_suspend_state() != PM_SUSPEND_ON) { lcd_suspend = 0; } switch(crash_side) { case MODEM_CRASH: case APPL_CRASH: case ANDROID_CRASH: if(!LG_ErrorHandler_enable) { LG_ErrorHandler_enable = 1; raw_local_irq_enable(); if (message != NULL) display_info_LCD(crash_side, message); } break; case ANDROID_DISPLAY_INFO : if (message != NULL) display_info_LCD(crash_side, message); return 0; default : break; } } raw_local_irq_disable(); preempt_disable(); smsm_reset_modem(SMSM_APPS_SHUTDOWN); if(BLUE_ERROR_HANDLER_LEVEL == 0) { mdelay(100); return SMSM_SYSTEM_REBOOT; } while(1) { gpio_set_value(36,0); gpio_set_value(32,1); gpio_set_value(33,1); if(gpio_get_value(38)==0) { printk("Pressed Volume up key\n"); return SMSM_SYSTEM_DOWNLOAD; } else if(gpio_get_value(37) ==0 ) { printk("Pressed Volume down key\n"); return SMSM_SYSTEM_REBOOT; } mdelay(200); ; } }
/* * Ok, this is the main fork-routine. * * It copies the process, and if successful kick-starts * it and waits for it to finish using the VM if required. */ long do_fork(unsigned long clone_flags, unsigned long stack_start, struct pt_regs *regs, unsigned long stack_size, int __user *parent_tidptr, int __user *child_tidptr) { struct task_struct *p; int trace = 0; long nr; /* * Do some preliminary argument and permissions checking before we * actually start allocating stuff */ if (clone_flags & CLONE_NEWUSER) { if (clone_flags & CLONE_THREAD) return -EINVAL; /* hopefully this check will go away when userns support is * complete */ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SETUID) || !capable(CAP_SETGID)) return -EPERM; } /* * Determine whether and which event to report to ptracer. When * called from kernel_thread or CLONE_UNTRACED is explicitly * requested, no event is reported; otherwise, report if the event * for the type of forking is enabled. */ if (likely(user_mode(regs)) && !(clone_flags & CLONE_UNTRACED)) { if (clone_flags & CLONE_VFORK) trace = PTRACE_EVENT_VFORK; else if ((clone_flags & CSIGNAL) != SIGCHLD) trace = PTRACE_EVENT_CLONE; else trace = PTRACE_EVENT_FORK; if (likely(!ptrace_event_enabled(current, trace))) trace = 0; } p = copy_process(clone_flags, stack_start, regs, stack_size, child_tidptr, NULL, trace); /* * Do this prior waking up the new thread - the thread pointer * might get invalid after that point, if the thread exits quickly. */ if (!IS_ERR(p)) { struct completion vfork; trace_sched_process_fork(current, p); atomic_notifier_call_chain(&task_fork_notifier, 0, p); nr = task_pid_vnr(p); if (clone_flags & CLONE_PARENT_SETTID) put_user(nr, parent_tidptr); if (clone_flags & CLONE_VFORK) { p->vfork_done = &vfork; init_completion(&vfork); } audit_finish_fork(p); /* * We set PF_STARTING at creation in case tracing wants to * use this to distinguish a fully live task from one that * hasn't finished SIGSTOP raising yet. Now we clear it * and set the child going. */ p->flags &= ~PF_STARTING; wake_up_new_task(p); /* forking complete and child started to run, tell ptracer */ if (unlikely(trace)) ptrace_event(trace, nr); if (clone_flags & CLONE_VFORK) { freezer_do_not_count(); wait_for_completion(&vfork); freezer_count(); ptrace_event(PTRACE_EVENT_VFORK_DONE, nr); } } else { nr = PTR_ERR(p); } return nr; }
static irqreturn_t twl6030_usb_irq(int irq, void *_twl) { struct twl6030_usb *twl = _twl; int status; u8 vbus_state, hw_state, misc2_data; unsigned charger_type; hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); vbus_state = twl6030_readb(twl, TWL_MODULE_MAIN_CHARGE, CONTROLLER_STAT1); vbus_state = vbus_state & VBUS_DET; /* Ignore charger events other than VBUS */ if (vbus_state == twl->prev_vbus) return IRQ_HANDLED; if ((vbus_state) && !(hw_state & STS_USB_ID)) { /* Program MISC2 register and set bit VUSB_IN_VBAT */ misc2_data = twl6030_readb(twl, TWL6030_MODULE_ID0, TWL6030_MISC2); misc2_data |= 0x10; twl6030_writeb(twl, TWL6030_MODULE_ID0, misc2_data, TWL6030_MISC2); regulator_enable(twl->usb3v3); twl6030_phy_suspend(&twl->otg, 0); if(0 == get_msc_connect_flag()) charger_type = POWER_SUPPLY_TYPE_USB_DCP; else charger_type = POWER_SUPPLY_TYPE_USB; twl6030_phy_suspend(&twl->otg, 1); if ((charger_type == POWER_SUPPLY_TYPE_USB_CDP) || (charger_type == POWER_SUPPLY_TYPE_USB)) { status = USB_EVENT_VBUS; twl->otg.default_a = false; twl->asleep = 1; twl->otg.state = OTG_STATE_B_IDLE; twl->linkstat = status; twl->otg.last_event = status; } else if (charger_type == POWER_SUPPLY_TYPE_USB_DCP) { regulator_disable(twl->usb3v3); status = USB_EVENT_CHARGER; twl->usb_cinlimit_mA = 1800; twl->otg.state = OTG_STATE_B_IDLE; twl->linkstat = status; twl->otg.last_event = status; } else { regulator_disable(twl->usb3v3); goto vbus_notify; } atomic_notifier_call_chain(&twl->otg.notifier, status, &charger_type); } if (!vbus_state) { status = USB_EVENT_NONE; twl->linkstat = status; twl->otg.last_event = status; atomic_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); if (twl->asleep) { regulator_disable(twl->usb3v3); twl->asleep = 0; /* Program MISC2 register and clear bit VUSB_IN_VBAT */ misc2_data = twl6030_readb(twl, TWL6030_MODULE_ID0, TWL6030_MISC2); misc2_data &= 0xEF; twl6030_writeb(twl, TWL6030_MODULE_ID0, misc2_data, TWL6030_MISC2); } } vbus_notify: sysfs_notify(&twl->dev->kobj, NULL, "vbus"); twl->prev_vbus = vbus_state; return IRQ_HANDLED; }
static int dwc3_intel_set_power(struct usb_phy *_otg, unsigned ma) { unsigned long flags; struct dwc_otg2 *otg = dwc3_get_otg(); struct power_supply_cable_props cap; struct intel_dwc_otg_pdata *data; data = (struct intel_dwc_otg_pdata *)otg->otg_data; /* On ANN, due the VBUS haven't connect to internal USB PHY. So * controller can't get disconnect interrupt which depend on vbus drop * detection. * So controller will receive early suspend and suspend interrupt. But * we can detect vbus status to determine current scenario is real * suspend or vbus drop. */ if (data->detect_vbus_drop && ma == OTG_DEVICE_SUSPEND) { if (!check_vbus_status(otg)) { cap.chrg_type = otg->charging_cap.chrg_type; cap.ma = otg->charging_cap.ma; cap.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_DISCONNECT; atomic_notifier_call_chain(&otg->usb2_phy.notifier, USB_EVENT_CHARGER, &cap); return 0; } } if (otg->charging_cap.chrg_type == POWER_SUPPLY_CHARGER_TYPE_USB_CDP) return 0; else if (otg->charging_cap.chrg_type != POWER_SUPPLY_CHARGER_TYPE_USB_SDP) { otg_err(otg, "%s: currently, chrg type is not SDP!\n", __func__); return -EINVAL; } if (ma == OTG_DEVICE_SUSPEND) { spin_lock_irqsave(&otg->lock, flags); cap.chrg_type = otg->charging_cap.chrg_type; cap.ma = otg->charging_cap.ma; cap.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_SUSPEND; spin_unlock_irqrestore(&otg->lock, flags); /* mA is zero mean D+/D- opened cable. * If SMIP set, then notify 500mA. * Otherwise, notify 0mA. */ if (!cap.ma) { if (data->charging_compliance) { cap.ma = 500; cap.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_CONNECT; } /* For standard SDP, if SMIP set, then ignore suspend */ } else if (data->charging_compliance) return 0; /* Stander SDP(cap.mA != 0) and SMIP not set. * Should send 0mA with SUSPEND event */ else cap.ma = 0; atomic_notifier_call_chain(&otg->usb2_phy.notifier, USB_EVENT_CHARGER, &cap); otg_dbg(otg, "Notify EM"); otg_dbg(otg, "POWER_SUPPLY_CHARGER_EVENT_SUSPEND\n"); return 0; } else if (ma == OTG_DEVICE_RESUME) { otg_dbg(otg, "Notify EM"); otg_dbg(otg, "POWER_SUPPLY_CHARGER_EVENT_CONNECT\n"); dwc3_intel_notify_charger_type(otg, POWER_SUPPLY_CHARGER_EVENT_CONNECT); return 0; } /* For SMIP set case, only need to report 500/900mA */ if (data->charging_compliance) { if ((ma != OTG_USB2_500MA) && (ma != OTG_USB3_900MA)) return 0; } /* Covert macro to integer number*/ switch (ma) { case OTG_USB2_0MA: ma = 0; break; case OTG_USB2_100MA: ma = 100; break; case OTG_USB3_150MA: ma = 150; break; case OTG_USB2_500MA: ma = 500; break; case OTG_USB3_900MA: ma = 900; break; default: otg_err(otg, "Device driver set invalid SDP current value!\n"); return -EINVAL; } spin_lock_irqsave(&otg->lock, flags); otg->charging_cap.ma = ma; spin_unlock_irqrestore(&otg->lock, flags); dwc3_intel_notify_charger_type(otg, POWER_SUPPLY_CHARGER_EVENT_CONNECT); return 0; }
static void exit_idle(void) { atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); }
static void enter_idle(void) { atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL); }
/** * Detects USBID presence status and notifies USB driver * * @pdata Pointer to the charger type detection driver data structure * @gnd Indicating whether USBID is grounded (true) or floating (false) * @validation Perform validation between interurpt and ID result * return 0 on success, otherwise error code */ static int pmic_usb_id_det(struct pmic_usb_det_data *pdata, bool gnd, bool validation) { u8 reg, id; int ret; struct power_supply_cable_props *pcp; enum usb_phy_events event; bool during_boot = false; if (!pdata || !pdata->pdev) return -EINVAL; if (pdata->usbid_state == -1) during_boot = true; pcp = &pdata->cable_props; ret = pmic_reg_read(DEV1, SPWRSRC, ®); if (ret) { dev_err(pdata->pdev, "%s - fail to read DEV1 SPWRSRC\n", __func__); return ret; } id = get_field(reg, SUSBIDDET_O, SUSBIDDET_W); if (validation && ((gnd && (id > ID_GND)) || (!gnd && (id < ID_FLT)))) { dev_err(pdata->pdev, "%s - USBID detection error (gnd=%d, id=%d)\n", __func__, gnd, id); return -EIO; } switch (id) { case ID_ACA: if (pdata->cable_type == POWER_SUPPLY_CHARGER_TYPE_USB_ACA) { dev_info(pdata->pdev, "ACA charger already reported by CTYP\n"); return 0; } dev_info(pdata->pdev, "ACA charger detected\n"); event = USB_EVENT_ID; pdata->cable_type = POWER_SUPPLY_CHARGER_TYPE_USB_ACA; pcp->chrg_type = POWER_SUPPLY_CHARGER_TYPE_USB_ACA; pcp->chrg_evt = POWER_SUPPLY_CHARGER_EVENT_CONNECT; break; case ID_GND: dev_info(pdata->pdev, "USBID grounded\n"); event = USB_EVENT_ID; pdata->cable_type = POWER_SUPPLY_CHARGER_TYPE_NONE; pcp->chrg_type = POWER_SUPPLY_CHARGER_TYPE_NONE; pcp->chrg_evt = POWER_SUPPLY_CHARGER_EVENT_CONNECT; break; case ID_FLT: dev_info(pdata->pdev, "USBID floating\n"); event = USB_EVENT_NONE; pcp->chrg_type = pdata->cable_type; pcp->chrg_evt = POWER_SUPPLY_CHARGER_EVENT_DISCONNECT; pdata->cable_type = POWER_SUPPLY_CHARGER_TYPE_NONE; break; default: dev_err(pdata->pdev, "%s - USBID detection error (gnd=%d, id=%d)\n", __func__, gnd, id); return -EIO; break; } pdata->usbid_state = id; pcp->ma = 0; /* Notify PSY/USB if not during boot or VBUS is not detected */ if (!during_boot || pdata->vbus_state == VBUS_OFF) atomic_notifier_call_chain(&pdata->otg_handle->notifier, event, pcp); return 0; }
static void irq_work(struct work_struct *work) { struct tegra_otg_data *tegra = container_of(work, struct tegra_otg_data, work); struct otg_transceiver *otg = &tegra->otg; enum usb_otg_state from = otg->state; enum usb_otg_state to = OTG_STATE_UNDEFINED; unsigned long flags; unsigned long status; spin_lock_irqsave(&tegra->lock, flags); status = tegra->int_status; /* ++ ZTE: cuijian@20120703 */ if( (status & USB_VBUS_STATUS) || !(status & USB_ID_STATUS)){ if (!tegra->otg_wake_locked){ printk(KERN_INFO "%s(%d) tegra_otg USB_EVENT_VBUS\n", __func__, __LINE__); tegra->otg.last_event = USB_EVENT_VBUS; atomic_notifier_call_chain(&tegra->otg.notifier, tegra->otg.last_event, NULL); tegra->otg_wake_locked = 1; } } else { if (tegra->otg_wake_locked){ printk(KERN_INFO "%s(%d) tegra_otg USB_EVENT_NONE\n", __func__, __LINE__); tegra->otg.last_event = USB_EVENT_NONE; atomic_notifier_call_chain(&tegra->otg.notifier, tegra->otg.last_event, NULL); tegra->otg_wake_locked = 0; } } /* -- ZTE: cuijian@20120703 */ /* Debug prints */ DBG("%s(%d) status = 0x%x\n", __func__, __LINE__, status); if ((status & USB_ID_INT_STATUS) && (status & USB_VBUS_INT_STATUS)){ DBG("%s(%d) got vbus & id interrupt\n", __func__, __LINE__); if ((!(status & USB_ID_STATUS)) && (status & USB_VBUS_STATUS)){ DBG("%s(%d) MHL with ext power\n", __func__, __LINE__); spin_unlock_irqrestore(&tegra->lock, flags); return; } } else { if (status & USB_ID_INT_STATUS) DBG("%s(%d) got id interrupt\n", __func__, __LINE__); if (status & USB_VBUS_INT_STATUS) DBG("%s(%d) got vbus interrupt\n", __func__, __LINE__); } if (!(status & USB_ID_STATUS)) to = OTG_STATE_A_HOST; else if (status & USB_VBUS_STATUS && from != OTG_STATE_A_HOST) to = OTG_STATE_B_PERIPHERAL; else to = OTG_STATE_A_SUSPEND; spin_unlock_irqrestore(&tegra->lock, flags); tegra_change_otg_state(tegra, to); }
int profile_handoff_task(struct task_struct * task) { int ret; ret = atomic_notifier_call_chain(&task_free_notifier, 0, task); return (ret == NOTIFY_OK) ? 1 : 0; }
static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) { static bool notify_otg, notify_charger; static unsigned int cable; int ret, stat, cfg, pwr_stat; u8 chrg_type; bool vbus_attach = false; ret = regmap_read(info->regmap, AXP288_PS_STAT_REG, &pwr_stat); if (ret < 0) { dev_err(info->dev, "failed to read vbus status\n"); return ret; } vbus_attach = (pwr_stat & PS_STAT_VBUS_PRESENT); if (!vbus_attach) goto notify_otg; /* Check charger detection completion status */ ret = regmap_read(info->regmap, AXP288_BC_GLOBAL_REG, &cfg); if (ret < 0) goto dev_det_ret; if (cfg & BC_GLOBAL_DET_STAT) { dev_dbg(info->dev, "can't complete the charger detection\n"); goto dev_det_ret; } ret = regmap_read(info->regmap, AXP288_BC_DET_STAT_REG, &stat); if (ret < 0) goto dev_det_ret; chrg_type = (stat & DET_STAT_MASK) >> DET_STAT_SHIFT; switch (chrg_type) { case DET_STAT_SDP: dev_dbg(info->dev, "sdp cable is connecetd\n"); notify_otg = true; notify_charger = true; cable = EXTCON_CHG_USB_SDP; break; case DET_STAT_CDP: dev_dbg(info->dev, "cdp cable is connecetd\n"); notify_otg = true; notify_charger = true; cable = EXTCON_CHG_USB_CDP; break; case DET_STAT_DCP: dev_dbg(info->dev, "dcp cable is connecetd\n"); notify_charger = true; cable = EXTCON_CHG_USB_DCP; break; default: dev_warn(info->dev, "disconnect or unknown or ID event\n"); } notify_otg: if (notify_otg) { /* * If VBUS is absent Connect D+/D- lines to PMIC for BC * detection. Else connect them to SOC for USB communication. */ if (info->pdata->gpio_mux_cntl) gpiod_set_value(info->pdata->gpio_mux_cntl, vbus_attach ? EXTCON_GPIO_MUX_SEL_SOC : EXTCON_GPIO_MUX_SEL_PMIC); atomic_notifier_call_chain(&info->otg->notifier, vbus_attach ? USB_EVENT_VBUS : USB_EVENT_NONE, NULL); } if (notify_charger) extcon_set_cable_state_(info->edev, cable, vbus_attach); /* Clear the flags on disconnect event */ if (!vbus_attach) notify_otg = notify_charger = false; return 0; dev_det_ret: if (ret < 0) dev_err(info->dev, "failed to detect BC Mod\n"); return ret; }
static void notify_switch_state(int state) { atomic_notifier_call_chain(&p_switch_usb_info->charger_type_notifier_head, state, NULL); pr_info("[%s]Notify usb switch state: %d\n", __func__, state); }
static inline void etm_restore_state(struct etm_ctx *etmdata) { int i, j; i = 0; ETM_UNLOCK(etmdata); switch (etmdata->arch) { case ETM_ARCH_V4: atomic_notifier_call_chain(&etm_restore_notifier_list, 0, NULL); /* check OS lock is locked */ if (BVAL(etm_readl(etmdata, TRCOSLSR), 1) != 1) { pr_err_ratelimited("OS lock is unlocked\n"); etm_os_lock(etmdata); } /* main control and configuration registers */ etm_writel(etmdata, etmdata->state[i++], TRCPROCSELR); etm_writel(etmdata, etmdata->state[i++], TRCCONFIGR); etm_writel(etmdata, etmdata->state[i++], TRCAUXCTLR); etm_writel(etmdata, etmdata->state[i++], TRCEVENTCTL0R); etm_writel(etmdata, etmdata->state[i++], TRCEVENTCTL1R); etm_writel(etmdata, etmdata->state[i++], TRCSTALLCTLR); etm_writel(etmdata, etmdata->state[i++], TRCTSCTLR); etm_writel(etmdata, etmdata->state[i++], TRCSYNCPR); etm_writel(etmdata, etmdata->state[i++], TRCCCCTLR); etm_writel(etmdata, etmdata->state[i++], TRCBBCTLR); etm_writel(etmdata, etmdata->state[i++], TRCTRACEIDR); etm_writel(etmdata, etmdata->state[i++], TRCQCTLR); /* filtering control registers */ etm_writel(etmdata, etmdata->state[i++], TRCVICTLR); etm_writel(etmdata, etmdata->state[i++], TRCVIIECTLR); etm_writel(etmdata, etmdata->state[i++], TRCVISSCTLR); etm_writel(etmdata, etmdata->state[i++], TRCVIPCSSCTLR); etm_writel(etmdata, etmdata->state[i++], TRCVDCTLR); etm_writel(etmdata, etmdata->state[i++], TRCVDSACCTLR); etm_writel(etmdata, etmdata->state[i++], TRCVDARCCTLR); /* derived resources registers */ for (j = 0; j < etmdata->nr_seq_state-1; j++) etm_writel(etmdata, etmdata->state[i++], TRCSEQEVRn(j)); etm_writel(etmdata, etmdata->state[i++], TRCSEQRSTEVR); etm_writel(etmdata, etmdata->state[i++], TRCSEQSTR); etm_writel(etmdata, etmdata->state[i++], TRCEXTINSELR); for (j = 0; j < etmdata->nr_cntr; j++) { etm_writel(etmdata, etmdata->state[i++], TRCCNTRLDVRn(j)); etm_writel(etmdata, etmdata->state[i++], TRCCNTCTLRn(j)); etm_writel(etmdata, etmdata->state[i++], TRCCNTVRn(j)); } /* resource selection registers */ for (j = 0; j < etmdata->nr_resource; j++) etm_writel(etmdata, etmdata->state[i++], TRCRSCTLRn(j)); /* comparator registers */ for (j = 0; j < etmdata->nr_addr_cmp * 2; j++) { etm_writeq(etmdata, etmdata->state[i++], TRCACVRn(j)); etm_writeq(etmdata, etmdata->state[i++], TRCACATRn(j)); } for (j = 0; j < etmdata->nr_data_cmp; j++) { etm_writeq(etmdata, etmdata->state[i++], TRCDVCVRn(j)); etm_writeq(etmdata, etmdata->state[i++], TRCDVCMRn(j)); } for (j = 0; j < etmdata->nr_ctxid_cmp; j++) etm_writeq(etmdata, etmdata->state[i++], TRCCIDCVRn(j)); etm_writel(etmdata, etmdata->state[i++], TRCCIDCCTLR0); etm_writel(etmdata, etmdata->state[i++], TRCCIDCCTLR1); for (j = 0; j < etmdata->nr_vmid_cmp; j++) etm_writeq(etmdata, etmdata->state[i++], TRCVMIDCVRn(j)); etm_writel(etmdata, etmdata->state[i++], TRCVMIDCCTLR0); etm_writel(etmdata, etmdata->state[i++], TRCVMIDCCTLR1); /* e-shot comparator registers */ for (j = 0; j < etmdata->nr_ss_cmp; j++) { etm_writel(etmdata, etmdata->state[i++], TRCSSCCRn(j)); etm_writel(etmdata, etmdata->state[i++], TRCSSCSRn(j)); etm_writel(etmdata, etmdata->state[i++], TRCSSPCICRn(j)); } /* claim tag registers */ etm_writel(etmdata, etmdata->state[i++], TRCCLAIMSET); /* program ctrl register */ etm_writel(etmdata, etmdata->state[i++], TRCPRGCTLR); etm_os_unlock(etmdata); break; default: pr_err_ratelimited("unsupported etm arch %d in %s\n", etmdata->arch, __func__); } ETM_LOCK(etmdata); }
void enter_idle(void) { this_cpu_write(is_idle, 1); atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL); }
void kgsl_cp_intrcallback(struct kgsl_device *device) { unsigned int status = 0, num_reads = 0, master_status = 0; struct kgsl_yamato_device *yamato_device = (struct kgsl_yamato_device *) device; struct kgsl_ringbuffer *rb = &device->ringbuffer; KGSL_CMD_VDBG("enter (device=%p)\n", device); kgsl_yamato_regread(device, REG_MASTER_INT_SIGNAL, &master_status); while (!status && (num_reads < VALID_STATUS_COUNT_MAX) && (master_status & MASTER_INT_SIGNAL__CP_INT_STAT)) { kgsl_yamato_regread(device, REG_CP_INT_STATUS, &status); kgsl_yamato_regread(device, REG_MASTER_INT_SIGNAL, &master_status); num_reads++; } if (num_reads > 1) KGSL_DRV_WARN("Looped %d times to read REG_CP_INT_STATUS\n", num_reads); if (!status) { if (master_status & MASTER_INT_SIGNAL__CP_INT_STAT) { KGSL_DRV_WARN("Unable to read CP_INT_STATUS\n"); wake_up_interruptible_all(&yamato_device->ib1_wq); } else KGSL_DRV_WARN("Spurious interrput detected\n"); return; } if (status & CP_INT_CNTL__RB_INT_MASK) { unsigned int enableflag = 0; kgsl_sharedmem_writel(&rb->device->memstore, KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable), enableflag); wmb(); KGSL_CMD_WARN("ringbuffer rb interrupt\n"); } if (status & CP_INT_CNTL__T0_PACKET_IN_IB_MASK) { KGSL_CMD_FATAL("ringbuffer TO packet in IB interrupt\n"); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); kgsl_ringbuffer_dump(rb); } if (status & CP_INT_CNTL__OPCODE_ERROR_MASK) { KGSL_CMD_FATAL("ringbuffer opcode error interrupt\n"); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); kgsl_ringbuffer_dump(rb); } if (status & CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK) { KGSL_CMD_FATAL("ringbuffer protected mode error interrupt\n"); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); kgsl_ringbuffer_dump(rb); } if (status & CP_INT_CNTL__RESERVED_BIT_ERROR_MASK) { KGSL_CMD_FATAL("ringbuffer reserved bit error interrupt\n"); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); kgsl_ringbuffer_dump(rb); } if (status & CP_INT_CNTL__IB_ERROR_MASK) { KGSL_CMD_FATAL("ringbuffer IB error interrupt\n"); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); kgsl_ringbuffer_dump(rb); } if (status & CP_INT_CNTL__SW_INT_MASK) KGSL_CMD_DBG("ringbuffer software interrupt\n"); if (status & CP_INT_CNTL__IB2_INT_MASK) KGSL_CMD_DBG("ringbuffer ib2 interrupt\n"); if (status & (~GSL_CP_INT_MASK)) KGSL_CMD_DBG("bad bits in REG_CP_INT_STATUS %08x\n", status); status &= GSL_CP_INT_MASK; kgsl_yamato_regwrite(device, REG_CP_INT_ACK, status); if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) { KGSL_CMD_WARN("ringbuffer ib1/rb interrupt\n"); wake_up_interruptible_all(&yamato_device->ib1_wq); atomic_notifier_call_chain(&(device->ts_notifier_list), KGSL_DEVICE_YAMATO, NULL); } KGSL_CMD_VDBG("return\n"); }
static void __exit_idle(void) { if (x86_test_and_clear_bit_percpu(0, is_idle) == 0) return; atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); }
int memory_isolate_notify(unsigned long val, void *v) { return atomic_notifier_call_chain(&memory_isolate_chain, val, v); }
static void mm_fmwk_job_scheduler(struct work_struct *work) { mm_job_status_e status = MM_JOB_STATUS_INVALID; bool is_hw_busy = false; struct mm_core *core_dev = container_of(work, \ struct mm_core, \ job_scheduler); MM_CORE_HW_IFC *hw_ifc = &core_dev->mm_device; if (plist_head_empty(&core_dev->job_list)) { return; } struct dev_job_list *job_list_elem = plist_first_entry(\ &(core_dev->job_list), \ struct dev_job_list, core_list); if (mm_core_enable_clock(core_dev)) goto mm_fmwk_job_scheduler_done; is_hw_busy = hw_ifc->mm_get_status(hw_ifc->mm_device_id); if (!is_hw_busy) { if (job_list_elem->job.size) { status = hw_ifc->mm_start_job(\ hw_ifc->mm_device_id, \ &job_list_elem->job, 0); if (status < MM_JOB_STATUS_SUCCESS) { getnstimeofday(&core_dev->sched_time); timespec_add_ns(\ &core_dev->sched_time, \ hw_ifc->mm_timeout * NSEC_PER_MSEC); core_dev->mm_core_idle = false; is_hw_busy = true; pr_debug("job posted "); atomic_notifier_call_chain(\ &core_dev->mm_common->notifier_head, \ MM_FMWK_NOTIFY_JOB_STARTED, NULL); } else { core_dev->mm_core_idle = true; job_list_elem->job.status \ = MM_JOB_STATUS_SUCCESS; mm_common_job_completion(\ job_list_elem, core_dev); SCHEDULER_WORK(core_dev, \ &core_dev->job_scheduler); } } else { job_list_elem->job.status \ = MM_JOB_STATUS_SUCCESS; mm_common_job_completion(\ job_list_elem, core_dev); SCHEDULER_WORK(core_dev, \ &core_dev->job_scheduler); } } else { struct timespec cur_time; getnstimeofday(&cur_time); if (timespec_compare(&cur_time, &core_dev->sched_time) > 0) { pr_err("abort hw "); hw_ifc->mm_abort(hw_ifc->mm_device_id, \ &job_list_elem->job); core_dev->mm_core_idle = true; is_hw_busy = false; SCHEDULER_WORK(core_dev, &core_dev->job_scheduler); } } if (is_hw_busy) { mod_timer(&core_dev->dev_timer, \ jiffies + msecs_to_jiffies(hw_ifc->mm_timer)); pr_debug("mod_timer %lx %lx", \ jiffies, \ msecs_to_jiffies(hw_ifc->mm_timer)); return; } mm_fmwk_job_scheduler_done: mm_core_disable_clock(core_dev); }
/* functions */ void kgsl_cp_intrcallback(struct kgsl_device *device) { unsigned int status = 0, num_reads = 0, master_status = 0; struct kgsl_yamato_device *yamato_device = KGSL_YAMATO_DEVICE(device); struct kgsl_ringbuffer *rb = &yamato_device->ringbuffer; KGSL_CMD_VDBG("enter (device=%p)\n", device); kgsl_yamato_regread(device, REG_MASTER_INT_SIGNAL, &master_status); while (!status && (num_reads < VALID_STATUS_COUNT_MAX) && (master_status & MASTER_INT_SIGNAL__CP_INT_STAT)) { kgsl_yamato_regread(device, REG_CP_INT_STATUS, &status); kgsl_yamato_regread(device, REG_MASTER_INT_SIGNAL, &master_status); num_reads++; } if (num_reads > 1) KGSL_DRV_WARN("Looped %d times to read REG_CP_INT_STATUS\n", num_reads); if (!status) { if (master_status & MASTER_INT_SIGNAL__CP_INT_STAT) { /* This indicates that we could not read CP_INT_STAT. * As a precaution just wake up processes so * they can check their timestamps. Since, we * did not ack any interrupts this interrupt will * be generated again */ KGSL_DRV_WARN("Unable to read CP_INT_STATUS\n"); wake_up_interruptible_all(&yamato_device->ib1_wq); } else KGSL_DRV_WARN("Spurious interrput detected\n"); return; } if (status & CP_INT_CNTL__RB_INT_MASK) { /* signal intr completion event */ unsigned int enableflag = 0; kgsl_sharedmem_writel(&rb->device->memstore, KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable), enableflag); wmb(); KGSL_CMD_WARN("ringbuffer rb interrupt\n"); } if (status & CP_INT_CNTL__T0_PACKET_IN_IB_MASK) { KGSL_CMD_FATAL("ringbuffer TO packet in IB interrupt\n"); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); } if (status & CP_INT_CNTL__OPCODE_ERROR_MASK) { KGSL_CMD_FATAL("ringbuffer opcode error interrupt\n"); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); } if (status & CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK) { KGSL_CMD_FATAL("ringbuffer protected mode error interrupt\n"); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); } if (status & CP_INT_CNTL__RESERVED_BIT_ERROR_MASK) { KGSL_CMD_FATAL("ringbuffer reserved bit error interrupt\n"); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); } if (status & CP_INT_CNTL__IB_ERROR_MASK) { KGSL_CMD_FATAL("ringbuffer IB error interrupt\n"); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); } if (status & CP_INT_CNTL__SW_INT_MASK) KGSL_CMD_DBG("ringbuffer software interrupt\n"); if (status & CP_INT_CNTL__IB2_INT_MASK) KGSL_CMD_DBG("ringbuffer ib2 interrupt\n"); if (status & (~GSL_CP_INT_MASK)) KGSL_CMD_DBG("bad bits in REG_CP_INT_STATUS %08x\n", status); /* only ack bits we understand */ status &= GSL_CP_INT_MASK; kgsl_yamato_regwrite(device, REG_CP_INT_ACK, status); if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) { KGSL_CMD_WARN("ringbuffer ib1/rb interrupt\n"); wake_up_interruptible_all(&yamato_device->ib1_wq); atomic_notifier_call_chain(&(device->ts_notifier_list), KGSL_DEVICE_YAMATO, NULL); } KGSL_CMD_VDBG("return\n"); }
int call_netevent_notifiers(unsigned long val, void *v) { return atomic_notifier_call_chain(&netevent_notif_chain, val, v); }
static int dwc3_intel_byt_set_power(struct usb_phy *_otg, unsigned ma) { unsigned long flags; struct dwc_otg2 *otg = dwc3_get_otg(); struct power_supply_cable_props cap; struct intel_dwc_otg_pdata *data; data = (struct intel_dwc_otg_pdata *)otg->otg_data; if (!data) return -EINVAL; if (ma == OTG_USB2_100MA || ma == OTG_USB3_150MA || ma == OTG_USB2_500MA || ma == OTG_USB3_900MA || ma == OTG_DEVICE_RESUME) { otg_dbg(otg, "cancel discon work\n"); __cancel_delayed_work(&data->suspend_discon_work); } else if (ma == OTG_DEVICE_SUSPEND) { otg_dbg(otg, "schedule discon work\n"); schedule_delayed_work(&data->suspend_discon_work, SUSPEND_DISCONNECT_TIMEOUT); } /* Needn't notify charger capability if charger_detection disable */ if (!charger_detect_enable(otg) && !sdp_charging(otg)) return 0; if (ma == OTG_DEVICE_SUSPEND) { spin_lock_irqsave(&otg->lock, flags); cap.chrg_type = otg->charging_cap.chrg_type; cap.ma = otg->charging_cap.ma; cap.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_SUSPEND; spin_unlock_irqrestore(&otg->lock, flags); /* ma is zero mean D+/D- opened cable. * If SMIP set, then notify 500ma. * Otherwise, notify 0ma. */ if (!cap.ma) { if (data->charging_compliance) { cap.ma = 500; cap.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_CONNECT; } /* For standard SDP, if SMIP set, then ignore suspend */ } else if (data->charging_compliance) return 0; /* Stander SDP(cap.ma != 0) and SMIP not set. * Should send 0ma with SUSPEND event */ else cap.ma = 2; if (sdp_charging(otg)) atomic_notifier_call_chain(&otg->usb2_phy.notifier, USB_EVENT_ENUMERATED, &cap.ma); else atomic_notifier_call_chain(&otg->usb2_phy.notifier, USB_EVENT_CHARGER, &cap); otg_dbg(otg, "Notify EM CHARGER_EVENT_SUSPEND\n"); return 0; } else if (ma == OTG_DEVICE_RESUME) { otg_dbg(otg, "Notify EM CHARGER_EVENT_CONNECT\n"); dwc3_intel_byt_notify_charger_type(otg, POWER_SUPPLY_CHARGER_EVENT_CONNECT); return 0; } /* For SMIP set case, only need to report 500/900ma */ if (data->charging_compliance) { if ((ma != OTG_USB2_500MA) && (ma != OTG_USB3_900MA)) return 0; } /* Covert macro to integer number*/ switch (ma) { case OTG_USB2_100MA: ma = 100; break; case OTG_USB3_150MA: ma = 150; break; case OTG_USB2_500MA: ma = 500; break; case OTG_USB3_900MA: ma = 900; break; default: otg_err(otg, "Device driver set invalid SDP current value!\n"); return -EINVAL; } spin_lock_irqsave(&otg->lock, flags); otg->charging_cap.ma = ma; spin_unlock_irqrestore(&otg->lock, flags); dwc3_intel_byt_notify_charger_type(otg, POWER_SUPPLY_CHARGER_EVENT_CONNECT); return 0; }
static void opal_message_do_notify(uint32_t msg_type, void *msg) { /* notify subscribers */ atomic_notifier_call_chain(&opal_msg_notifier_head[msg_type], msg_type, msg); }
void idle_notifier_call_chain(unsigned long val) { atomic_notifier_call_chain(&idle_notifier, val, NULL); }
/** * Detects VBUS presence status and notifies USB driver * * @pdata Pointer to the charger type detection driver data structure * return 0 on success, otherwise error code */ static int pmic_usb_vbus_det(struct pmic_usb_det_data *pdata) { u8 reg; int ret; bool during_boot = false; if (!pdata || !pdata->pdev) return -EINVAL; if (pdata->vbus_state == -1) during_boot = true; /* Ignore the VBUS report during boost */ if (pdata->usbid_state == ID_GND || pdata->usbid_state == ID_ACA) return 0; ret = pmic_reg_read(DEV1, SPWRSRC, ®); if (ret) { dev_err(pdata->pdev, "%s - fail to read DEV1 SPWRSRC\n", __func__); return ret; } if (get_field(reg, SVBUSDET_O, 1)) { dev_info(pdata->pdev, "VBUS connected\n"); /* Enable the detection circuit and start CTYP detection */ ret = pmic_usb_enable_usb_det(pdata, true); if (ret) { dev_err(pdata->pdev, "%s - fail to enable USB detection\n", __func__); return ret; } pdata->vbus_state = VBUS_ON; } else { /* Ignore the unwanted VBUS removal after stopping boost */ if (pdata->vbus_state == VBUS_OFF) return 0; dev_info(pdata->pdev, "VBUS disconnected\n"); /* Disable the internal detection circuit */ ret = pmic_usb_enable_usb_det(pdata, false); if (ret) { dev_err(pdata->pdev, "%s - fail to disable USB detection\n", __func__); return ret; } pdata->vbus_state = VBUS_OFF; /* Notify PSY/USB about NONE event if it's not during boot */ if (!during_boot) { pdata->cable_props.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_DISCONNECT; pdata->cable_props.chrg_type = pdata->cable_type; pdata->cable_props.ma = 0; pdata->cable_type = POWER_SUPPLY_CHARGER_TYPE_NONE; atomic_notifier_call_chain(&pdata->otg_handle->notifier, USB_EVENT_NONE, &pdata->cable_props); } } return 0; }