int bus_add_driver(struct device_driver *drv) { struct bus_type *bus; struct driver_private *priv; int error = 0; bus = bus_get(drv->bus); if (!bus) return -EINVAL; pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name); priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { error = -ENOMEM; goto out_put_bus; } klist_init(&priv->klist_devices, NULL, NULL); priv->driver = drv; drv->p = priv; priv->kobj.kset = bus->p->drivers_kset; error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL, "%s", drv->name); if (error) goto out_unregister; if (drv->bus->p->drivers_autoprobe) { error = driver_attach(drv); if (error) goto out_unregister; } klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); module_add_driver(drv->owner, drv); error = driver_create_file(drv, &driver_attr_uevent); if (error) { printk(KERN_ERR "%s: uevent attr (%s) failed\n", __func__, drv->name); } error = driver_add_attrs(bus, drv); if (error) { printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", __func__, drv->name); } if (!drv->suppress_bind_attrs) { error = add_bind_files(drv); if (error) { printk(KERN_ERR "%s: add_bind_files(%s) failed\n", __func__, drv->name); } } kobject_uevent(&priv->kobj, KOBJ_ADD); return 0; out_unregister: kobject_put(&priv->kobj); kfree(drv->p); drv->p = NULL; out_put_bus: bus_put(bus); return error; }
void usb_function_set_enabled(struct usb_function *f, int enabled) { f->disabled = !enabled; CSY_DBG2("name=%s, enabled=%d\n", f->name, enabled); kobject_uevent(&f->dev->kobj, KOBJ_CHANGE); }
void usb_function_set_enabled(struct usb_function *f, int enabled) { f->disabled = !enabled; kobject_uevent(&f->dev->kobj, KOBJ_CHANGE); }
int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num, struct kobject *kobj) { struct hfi1_pportdata *ppd; struct hfi1_devdata *dd = dd_from_ibdev(ibdev); int ret; if (!port_num || port_num > dd->num_pports) { dd_dev_err(dd, "Skipping infiniband class with invalid port %u\n", port_num); return -ENODEV; } ppd = &dd->pport[port_num - 1]; ret = kobject_init_and_add(&ppd->sc2vl_kobj, &hfi1_sc2vl_ktype, kobj, "sc2vl"); if (ret) { dd_dev_err(dd, "Skipping sc2vl sysfs info, (err %d) port %u\n", ret, port_num); goto bail; } kobject_uevent(&ppd->sc2vl_kobj, KOBJ_ADD); ret = kobject_init_and_add(&ppd->sl2sc_kobj, &hfi1_sl2sc_ktype, kobj, "sl2sc"); if (ret) { dd_dev_err(dd, "Skipping sl2sc sysfs info, (err %d) port %u\n", ret, port_num); goto bail_sc2vl; } kobject_uevent(&ppd->sl2sc_kobj, KOBJ_ADD); ret = kobject_init_and_add(&ppd->vl2mtu_kobj, &hfi1_vl2mtu_ktype, kobj, "vl2mtu"); if (ret) { dd_dev_err(dd, "Skipping vl2mtu sysfs info, (err %d) port %u\n", ret, port_num); goto bail_sl2sc; } kobject_uevent(&ppd->vl2mtu_kobj, KOBJ_ADD); ret = kobject_init_and_add(&ppd->pport_cc_kobj, &port_cc_ktype, kobj, "CCMgtA"); if (ret) { dd_dev_err(dd, "Skipping Congestion Control sysfs info, (err %d) port %u\n", ret, port_num); goto bail_vl2mtu; } kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr); if (ret) { dd_dev_err(dd, "Skipping Congestion Control setting sysfs info, (err %d) port %u\n", ret, port_num); goto bail_cc; } ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_table_bin_attr); if (ret) { dd_dev_err(dd, "Skipping Congestion Control table sysfs info, (err %d) port %u\n", ret, port_num); goto bail_cc_entry_bin; } dd_dev_info(dd, "Congestion Control Agent enabled for port %d\n", port_num); return 0; bail_cc_entry_bin: sysfs_remove_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr); bail_cc: kobject_put(&ppd->pport_cc_kobj); bail_vl2mtu: kobject_put(&ppd->vl2mtu_kobj); bail_sl2sc: kobject_put(&ppd->sl2sc_kobj); bail_sc2vl: kobject_put(&ppd->sc2vl_kobj); bail: return ret; }
/* * device functions */ static int uio_dev_add_attributes(struct uio_device *idev) { int ret; int mi, pi; int map_found = 0; int portio_found = 0; struct uio_mem *mem; struct uio_map *map; struct uio_port *port; struct uio_portio *portio; for (mi = 0; mi < MAX_UIO_MAPS; mi++) { mem = &idev->info->mem[mi]; if (mem->size == 0) break; if (!map_found) { map_found = 1; idev->map_dir = kobject_create_and_add("maps", &idev->dev->kobj); if (!idev->map_dir) goto err_map; } map = kzalloc(sizeof(*map), GFP_KERNEL); if (!map) goto err_map; kobject_init(&map->kobj, &map_attr_type); map->mem = mem; mem->map = map; ret = kobject_add(&map->kobj, idev->map_dir, "map%d", mi); if (ret) goto err_map; ret = kobject_uevent(&map->kobj, KOBJ_ADD); if (ret) goto err_map; } for (pi = 0; pi < MAX_UIO_PORT_REGIONS; pi++) { port = &idev->info->port[pi]; if (port->size == 0) break; if (!portio_found) { portio_found = 1; idev->portio_dir = kobject_create_and_add("portio", &idev->dev->kobj); if (!idev->portio_dir) goto err_portio; } portio = kzalloc(sizeof(*portio), GFP_KERNEL); if (!portio) goto err_portio; kobject_init(&portio->kobj, &portio_attr_type); portio->port = port; port->portio = portio; ret = kobject_add(&portio->kobj, idev->portio_dir, "port%d", pi); if (ret) goto err_portio; ret = kobject_uevent(&portio->kobj, KOBJ_ADD); if (ret) goto err_portio; } return 0; err_portio: for (pi--; pi >= 0; pi--) { port = &idev->info->port[pi]; portio = port->portio; kobject_put(&portio->kobj); } kobject_put(idev->portio_dir); err_map: for (mi--; mi>=0; mi--) { mem = &idev->info->mem[mi]; map = mem->map; kobject_put(&map->kobj); } kobject_put(idev->map_dir); dev_err(idev->dev, "error creating sysfs files (%d)\n", ret); return ret; }
int mdp4_dsi_video_on(struct platform_device *pdev) { int dsi_width; int dsi_height; int dsi_bpp; int dsi_border_clr; int dsi_underflow_clr; int dsi_hsync_skew; int hsync_period; int hsync_ctrl; int vsync_period; int display_hctl; int display_v_start; int display_v_end; int active_hctl; int active_h_start; int active_h_end; int active_v_start; int active_v_end; int ctrl_polarity; int h_back_porch; int h_front_porch; int v_back_porch; int v_front_porch; int hsync_pulse_width; int vsync_pulse_width; int hsync_polarity; int vsync_polarity; int data_en_polarity; int hsync_start_x; int hsync_end_x; uint8 *buf; unsigned int buf_offset; int bpp, ptype; static bool first_video_on = true; struct fb_info *fbi; struct fb_var_screeninfo *var; struct msm_fb_data_type *mfd; struct mdp4_overlay_pipe *pipe; int ret = 0; int cndx = 0; struct vsycn_ctrl *vctrl; vctrl = &vsync_ctrl_db[cndx]; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; vctrl->mfd = mfd; vctrl->dev = mfd->fbi->dev; /* mdp clock on */ mdp_clk_ctrl(1); fbi = mfd->fbi; var = &fbi->var; bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf_offset = calc_fb_offset(mfd, fbi, bpp); if (first_video_on) first_video_on = false; else { if (mfd->ref_cnt == 0) { //clean all pipes before base pipe and layer pipes are allocated int ndx; for (ndx=1; ndx<4; ndx++) { pipe = mdp4_overlay_ndx2pipe(ndx); if (pipe && pipe->pipe_used) mdp4_overlay_unset(mfd->fbi, ndx); } } } if (vctrl->base_pipe == NULL) { ptype = mdp4_overlay_format2type(mfd->fb_imgType); if (ptype < 0) printk(KERN_INFO "%s: format2type failed\n", __func__); pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0); if (pipe == NULL) { printk(KERN_INFO "%s: pipe_alloc failed\n", __func__); return -EBUSY; } pipe->pipe_used++; pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; pipe->mixer_num = MDP4_MIXER0; pipe->src_format = mfd->fb_imgType; mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DSI_VIDEO); ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) printk(KERN_INFO "%s: format2type failed\n", __func__); pipe->ov_blt_addr = 0; pipe->dma_blt_addr = 0; vctrl->base_pipe = pipe; /* keep it */ mdp4_init_writeback_buf(mfd, MDP4_MIXER0); } else { pipe = vctrl->base_pipe; } #ifdef CONTINUOUS_SPLASH /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); if (!(mfd->cont_splash_done)) { mfd->cont_splash_done = 1; mdp4_dsi_video_wait4dmap_done(0); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); mdelay(20); mipi_dsi_controller_cfg(0); mfd->cont_splash_done = 1; mdp_clk_ctrl(0); } #endif pipe->src_height = fbi->var.yres; pipe->src_width = fbi->var.xres; pipe->src_h = fbi->var.yres; pipe->src_w = fbi->var.xres; pipe->src_y = 0; pipe->src_x = 0; pipe->dst_h = fbi->var.yres; pipe->dst_w = fbi->var.xres; pipe->srcp0_ystride = fbi->fix.line_length; pipe->bpp = bpp; if (mfd->display_iova) pipe->srcp0_addr = mfd->display_iova + buf_offset; else pipe->srcp0_addr = (uint32)(buf + buf_offset); pipe->dst_h = fbi->var.yres; pipe->dst_w = fbi->var.xres; mdp4_overlay_mdp_pipe_req(pipe, mfd); atomic_set(&vctrl->suspend, 0); mdp4_overlay_dmap_xy(pipe); /* dma_p */ mdp4_overlay_dmap_cfg(mfd, 1); mdp4_overlay_rgb_setup(pipe); mdp4_overlayproc_cfg(pipe); mdp4_overlay_reg_flush(pipe, 1); mdp4_mixer_stage_up(pipe); mdp4_mixer_stage_commit(pipe->mixer_num); /* * DSI timing setting */ h_back_porch = var->left_margin; h_front_porch = var->right_margin; v_back_porch = var->upper_margin; v_front_porch = var->lower_margin; hsync_pulse_width = var->hsync_len; vsync_pulse_width = var->vsync_len; dsi_border_clr = mfd->panel_info.lcdc.border_clr; dsi_underflow_clr = mfd->panel_info.lcdc.underflow_clr; dsi_hsync_skew = mfd->panel_info.lcdc.hsync_skew; dsi_width = mfd->panel_info.xres + mfd->panel_info.lcdc.xres_pad; dsi_height = mfd->panel_info.yres + mfd->panel_info.lcdc.yres_pad; dsi_bpp = mfd->panel_info.bpp; hsync_period = hsync_pulse_width + h_back_porch + dsi_width + h_front_porch; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = h_back_porch + hsync_pulse_width; hsync_end_x = hsync_period - h_front_porch - 1; display_hctl = (hsync_end_x << 16) | hsync_start_x; vsync_period = (vsync_pulse_width + v_back_porch + dsi_height + v_front_porch); display_v_start = ((vsync_pulse_width + v_back_porch) * hsync_period) + dsi_hsync_skew; display_v_end = ((vsync_period - v_front_porch) * hsync_period) + dsi_hsync_skew - 1; if (dsi_width != var->xres) { active_h_start = hsync_start_x + first_pixel_start_x; active_h_end = active_h_start + var->xres - 1; active_hctl = ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start; } else { active_hctl = 0; } if (dsi_height != var->yres) { active_v_start = display_v_start + first_pixel_start_y * hsync_period; active_v_end = active_v_start + (var->yres) * hsync_period - 1; active_v_start |= ACTIVE_START_Y_EN; } else { active_v_start = 0; active_v_end = 0; } dsi_underflow_clr |= 0x80000000; /* enable recovery */ hsync_polarity = 0; vsync_polarity = 0; data_en_polarity = 0; ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x8, vsync_period * hsync_period); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0xc, vsync_pulse_width * hsync_period); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x10, display_hctl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x14, display_v_start); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x18, display_v_end); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x1c, active_hctl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x20, active_v_start); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x24, active_v_end); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x28, dsi_border_clr); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x2c, dsi_underflow_clr); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x30, dsi_hsync_skew); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x38, ctrl_polarity); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); mdp_histogram_ctrl_all(TRUE); if (!vctrl->sysfs_created) { ret = sysfs_create_group(&vctrl->dev->kobj, &vsync_fs_attr_group); if (ret) { pr_err("%s: sysfs group creation failed, ret=%d\n", __func__, ret); return ret; } kobject_uevent(&vctrl->dev->kobj, KOBJ_ADD); pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__); vctrl->sysfs_created = 1; } return ret; }
static void __ref acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data) { struct acpi_processor *pr; struct acpi_device *device = NULL; int result; switch (event) { case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor driver received %s event\n", (event == ACPI_NOTIFY_BUS_CHECK) ? "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK")); if (!is_processor_present(handle)) break; if (acpi_bus_get_device(handle, &device)) { result = acpi_processor_device_add(handle, &device); if (result) printk(KERN_ERR PREFIX "Unable to add the device\n"); break; } pr = acpi_driver_data(device); if (!pr) { printk(KERN_ERR PREFIX "Driver data is NULL\n"); break; } if (pr->id >= 0 && (pr->id < nr_cpu_ids)) { kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); break; } result = acpi_processor_start(device); if ((!result) && ((pr->id >= 0) && (pr->id < nr_cpu_ids))) { kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); } else { printk(KERN_ERR PREFIX "Device [%s] failed to start\n", acpi_device_bid(device)); } break; case ACPI_NOTIFY_EJECT_REQUEST: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "received ACPI_NOTIFY_EJECT_REQUEST\n")); if (acpi_bus_get_device(handle, &device)) { printk(KERN_ERR PREFIX "Device don't exist, dropping EJECT\n"); break; } pr = acpi_driver_data(device); if (!pr) { printk(KERN_ERR PREFIX "Driver data is NULL, dropping EJECT\n"); return; } if ((pr->id < nr_cpu_ids) && (cpu_present(pr->id))) kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); break; } return; }
int mdp_lcdc_on(struct platform_device *pdev) { int lcdc_width; int lcdc_height; int lcdc_bpp; int lcdc_border_clr; int lcdc_underflow_clr; int lcdc_hsync_skew; int hsync_period; int hsync_ctrl; int vsync_period; int display_hctl; int display_v_start; int display_v_end; int active_hctl; int active_h_start; int active_h_end; int active_v_start; int active_v_end; int ctrl_polarity; int h_back_porch; int h_front_porch; int v_back_porch; int v_front_porch; int hsync_pulse_width; int vsync_pulse_width; int hsync_polarity; int vsync_polarity; int data_en_polarity; int hsync_start_x; int hsync_end_x; uint8 *buf; int bpp; uint32 dma2_cfg_reg; struct fb_info *fbi; struct fb_var_screeninfo *var; struct msm_fb_data_type *mfd; uint32 dma_base; uint32 timer_base = LCDC_BASE; uint32 block = MDP_DMA2_BLOCK; int ret; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; fbi = mfd->fbi; var = &fbi->var; vsync_cntrl.dev = mfd->fbi->dev; atomic_set(&vsync_cntrl.suspend, 0); /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf += calc_fb_offset(mfd, fbi, bpp); dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_LCDC; if (mfd->fb_imgType == MDP_BGR_565) dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; else if (mfd->fb_imgType == MDP_RGBA_8888) dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; else dma2_cfg_reg |= DMA_PACK_PATTERN_RGB; if (bpp == 2) dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565; else if (bpp == 3) dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB888; else dma2_cfg_reg |= DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888; switch (mfd->panel_info.bpp) { case 24: dma2_cfg_reg |= DMA_DSTC0G_8BITS | DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS; break; case 18: dma2_cfg_reg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; break; case 16: dma2_cfg_reg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; break; default: printk(KERN_ERR "mdp lcdc can't support format %d bpp!\n", mfd->panel_info.bpp); return -ENODEV; } /* DMA register config */ dma_base = DMA_P_BASE; #ifdef CONFIG_FB_MSM_MDP40 if (mfd->panel.type == HDMI_PANEL) dma_base = DMA_E_BASE; #endif /* starting address */ MDP_OUTP(MDP_BASE + dma_base + 0x8, (uint32) buf); /* active window width and height */ MDP_OUTP(MDP_BASE + dma_base + 0x4, ((fbi->var.yres) << 16) | (fbi->var.xres)); /* buffer ystride */ MDP_OUTP(MDP_BASE + dma_base + 0xc, fbi->fix.line_length); /* x/y coordinate = always 0 for lcdc */ MDP_OUTP(MDP_BASE + dma_base + 0x10, 0); /* dma config */ MDP_OUTP(MDP_BASE + dma_base, dma2_cfg_reg); /* * LCDC timing setting */ h_back_porch = var->left_margin; h_front_porch = var->right_margin; v_back_porch = var->upper_margin; v_front_porch = var->lower_margin; hsync_pulse_width = var->hsync_len; vsync_pulse_width = var->vsync_len; lcdc_border_clr = mfd->panel_info.lcdc.border_clr; lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr; lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew; lcdc_width = mfd->panel_info.xres; lcdc_height = mfd->panel_info.yres; lcdc_bpp = mfd->panel_info.bpp; hsync_period = hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = hsync_pulse_width + h_back_porch; hsync_end_x = hsync_period - h_front_porch - 1; display_hctl = (hsync_end_x << 16) | hsync_start_x; vsync_period = (vsync_pulse_width + v_back_porch + lcdc_height + v_front_porch) * hsync_period; display_v_start = (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew; display_v_end = vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1; if (lcdc_width != var->xres) { active_h_start = hsync_start_x + first_pixel_start_x; active_h_end = active_h_start + var->xres - 1; active_hctl = ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start; } else { active_hctl = 0; } if (lcdc_height != var->yres) { active_v_start = display_v_start + first_pixel_start_y * hsync_period; active_v_end = active_v_start + (var->yres) * hsync_period - 1; active_v_start |= ACTIVE_START_Y_EN; } else { active_v_start = 0; active_v_end = 0; } #ifdef CONFIG_FB_MSM_MDP40 if (mfd->panel.type == HDMI_PANEL) { block = MDP_DMA_E_BLOCK; timer_base = DTV_BASE; hsync_polarity = 0; vsync_polarity = 0; } else { hsync_polarity = 1; vsync_polarity = 1; } lcdc_underflow_clr |= 0x80000000; /* enable recovery */ #else hsync_polarity = 0; vsync_polarity = 0; #endif data_en_polarity = 0; ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); MDP_OUTP(MDP_BASE + timer_base + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + timer_base + 0x8, vsync_period); MDP_OUTP(MDP_BASE + timer_base + 0xc, vsync_pulse_width * hsync_period); if (timer_base == LCDC_BASE) { MDP_OUTP(MDP_BASE + timer_base + 0x10, display_hctl); MDP_OUTP(MDP_BASE + timer_base + 0x14, display_v_start); MDP_OUTP(MDP_BASE + timer_base + 0x18, display_v_end); MDP_OUTP(MDP_BASE + timer_base + 0x28, lcdc_border_clr); MDP_OUTP(MDP_BASE + timer_base + 0x2c, lcdc_underflow_clr); MDP_OUTP(MDP_BASE + timer_base + 0x30, lcdc_hsync_skew); MDP_OUTP(MDP_BASE + timer_base + 0x38, ctrl_polarity); MDP_OUTP(MDP_BASE + timer_base + 0x1c, active_hctl); MDP_OUTP(MDP_BASE + timer_base + 0x20, active_v_start); MDP_OUTP(MDP_BASE + timer_base + 0x24, active_v_end); } else { MDP_OUTP(MDP_BASE + timer_base + 0x18, display_hctl); MDP_OUTP(MDP_BASE + timer_base + 0x1c, display_v_start); MDP_OUTP(MDP_BASE + timer_base + 0x20, display_v_end); MDP_OUTP(MDP_BASE + timer_base + 0x40, lcdc_border_clr); MDP_OUTP(MDP_BASE + timer_base + 0x44, lcdc_underflow_clr); MDP_OUTP(MDP_BASE + timer_base + 0x48, lcdc_hsync_skew); MDP_OUTP(MDP_BASE + timer_base + 0x50, ctrl_polarity); MDP_OUTP(MDP_BASE + timer_base + 0x2c, active_hctl); MDP_OUTP(MDP_BASE + timer_base + 0x30, active_v_start); MDP_OUTP(MDP_BASE + timer_base + 0x38, active_v_end); } ret = panel_next_on(pdev); if (ret == 0) { /* enable LCDC block */ MDP_OUTP(MDP_BASE + timer_base, 1); mdp_pipe_ctrl(block, MDP_BLOCK_POWER_ON, FALSE); } /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); if (!vsync_cntrl.sysfs_created) { ret = sysfs_create_group(&vsync_cntrl.dev->kobj, &vsync_fs_attr_group); if (ret) { pr_err("%s: sysfs creation failed, ret=%d\n", __func__, ret); return ret; } kobject_uevent(&vsync_cntrl.dev->kobj, KOBJ_ADD); pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__); vsync_cntrl.sysfs_created = 1; } return ret; }
static void ev3_uart_handle_rx_data(struct work_struct *work) { struct ev3_uart_port_data *port = container_of(work, struct ev3_uart_port_data, rx_data_work); struct circ_buf *cb = &port->circ_buf; u8 message[EV3_UART_MAX_MESSAGE_SIZE + 2]; int count = CIRC_CNT(cb->head, cb->tail, EV3_UART_BUFFER_SIZE); int i, speed, size_to_end; u8 cmd, cmd2, type, mode, msg_type, msg_size, chksum; #ifdef DEBUG printk("received: "); for (i = 0; i < count; i++) { cmd = cb->buf[(cb->tail + i) % EV3_UART_BUFFER_SIZE]; if (cmd >= 32 && cmd < 127) printk("%c ", cmd); else printk("0x%02x ", cmd); } printk("(%d)\n", count); #endif /* * To get in sync with the data stream from the sensor, we look * for a valid TYPE command. */ while (!port->synced) { if (count < 3) return; cmd = cb->buf[cb->tail]; cb->tail++; if (cb->tail >= EV3_UART_BUFFER_SIZE) cb->tail = 0; count--; if (cmd != (EV3_UART_MSG_TYPE_CMD | EV3_UART_CMD_TYPE)) continue; type = cb->buf[cb->tail]; if (!type || type > EV3_UART_TYPE_MAX) continue; chksum = 0xFF ^ cmd ^ type; if ((u8)cb->buf[(cb->tail + 1) % EV3_UART_BUFFER_SIZE] != chksum) continue; port->sensor.num_modes = 1; port->sensor.num_view_modes = 1; for (i = 0; i <= EV3_UART_MODE_MAX; i++) port->mode_info[i] = ev3_uart_default_mode_info; port->type_id = type; /* look up well-known driver names */ port->device_name[0] = 0; for (i = 0; i < NUM_LEGO_EV3_SENSOR_TYPES; i++) { if (type == ev3_uart_sensor_defs[i].type_id) { snprintf(port->device_name, LEGO_SENSOR_NAME_SIZE, "%s", ev3_uart_sensor_defs[i].name); break; } } /* or use generic name if well-known name is not found */ if (!port->device_name[0]) snprintf(port->device_name, LEGO_SENSOR_NAME_SIZE, EV3_UART_SENSOR_NAME("%u"), type); port->info_flags = EV3_UART_INFO_FLAG_CMD_TYPE; port->synced = 1; port->info_done = 0; port->data_rec = 0; port->num_data_err = 0; cb->tail = (cb->tail + 2) % EV3_UART_BUFFER_SIZE; count -= 2; } if (!port->synced) return; while (count > 0) { /* * Sometimes we get 0xFF after switching baud rates, so just * ignore it. */ if ((u8)cb->buf[cb->tail] == 0xFF) { cb->tail++; if (cb->tail >= EV3_UART_BUFFER_SIZE) cb->tail = 0; count--; continue; } msg_size = ev3_uart_msg_size((u8)cb->buf[cb->tail]); if (msg_size > count) break; size_to_end = CIRC_CNT_TO_END(cb->head, cb->tail, EV3_UART_BUFFER_SIZE); if (msg_size > size_to_end) { memcpy(message, cb->buf + cb->tail, size_to_end); memcpy(message + size_to_end, cb->buf, msg_size - size_to_end); cb->tail = msg_size - size_to_end; } else { memcpy(message, cb->buf + cb->tail, msg_size); cb->tail += msg_size; if (cb->tail >= EV3_UART_BUFFER_SIZE) cb->tail = 0; } count -= msg_size; #ifdef DEBUG printk("processing: "); for (i = 0; i < msg_size; i++) printk("0x%02x ", message[i]); printk(" (%d)\n", msg_size); #endif if (msg_size > EV3_UART_MAX_MESSAGE_SIZE) { port->last_err = "Bad message size."; goto err_invalid_state; } msg_type = message[0] & EV3_UART_MSG_TYPE_MASK; cmd = message[0] & EV3_UART_MSG_CMD_MASK; mode = cmd; cmd2 = message[1]; if (msg_size > 1) { chksum = 0xFF; for (i = 0; i < msg_size - 1; i++) chksum ^= message[i]; debug_pr("chksum:%d, actual:%d\n", chksum, message[msg_size - 1]); /* * The LEGO EV3 color sensor sends bad checksums * for RGB-RAW data (mode 4). The check here could be * improved if someone can find a pattern. */ if (chksum != message[msg_size - 1] && port->type_id != EV3_UART_TYPE_ID_COLOR && message[0] != 0xDC) { port->last_err = "Bad checksum."; if (port->info_done) { port->num_data_err++; goto err_bad_data_msg_checksum; } else goto err_invalid_state; } } switch (msg_type) { case EV3_UART_MSG_TYPE_SYS: debug_pr("SYS:%d\n", message[0] & EV3_UART_MSG_CMD_MASK); switch(cmd) { case EV3_UART_SYS_SYNC: /* IR sensor (type 33) sends checksum after SYNC */ if (msg_size > 1 && (cmd ^ cmd2) == 0xFF) msg_size++; break; case EV3_UART_SYS_ACK: if (!port->sensor.num_modes) { port->last_err = "Received ACK before all mode INFO."; goto err_invalid_state; } if ((port->info_flags & EV3_UART_INFO_FLAG_REQUIRED) != EV3_UART_INFO_FLAG_REQUIRED) { port->last_err = "Did not receive all required INFO."; goto err_invalid_state; } schedule_delayed_work(&port->send_ack_work, msecs_to_jiffies(EV3_UART_SEND_ACK_DELAY)); port->info_done = 1; return; } break; case EV3_UART_MSG_TYPE_CMD: debug_pr("CMD:%d\n", cmd); switch (cmd) { case EV3_UART_CMD_MODES: if (test_and_set_bit(EV3_UART_INFO_BIT_CMD_MODES, &port->info_flags)) { port->last_err = "Received duplicate modes INFO."; goto err_invalid_state; } if (!cmd2 || cmd2 > EV3_UART_MODE_MAX) { port->last_err = "Number of modes is out of range."; goto err_invalid_state; } port->sensor.num_modes = cmd2 + 1; if (msg_size > 3) port->sensor.num_view_modes = message[2] + 1; else port->sensor.num_view_modes = port->sensor.num_modes; debug_pr("num_modes:%d, num_view_modes:%d\n", port->sensor.num_modes, port->sensor.num_view_modes); break; case EV3_UART_CMD_SPEED: if (test_and_set_bit(EV3_UART_INFO_BIT_CMD_SPEED, &port->info_flags)) { port->last_err = "Received duplicate speed INFO."; goto err_invalid_state; } speed = *(int*)(message + 1); if (speed < EV3_UART_SPEED_MIN || speed > EV3_UART_SPEED_MAX) { port->last_err = "Speed is out of range."; goto err_invalid_state; } port->new_baud_rate = speed; debug_pr("speed:%d\n", speed); break; default: port->last_err = "Unknown command."; goto err_invalid_state; } break; case EV3_UART_MSG_TYPE_INFO: debug_pr("INFO:%d, mode:%d\n", cmd2, mode); switch (cmd2) { case EV3_UART_INFO_NAME: port->info_flags &= ~EV3_UART_INFO_FLAG_ALL_INFO; if (message[2] < 'A' || message[2] > 'z') { port->last_err = "Invalid name INFO."; goto err_invalid_state; } /* * Name may not have null terminator and we * are done with the checksum at this point * so we are writing 0 over the checksum to * ensure a null terminator for the string * functions. */ message[msg_size - 1] = 0; if (strlen(message + 2) > EV3_UART_MODE_NAME_SIZE) { port->last_err = "Name is too long."; goto err_invalid_state; } snprintf(port->mode_info[mode].name, EV3_UART_MODE_NAME_SIZE + 1, "%s", message + 2); if (port->sensor.mode != mode) { port->sensor.mode = mode; kobject_uevent(&port->sensor.dev.kobj, KOBJ_CHANGE); } port->info_flags |= EV3_UART_INFO_FLAG_INFO_NAME; debug_pr("mode %d name:%s\n", mode, port->sensor.address); break; case EV3_UART_INFO_RAW: if (port->sensor.mode != mode) { port->last_err = "Received INFO for incorrect mode."; goto err_invalid_state; } if (test_and_set_bit(EV3_UART_INFO_BIT_INFO_RAW, &port->info_flags)) { port->last_err = "Received duplicate raw scaling INFO."; goto err_invalid_state; } port->raw_min = *(u32 *)(message + 2); port->raw_max = *(u32 *)(message + 6); debug_pr("mode %d raw_min:%08x, raw_max:%08x\n", mode, port->mode_info[mode].raw_min, port->mode_info[mode].raw_max); break; case EV3_UART_INFO_PCT: if (port->sensor.mode != mode) { port->last_err = "Received INFO for incorrect mode."; goto err_invalid_state; } if (test_and_set_bit(EV3_UART_INFO_BIT_INFO_PCT, &port->info_flags)) { port->last_err = "Received duplicate percent scaling INFO."; goto err_invalid_state; } port->pct_min = *(u32 *)(message + 2); port->pct_max = *(u32 *)(message + 6); debug_pr("mode %d pct_min:%08x, pct_max:%08x\n", mode, port->mode_info[mode].pct_min, port->mode_info[mode].pct_max); break; case EV3_UART_INFO_SI: if (port->sensor.mode != mode) { port->last_err = "Received INFO for incorrect mode."; goto err_invalid_state; } if (test_and_set_bit(EV3_UART_INFO_BIT_INFO_SI, &port->info_flags)) { port->last_err = "Received duplicate SI scaling INFO."; goto err_invalid_state; } port->si_min = *(u32 *)(message + 2); port->si_max = *(u32 *)(message + 6); debug_pr("mode %d si_min:%08x, si_max:%08x\n", mode, port->mode_info[mode].si_min, port->mode_info[mode].si_max); break; case EV3_UART_INFO_UNITS: if (port->sensor.mode != mode) { port->last_err = "Received INFO for incorrect mode."; goto err_invalid_state; } if (test_and_set_bit(EV3_UART_INFO_BIT_INFO_UNITS, &port->info_flags)) { port->last_err = "Received duplicate SI units INFO."; goto err_invalid_state; } /* * Units may not have null terminator and we * are done with the checksum at this point * so we are writing 0 over the checksum to * ensure a null terminator for the string * functions. */ message[msg_size - 1] = 0; snprintf(port->mode_info[mode].units, EV3_UART_UNITS_SIZE + 1, "%s", message + 2); debug_pr("mode %d units:%s\n", mode, port->mode_info[mode].units); break; case EV3_UART_INFO_FORMAT: if (port->sensor.mode != mode) { port->last_err = "Received INFO for incorrect mode."; goto err_invalid_state; } if (test_and_set_bit(EV3_UART_INFO_BIT_INFO_FORMAT, &port->info_flags)) { port->last_err = "Received duplicate format INFO."; goto err_invalid_state; } port->mode_info[mode].data_sets = message[2]; if (!port->mode_info[mode].data_sets) { port->last_err = "Invalid number of data sets."; goto err_invalid_state; } if (msg_size < 7) { port->last_err = "Invalid format message size."; goto err_invalid_state; } if ((port->info_flags & EV3_UART_INFO_FLAG_REQUIRED) != EV3_UART_INFO_FLAG_REQUIRED) { port->last_err = "Did not receive all required INFO."; goto err_invalid_state; } switch (message[3]) { case EV3_UART_DATA_8: port->mode_info[mode].data_type = LEGO_SENSOR_DATA_S8; break; case EV3_UART_DATA_16: port->mode_info[mode].data_type = LEGO_SENSOR_DATA_S16; break; case EV3_UART_DATA_32: port->mode_info[mode].data_type = LEGO_SENSOR_DATA_S32; break; case EV3_UART_DATA_FLOAT: port->mode_info[mode].data_type = LEGO_SENSOR_DATA_FLOAT; break; default: port->last_err = "Invalid data type."; goto err_invalid_state; } port->mode_info[mode].figures = message[4]; port->mode_info[mode].decimals = message[5]; if (port->info_flags & EV3_UART_INFO_FLAG_INFO_RAW) { port->mode_info[mode].raw_min = lego_sensor_ftoi(port->raw_min, 0); port->mode_info[mode].raw_max = lego_sensor_ftoi(port->raw_max, 0); } if (port->info_flags & EV3_UART_INFO_FLAG_INFO_PCT) { port->mode_info[mode].pct_min = lego_sensor_ftoi(port->pct_min, 0); port->mode_info[mode].pct_max = lego_sensor_ftoi(port->pct_max, 0); } if (port->info_flags & EV3_UART_INFO_FLAG_INFO_SI) { port->mode_info[mode].si_min = lego_sensor_ftoi(port->si_min, port->mode_info[mode].decimals); port->mode_info[mode].si_max = lego_sensor_ftoi(port->si_max, port->mode_info[mode].decimals); } if (port->sensor.mode) port->sensor.mode--; debug_pr("mode %d - data_sets:%d, data_type:%d, figures:%d, decimals:%d\n", mode, port->mode_info[mode].data_sets, port->mode_info[mode].data_type, port->mode_info[mode].figures, port->mode_info[mode].decimals); debug_pr("raw_min: %d, raw_max: %d\n", port->mode_info[mode].raw_min, port->mode_info[mode].raw_max); debug_pr("pct_min: %d, pct_max: %d\n", port->mode_info[mode].pct_min, port->mode_info[mode].pct_max); debug_pr("si_min: %d, si_max: %d\n", port->mode_info[mode].si_min, port->mode_info[mode].si_max); break; } break; case EV3_UART_MSG_TYPE_DATA: debug_pr("DATA:%d\n", message[0] & EV3_UART_MSG_CMD_MASK); if (!port->info_done) { port->last_err = "Received DATA before INFO was complete."; goto err_invalid_state; } if (mode > EV3_UART_MODE_MAX) { port->last_err = "Invalid mode received."; goto err_invalid_state; } if (mode != port->sensor.mode) { if (mode == port->new_mode) { port->sensor.mode = mode; kobject_uevent(&port->sensor.dev.kobj, KOBJ_CHANGE); } else { port->last_err = "Unexpected mode."; goto err_invalid_state; } } if (!completion_done(&port->set_mode_completion) && mode == port->new_mode) complete(&port->set_mode_completion); memcpy(port->mode_info[mode].raw_data, message + 1, msg_size - 2); port->data_rec = 1; if (port->num_data_err) port->num_data_err--; break; } err_bad_data_msg_checksum: count = CIRC_CNT(cb->head, cb->tail, EV3_UART_BUFFER_SIZE); } return; err_invalid_state: port->synced = 0; port->new_baud_rate = EV3_UART_SPEED_MIN; schedule_work(&port->change_bitrate_work); }
/** * edac_pci_main_kobj_setup() * * setup the sysfs for EDAC PCI attributes * assumes edac_subsys has already been initialized */ static int edac_pci_main_kobj_setup(void) { int err; struct bus_type *edac_subsys; debugf0("%s()\n", __func__); /* check and count if we have already created the main kobject */ if (atomic_inc_return(&edac_pci_sysfs_refcount) != 1) return 0; /* First time, so create the main kobject and its * controls and attributes */ edac_subsys = edac_get_sysfs_subsys(); if (edac_subsys == NULL) { debugf1("%s() no edac_subsys\n", __func__); err = -ENODEV; goto decrement_count_fail; } /* Bump the reference count on this module to ensure the * modules isn't unloaded until we deconstruct the top * level main kobj for EDAC PCI */ if (!try_module_get(THIS_MODULE)) { debugf1("%s() try_module_get() failed\n", __func__); err = -ENODEV; goto mod_get_fail; } edac_pci_top_main_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); if (!edac_pci_top_main_kobj) { debugf1("Failed to allocate\n"); err = -ENOMEM; goto kzalloc_fail; } /* Instanstiate the pci object */ err = kobject_init_and_add(edac_pci_top_main_kobj, &ktype_edac_pci_main_kobj, &edac_subsys->dev_root->kobj, "pci"); if (err) { debugf1("Failed to register '.../edac/pci'\n"); goto kobject_init_and_add_fail; } /* At this point, to 'release' the top level kobject * for EDAC PCI, then edac_pci_main_kobj_teardown() * must be used, for resources to be cleaned up properly */ kobject_uevent(edac_pci_top_main_kobj, KOBJ_ADD); debugf1("Registered '.../edac/pci' kobject\n"); return 0; /* Error unwind statck */ kobject_init_and_add_fail: kfree(edac_pci_top_main_kobj); kzalloc_fail: module_put(THIS_MODULE); mod_get_fail: edac_put_sysfs_subsys(); decrement_count_fail: /* if are on this error exit, nothing to tear down */ atomic_dec(&edac_pci_sysfs_refcount); return err; }
static int __devinit tmp102_temp_sensor_probe( struct i2c_client *client, const struct i2c_device_id *id) { struct tmp102_temp_sensor *tmp102; int ret = 0; #ifdef CONFIG_THERMAL_DEBUG printk(KERN_DEBUG "%s\n", __func__); #endif if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { dev_err(&client->dev, "adapter doesn't support SMBus word " "transactions\n"); return -ENODEV; } tmp102 = kzalloc(sizeof(struct tmp102_temp_sensor), GFP_KERNEL); if (!tmp102) return -ENOMEM; mutex_init(&tmp102->sensor_mutex); tmp102->iclient = client; tmp102->dev = &client->dev; kobject_uevent(&client->dev.kobj, KOBJ_ADD); i2c_set_clientdata(client, tmp102); ret = tmp102_read_reg(client, TMP102_CONF_REG); if (ret < 0) { dev_err(&client->dev, "error reading config register\n"); goto free_err; } tmp102->config_orig = ret; ret = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); if (ret < 0) { dev_err(&client->dev, "error writing config register\n"); goto restore_config_err; } ret = tmp102_read_reg(client, TMP102_CONF_REG); if (ret < 0) { dev_err(&client->dev, "error reading config register\n"); goto restore_config_err; } ret &= ~TMP102_CONFIG_RD_ONLY; if (ret != TMP102_CONFIG) { dev_err(&client->dev, "config settings did not stick\n"); ret = -ENODEV; goto restore_config_err; } tmp102->last_update = jiffies - HZ; mutex_init(&tmp102->sensor_mutex); ret = sysfs_create_group(&client->dev.kobj, &tmp102_temp_sensor_attr_group); if (ret) goto sysfs_create_err; tmp102->therm_fw = kzalloc(sizeof(struct thermal_dev), GFP_KERNEL); if (tmp102->therm_fw) { tmp102->therm_fw->name = TMP102_SENSOR_NAME; tmp102->therm_fw->domain_name = "pcb"; tmp102->therm_fw->dev = tmp102->dev; tmp102->therm_fw->dev_ops = &tmp102_temp_sensor_ops; thermal_sensor_dev_register(tmp102->therm_fw); } else { ret = -ENOMEM; goto therm_fw_alloc_err; } dev_info(&client->dev, "initialized\n"); return 0; sysfs_create_err: thermal_sensor_dev_unregister(tmp102->therm_fw); kfree(tmp102->therm_fw); restore_config_err: tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig); therm_fw_alloc_err: free_err: mutex_destroy(&tmp102->sensor_mutex); kfree(tmp102); return ret; }
int mdp4_lcdc_on(struct platform_device *pdev) { int lcdc_width; int lcdc_height; int lcdc_bpp; int lcdc_border_clr; int lcdc_underflow_clr; int lcdc_hsync_skew; int hsync_period; int hsync_ctrl; int vsync_period; int display_hctl; int display_v_start; int display_v_end; int active_hctl; int active_h_start; int active_h_end; int active_v_start; int active_v_end; int ctrl_polarity; int h_back_porch; int h_front_porch; int v_back_porch; int v_front_porch; int hsync_pulse_width; int vsync_pulse_width; int hsync_polarity; int vsync_polarity; int data_en_polarity; int hsync_start_x; int hsync_end_x; uint8 *buf; unsigned int buf_offset; int bpp, ptype; struct fb_info *fbi; struct fb_var_screeninfo *var; struct msm_fb_data_type *mfd; struct mdp4_overlay_pipe *pipe; int ret = 0; int cndx = 0; struct vsycn_ctrl *vctrl; vctrl = &vsync_ctrl_db[cndx]; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; vctrl->mfd = mfd; vctrl->dev = mfd->fbi->dev; vctrl->vsync_irq_enabled = 0; /* mdp clock on */ mdp_clk_ctrl(1); fbi = mfd->fbi; var = &fbi->var; bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf_offset = calc_fb_offset(mfd, fbi, bpp); if (vctrl->base_pipe == NULL) { ptype = mdp4_overlay_format2type(mfd->fb_imgType); if (ptype < 0) printk(KERN_INFO "%s: format2type failed\n", __func__); pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0); if (pipe == NULL) printk(KERN_INFO "%s: pipe_alloc failed\n", __func__); pipe->pipe_used++; pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; pipe->mixer_num = MDP4_MIXER0; pipe->src_format = mfd->fb_imgType; mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_LCDC); ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) printk(KERN_INFO "%s: format2pipe failed\n", __func__); mdp4_init_writeback_buf(mfd, MDP4_MIXER0); pipe->ov_blt_addr = 0; pipe->dma_blt_addr = 0; vctrl->base_pipe = pipe; /* keep it */ } else { pipe = vctrl->base_pipe; } pipe->src_height = fbi->var.yres; pipe->src_width = fbi->var.xres; pipe->src_h = fbi->var.yres; pipe->src_w = fbi->var.xres; pipe->src_y = 0; pipe->src_x = 0; pipe->dst_h = fbi->var.yres; pipe->dst_w = fbi->var.xres; if (mfd->display_iova) pipe->srcp0_addr = mfd->display_iova + buf_offset; else pipe->srcp0_addr = (uint32)(buf + buf_offset); pipe->srcp0_ystride = fbi->fix.line_length; pipe->bpp = bpp; mdp4_overlay_solidfill_init(pipe); mdp4_overlay_mdp_pipe_req(pipe, mfd); atomic_set(&vctrl->suspend, 0); mdp4_overlay_dmap_xy(pipe); mdp4_overlay_dmap_cfg(mfd, 1); mdp4_overlay_rgb_setup(pipe); mdp4_overlayproc_cfg(pipe); mdp4_overlay_reg_flush(pipe, 1); mdp4_mixer_stage_up(pipe, 0); mdp4_mixer_stage_commit(pipe->mixer_num); /* * LCDC timing setting */ h_back_porch = var->left_margin; h_front_porch = var->right_margin; v_back_porch = var->upper_margin; v_front_porch = var->lower_margin; hsync_pulse_width = var->hsync_len; vsync_pulse_width = var->vsync_len; lcdc_border_clr = mfd->panel_info.lcdc.border_clr; lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr; lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew; lcdc_width = var->xres + mfd->panel_info.lcdc.xres_pad; lcdc_height = var->yres + mfd->panel_info.lcdc.yres_pad; lcdc_bpp = mfd->panel_info.bpp; hsync_period = hsync_pulse_width + h_back_porch + h_front_porch; if ((mfd->panel_info.type == LVDS_PANEL) && (mfd->panel_info.lvds.channel_mode == LVDS_DUAL_CHANNEL_MODE)) hsync_period += lcdc_width / 2; else hsync_period += lcdc_width; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = hsync_pulse_width + h_back_porch; hsync_end_x = hsync_period - h_front_porch - 1; display_hctl = (hsync_end_x << 16) | hsync_start_x; vsync_period = (vsync_pulse_width + v_back_porch + lcdc_height + v_front_porch) * hsync_period; display_v_start = (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew; display_v_end = vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1; if (lcdc_width != var->xres) { active_h_start = hsync_start_x + first_pixel_start_x; active_h_end = active_h_start + var->xres - 1; active_hctl = ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start; } else { active_hctl = 0; } if (lcdc_height != var->yres) { active_v_start = display_v_start + first_pixel_start_y * hsync_period; active_v_end = active_v_start + (var->yres) * hsync_period - 1; active_v_start |= ACTIVE_START_Y_EN; } else { active_v_start = 0; active_v_end = 0; } #ifdef CONFIG_FB_MSM_MDP40 if (mfd->panel_info.lcdc.is_sync_active_high) { hsync_polarity = 0; vsync_polarity = 0; } else { hsync_polarity = 1; vsync_polarity = 1; } lcdc_underflow_clr |= 0x80000000; /* enable recovery */ #else hsync_polarity = 0; vsync_polarity = 0; #endif #if defined(CONFIG_MACH_ARIESVE) || defined(CONFIG_MACH_APACHE) data_en_polarity = 1; #else data_en_polarity = 0; #endif ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x8, vsync_period); MDP_OUTP(MDP_BASE + LCDC_BASE + 0xc, vsync_pulse_width * hsync_period); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x10, display_hctl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x14, display_v_start); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x18, display_v_end); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x28, lcdc_border_clr); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x2c, lcdc_underflow_clr); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x30, lcdc_hsync_skew); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x38, ctrl_polarity); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x1c, active_hctl); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x20, active_v_start); MDP_OUTP(MDP_BASE + LCDC_BASE + 0x24, active_v_end); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); mdp_histogram_ctrl_all(TRUE); #if defined(CONFIG_MACH_ANCORA) || defined(CONFIG_MACH_ANCORA_TMO) if (board_lcd_hw_revision == 3) { ret = panel_next_on(pdev); if (ret == 0) { /* enable LCDC block */ MDP_OUTP(MDP_BASE + LCDC_BASE, 1); mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE); } /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); } else { /* * LCDC Block must be enabled before the time of turn on lcd * because of the signal timing. */ mdp4_overlay_lcdc_start(); } #else /* * LCDC Block must be enabled before the time of turn on lcd * because of the signal timing. */ mdp4_overlay_lcdc_start(); #endif if (!vctrl->sysfs_created) { ret = sysfs_create_group(&vctrl->dev->kobj, &vsync_fs_attr_group); if (ret) { pr_err("%s: sysfs group creation failed, ret=%d\n", __func__, ret); return ret; } kobject_uevent(&vctrl->dev->kobj, KOBJ_ADD); pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__); vctrl->sysfs_created = 1; } return ret; }
static int pm8xxx_tz_get_temp_pm8xxx_adc(struct thermal_zone_device *thermal, unsigned long *temp) { struct pm8xxx_tm_chip *chip = thermal->devdata; struct pm8xxx_adc_chan_result result = { .physical = 0lu, }; int rc; if (!chip || !temp) return -EINVAL; *temp = chip->temp; rc = pm8xxx_adc_read(chip->cdata.adc_channel, &result); if (rc < 0) { pr_err("%s: adc_channel_read_result() failed, rc = %d\n", chip->cdata.tm_name, rc); return rc; } *temp = result.physical; chip->temp = result.physical; return 0; } static int pm8xxx_tz_get_mode(struct thermal_zone_device *thermal, enum thermal_device_mode *mode) { struct pm8xxx_tm_chip *chip = thermal->devdata; if (!chip || !mode) return -EINVAL; *mode = chip->mode; return 0; } static int pm8xxx_tz_set_mode(struct thermal_zone_device *thermal, enum thermal_device_mode mode) { struct pm8xxx_tm_chip *chip = thermal->devdata; if (!chip) return -EINVAL; if (mode != chip->mode) { if (mode == THERMAL_DEVICE_ENABLED) pm8xxx_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_ENABLED); else pm8xxx_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED); } chip->mode = mode; return 0; } static int pm8xxx_tz_get_trip_type(struct thermal_zone_device *thermal, int trip, enum thermal_trip_type *type) { if (trip < 0 || !type) return -EINVAL; switch (trip) { case TRIP_STAGE3: *type = THERMAL_TRIP_CRITICAL; break; case TRIP_STAGE2: *type = THERMAL_TRIP_HOT; break; case TRIP_STAGE1: *type = THERMAL_TRIP_HOT; break; default: return -EINVAL; } return 0; } static int pm8xxx_tz_get_trip_temp(struct thermal_zone_device *thermal, int trip, unsigned long *temp) { struct pm8xxx_tm_chip *chip = thermal->devdata; int thresh_temp; if (!chip || trip < 0 || !temp) return -EINVAL; thresh_temp = chip->thresh * TEMP_THRESH_STEP + TEMP_THRESH_MIN; switch (trip) { case TRIP_STAGE3: thresh_temp += 2 * TEMP_STAGE_STEP; break; case TRIP_STAGE2: thresh_temp += TEMP_STAGE_STEP; break; case TRIP_STAGE1: break; default: return -EINVAL; } *temp = thresh_temp; return 0; } static int pm8xxx_tz_get_crit_temp(struct thermal_zone_device *thermal, unsigned long *temp) { struct pm8xxx_tm_chip *chip = thermal->devdata; if (!chip || !temp) return -EINVAL; *temp = chip->thresh * TEMP_THRESH_STEP + TEMP_THRESH_MIN + 2 * TEMP_STAGE_STEP; return 0; } static struct thermal_zone_device_ops pm8xxx_thermal_zone_ops_no_adc = { .get_temp = pm8xxx_tz_get_temp_no_adc, .get_mode = pm8xxx_tz_get_mode, .set_mode = pm8xxx_tz_set_mode, .get_trip_type = pm8xxx_tz_get_trip_type, .get_trip_temp = pm8xxx_tz_get_trip_temp, .get_crit_temp = pm8xxx_tz_get_crit_temp, }; static struct thermal_zone_device_ops pm8xxx_thermal_zone_ops_pm8xxx_adc = { .get_temp = pm8xxx_tz_get_temp_pm8xxx_adc, .get_mode = pm8xxx_tz_get_mode, .set_mode = pm8xxx_tz_set_mode, .get_trip_type = pm8xxx_tz_get_trip_type, .get_trip_temp = pm8xxx_tz_get_trip_temp, .get_crit_temp = pm8xxx_tz_get_crit_temp, }; static void pm8xxx_tm_work(struct work_struct *work) { struct pm8xxx_tm_chip *chip = container_of(work, struct pm8xxx_tm_chip, irq_work); int rc; u8 reg; rc = pm8xxx_tm_read_ctrl(chip, ®); if (rc < 0) goto bail; if (chip->cdata.adc_type == PM8XXX_TM_ADC_NONE) { rc = pm8xxx_tm_update_temp_no_adc(chip); if (rc < 0) goto bail; pr_info("%s: Temp Alarm - stage=%u, threshold=%u, " "temp=%lu mC\n", chip->cdata.tm_name, chip->stage, chip->thresh, chip->temp); } else { chip->stage = (reg & TEMP_ALARM_CTRL_STATUS_MASK) >> TEMP_ALARM_CTRL_STATUS_SHIFT; chip->thresh = (reg & TEMP_ALARM_CTRL_THRESH_MASK) >> TEMP_ALARM_CTRL_THRESH_SHIFT; pr_info("%s: Temp Alarm - stage=%u, threshold=%u\n", chip->cdata.tm_name, chip->stage, chip->thresh); } /* Clear status bits. */ if (reg & (TEMP_ALARM_CTRL_ST2_SD | TEMP_ALARM_CTRL_ST3_SD)) { reg &= ~(TEMP_ALARM_CTRL_ST2_SD | TEMP_ALARM_CTRL_ST3_SD | TEMP_ALARM_CTRL_STATUS_MASK); pm8xxx_tm_write_ctrl(chip, reg); } thermal_zone_device_update(chip->tz_dev); /* Notify user space */ if (chip->mode == THERMAL_DEVICE_ENABLED) kobject_uevent(&chip->tz_dev->device.kobj, KOBJ_CHANGE); bail: enable_irq(chip->tempstat_irq); enable_irq(chip->overtemp_irq); } static irqreturn_t pm8xxx_tm_isr(int irq, void *data) { struct pm8xxx_tm_chip *chip = data; disable_irq_nosync(chip->tempstat_irq); disable_irq_nosync(chip->overtemp_irq); schedule_work(&chip->irq_work); return IRQ_HANDLED; } static int pm8xxx_tm_init_reg(struct pm8xxx_tm_chip *chip) { int rc; u8 reg; rc = pm8xxx_tm_read_ctrl(chip, ®); if (rc < 0) return rc; chip->stage = (reg & TEMP_ALARM_CTRL_STATUS_MASK) >> TEMP_ALARM_CTRL_STATUS_SHIFT; chip->temp = 0; /* Use temperature threshold set 0: (105, 125, 145) */ chip->thresh = 0; reg = (chip->thresh << TEMP_ALARM_CTRL_THRESH_SHIFT) & TEMP_ALARM_CTRL_THRESH_MASK; rc = pm8xxx_tm_write_ctrl(chip, reg); if (rc < 0) return rc; /* * Set the PMIC alarm module PWM to have a frequency of 8 Hz. This * helps cut down on the number of unnecessary interrupts fired when * changing between thermal stages. Also, Enable the over temperature * PWM whenever the PMIC is enabled. */ reg = (1 << TEMP_ALARM_PWM_EN_SHIFT) | (3 << TEMP_ALARM_PWM_PER_PRE_SHIFT) | (3 << TEMP_ALARM_PWM_PER_DIV_SHIFT); rc = pm8xxx_tm_write_pwm(chip, reg); return rc; }
static int escore_vs_isr(struct notifier_block *self, unsigned long action, void *dev) { struct escore_priv *escore = (struct escore_priv *)dev; struct escore_voice_sense *voice_sense = (struct escore_voice_sense *) escore->voice_sense; u32 smooth_mute = ES_SET_SMOOTH_MUTE << 16 | ES_SMOOTH_MUTE_ZERO; u32 es_set_power_level = ES_SET_POWER_LEVEL << 16 | ES_POWER_LEVEL_6; u32 resp; int rc = 0; dev_dbg(escore->dev, "%s(): Event: 0x%04x\n", __func__, (u32)action); if ((action & 0xFF) != ES_VS_INTR_EVENT) { dev_err(escore->dev, "%s(): Invalid event callback 0x%04x\n", __func__, (u32) action); return NOTIFY_DONE; } dev_info(escore->dev, "%s(): VS event detected 0x%04x\n", __func__, (u32) action); if (voice_sense->cvs_preset != 0xFFFF && voice_sense->cvs_preset != 0) { escore->escore_power_state = ES_SET_POWER_STATE_NORMAL; escore->vs_pm_state = ES_PM_NORMAL; escore->non_vs_pm_state = ES_PM_NORMAL; escore->mode = STANDARD; } mutex_lock(&voice_sense->vs_event_mutex); voice_sense->vs_get_event = action; mutex_unlock(&voice_sense->vs_event_mutex); /* If CVS preset is set (other than 0xFFFF), earSmart chip is * in CVS mode. To make it switch from internal to external * oscillator, send power level command with highest power * level */ if (voice_sense->cvs_preset != 0xFFFF && voice_sense->cvs_preset != 0) { rc = escore_cmd(escore, smooth_mute, &resp); if (rc < 0) { pr_err("%s(): Error setting smooth mute\n", __func__); goto voiceq_isr_exit; } usleep_range(2000, 2005); rc = escore_cmd(escore, es_set_power_level, &resp); if (rc < 0) { pr_err("%s(): Error setting power level\n", __func__); goto voiceq_isr_exit; } usleep_range(2000, 2005); /* Each time earSmart chip comes in BOSKO mode after * VS detect, CVS mode will be disabled */ voice_sense->cvs_preset = 0; } kobject_uevent(&escore->dev->kobj, KOBJ_CHANGE); return NOTIFY_OK; voiceq_isr_exit: return NOTIFY_DONE; }
int qib_create_port_files(struct ib_device *ibdev, u8 port_num, struct kobject *kobj) { struct qib_pportdata *ppd; struct qib_devdata *dd = dd_from_ibdev(ibdev); int ret; if (!port_num || port_num > dd->num_pports) { qib_dev_err(dd, "Skipping infiniband class with invalid port %u\n", port_num); ret = -ENODEV; goto bail; } ppd = &dd->pport[port_num - 1]; ret = kobject_init_and_add(&ppd->pport_kobj, &qib_port_ktype, kobj, "linkcontrol"); if (ret) { qib_dev_err(dd, "Skipping linkcontrol sysfs info, (err %d) port %u\n", ret, port_num); goto bail; } kobject_uevent(&ppd->pport_kobj, KOBJ_ADD); ret = kobject_init_and_add(&ppd->sl2vl_kobj, &qib_sl2vl_ktype, kobj, "sl2vl"); if (ret) { qib_dev_err(dd, "Skipping sl2vl sysfs info, (err %d) port %u\n", ret, port_num); goto bail_link; } kobject_uevent(&ppd->sl2vl_kobj, KOBJ_ADD); ret = kobject_init_and_add(&ppd->diagc_kobj, &qib_diagc_ktype, kobj, "diag_counters"); if (ret) { qib_dev_err(dd, "Skipping diag_counters sysfs info, (err %d) port %u\n", ret, port_num); goto bail_sl; } kobject_uevent(&ppd->diagc_kobj, KOBJ_ADD); if (!qib_cc_table_size || !ppd->congestion_entries_shadow) return 0; ret = kobject_init_and_add(&ppd->pport_cc_kobj, &qib_port_cc_ktype, kobj, "CCMgtA"); if (ret) { qib_dev_err(dd, "Skipping Congestion Control sysfs info, (err %d) port %u\n", ret, port_num); goto bail_diagc; } kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr); if (ret) { qib_dev_err(dd, "Skipping Congestion Control setting sysfs info, (err %d) port %u\n", ret, port_num); goto bail_cc; } ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_table_bin_attr); if (ret) { qib_dev_err(dd, "Skipping Congestion Control table sysfs info, (err %d) port %u\n", ret, port_num); goto bail_cc_entry_bin; } qib_devinfo(dd->pcidev, "IB%u: Congestion Control Agent enabled for port %d\n", dd->unit, port_num); return 0; bail_cc_entry_bin: sysfs_remove_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr); bail_cc: kobject_put(&ppd->pport_cc_kobj); bail_diagc: kobject_put(&ppd->diagc_kobj); bail_sl: kobject_put(&ppd->sl2vl_kobj); bail_link: kobject_put(&ppd->pport_kobj); bail: return ret; }
static ssize_t disk_uevent_store(struct gendisk * disk, const char *buf, size_t count) { kobject_uevent(&disk->kobj, KOBJ_ADD); return count; }
/** * bus_add_driver :总线注册驱动. */ int bus_add_driver(struct device_driver *drv) { struct bus_type *bus; struct driver_private *priv; int error = 0; bus = bus_get(drv->bus); if (!bus) return -EINVAL; pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name); /*申请驱动私有数据内存,驱动所支持的所有设备都存放到 * priv中*/ priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { error = -ENOMEM; goto out_put_bus; } klist_init(&priv->klist_devices, NULL, NULL); priv->driver = drv; drv->p = priv; /*驱动加入到总线的驱动对象集合中*/ priv->kobj.kset = bus->p->drivers_kset; /*在sys文件系统中创建priv->kobj对象,目录名称为drv->name*/ error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL, "%s", drv->name); if (error) goto out_unregister; if (drv->bus->p->drivers_autoprobe) { error = driver_attach(drv); if (error) goto out_unregister; } /*驱动链接到所属的bus的driver链表中*/ klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); module_add_driver(drv->owner, drv); /*在sys文件系统中创建drv->p->kobj目录下创建驱动属性文件*/ error = driver_create_file(drv, &driver_attr_uevent); if (error) { printk(KERN_ERR "%s: uevent attr (%s) failed\n", __func__, drv->name); } /*为drv->p->kobj目录项下创建bus属性文件*/ error = driver_add_attrs(bus, drv); if (error) { /* How the hell do we get out of this pickle? Give up */ printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", __func__, drv->name); } if (!drv->suppress_bind_attrs) { error = add_bind_files(drv); if (error) { /* Ditto */ printk(KERN_ERR "%s: add_bind_files(%s) failed\n", __func__, drv->name); } } kobject_uevent(&priv->kobj, KOBJ_ADD); return 0; out_unregister: kfree(drv->p); drv->p = NULL; kobject_put(&priv->kobj); out_put_bus: bus_put(bus); return error; }
int mdp_dsi_video_on(struct platform_device *pdev) { int dsi_width; int dsi_height; int dsi_bpp; int dsi_border_clr; int dsi_underflow_clr; int dsi_hsync_skew; int hsync_period; int hsync_ctrl; int vsync_period; int display_hctl; int display_v_start; int display_v_end; int active_hctl; int active_h_start; int active_h_end; int active_v_start; int active_v_end; int ctrl_polarity; int h_back_porch; int h_front_porch; int v_back_porch; int v_front_porch; int hsync_pulse_width; int vsync_pulse_width; int hsync_polarity; int vsync_polarity; int data_en_polarity; int hsync_start_x; int hsync_end_x; uint8 *buf; uint32 dma2_cfg_reg; int bpp; struct fb_info *fbi; struct fb_var_screeninfo *var; struct msm_fb_data_type *mfd; int ret; uint32_t mask, curr; mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); if (!mfd) return -ENODEV; if (mfd->key != MFD_KEY) return -EINVAL; fbi = mfd->fbi; var = &fbi->var; vsync_cntrl.dev = mfd->fbi->dev; atomic_set(&vsync_cntrl.suspend, 0); bpp = fbi->var.bits_per_pixel / 8; buf = (uint8 *) fbi->fix.smem_start; buf += calc_fb_offset(mfd, fbi, bpp); dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_DSI_VIDEO; if (mfd->fb_imgType == MDP_BGR_565) dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; else if (mfd->fb_imgType == MDP_RGBA_8888) dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; else dma2_cfg_reg |= DMA_PACK_PATTERN_RGB; if (bpp == 2) dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565; else if (bpp == 3) dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB888; else dma2_cfg_reg |= DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888; switch (mfd->panel_info.bpp) { case 24: dma2_cfg_reg |= DMA_DSTC0G_8BITS | DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS; break; case 18: dma2_cfg_reg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; break; case 16: dma2_cfg_reg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; break; default: printk(KERN_ERR "mdp lcdc can't support format %d bpp!\n", mfd->panel_info.bpp); return -ENODEV; } /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); /* starting address */ MDP_OUTP(MDP_BASE + DMA_P_BASE + 0x8, (uint32) buf); /* active window width and height */ MDP_OUTP(MDP_BASE + DMA_P_BASE + 0x4, ((fbi->var.yres) << 16) | (fbi->var.xres)); /* buffer ystride */ MDP_OUTP(MDP_BASE + DMA_P_BASE + 0xc, fbi->fix.line_length); /* x/y coordinate = always 0 for lcdc */ MDP_OUTP(MDP_BASE + DMA_P_BASE + 0x10, 0); /* dma config */ curr = inpdw(MDP_BASE + DMA_P_BASE); mask = 0x0FFFFFFF; dma2_cfg_reg = (dma2_cfg_reg & mask) | (curr & ~mask); MDP_OUTP(MDP_BASE + DMA_P_BASE, dma2_cfg_reg); /* * DSI timing setting */ h_back_porch = var->left_margin; h_front_porch = var->right_margin; v_back_porch = var->upper_margin; v_front_porch = var->lower_margin; hsync_pulse_width = var->hsync_len; vsync_pulse_width = var->vsync_len; dsi_border_clr = mfd->panel_info.lcdc.border_clr; dsi_underflow_clr = mfd->panel_info.lcdc.underflow_clr; dsi_hsync_skew = mfd->panel_info.lcdc.hsync_skew; dsi_width = mfd->panel_info.xres; dsi_height = mfd->panel_info.yres; dsi_bpp = mfd->panel_info.bpp; hsync_period = h_back_porch + dsi_width + h_front_porch + 1; hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; hsync_start_x = h_back_porch; hsync_end_x = dsi_width + h_back_porch - 1; display_hctl = (hsync_end_x << 16) | hsync_start_x; vsync_period = (v_back_porch + dsi_height + v_front_porch + 1) * hsync_period; display_v_start = v_back_porch * hsync_period + dsi_hsync_skew; display_v_end = (dsi_height + v_back_porch) * hsync_period; active_h_start = hsync_start_x + first_pixel_start_x; active_h_end = active_h_start + var->xres - 1; active_hctl = ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start; active_v_start = display_v_start + first_pixel_start_y * hsync_period; active_v_end = active_v_start + (var->yres) * hsync_period - 1; active_v_start |= ACTIVE_START_Y_EN; dsi_underflow_clr |= 0x80000000; /* enable recovery */ hsync_polarity = 0; vsync_polarity = 0; data_en_polarity = 0; ctrl_polarity = (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); if (!(mfd->cont_splash_done)) { mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); /* lichm 20130227 add for RGB lcd build error */ #if defined(TYQ_LCD_SUPPORT) #else mipi_dsi_controller_cfg(0); #endif } MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x4, hsync_ctrl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x8, vsync_period); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0xc, vsync_pulse_width); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x10, display_hctl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x14, display_v_start); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x18, display_v_end); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x1c, active_hctl); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x20, active_v_start); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x24, active_v_end); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x28, dsi_border_clr); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x2c, dsi_underflow_clr); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x30, dsi_hsync_skew); MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x38, ctrl_polarity); ret = panel_next_on(pdev); if (ret == 0) { /* enable DSI block */ MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1); /*Turning on DMA_P block*/ mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE); } /* MDP cmd block disable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); if (!vsync_cntrl.sysfs_created) { ret = sysfs_create_group(&vsync_cntrl.dev->kobj, &vsync_fs_attr_group); if (ret) { pr_err("%s: sysfs creation failed, ret=%d\n", __func__, ret); return ret; } kobject_uevent(&vsync_cntrl.dev->kobj, KOBJ_ADD); pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__); vsync_cntrl.sysfs_created = 1; } mdp_histogram_ctrl_all(TRUE); return ret; }
int mdp3_ctrl_init(struct msm_fb_data_type *mfd) { struct device *dev = mfd->fbi->dev; struct msm_mdp_interface *mdp3_interface = &mfd->mdp; struct mdp3_session_data *mdp3_session = NULL; u32 intf_type = MDP3_DMA_OUTPUT_SEL_DSI_VIDEO; int rc; pr_debug("mdp3_ctrl_init\n"); mdp3_interface->on_fnc = mdp3_ctrl_on; mdp3_interface->off_fnc = mdp3_ctrl_off; mdp3_interface->do_histogram = NULL; mdp3_interface->cursor_update = NULL; mdp3_interface->dma_fnc = mdp3_ctrl_pan_display; mdp3_interface->ioctl_handler = mdp3_ctrl_ioctl_handler; mdp3_interface->kickoff_fnc = mdp3_ctrl_display_commit_kickoff; mdp3_session = kmalloc(sizeof(struct mdp3_session_data), GFP_KERNEL); if (!mdp3_session) { pr_err("fail to allocate mdp3 private data structure"); return -ENOMEM; } memset(mdp3_session, 0, sizeof(struct mdp3_session_data)); mutex_init(&mdp3_session->lock); init_completion(&mdp3_session->vsync_comp); spin_lock_init(&mdp3_session->vsync_lock); mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL); if (!mdp3_session->dma) { rc = -ENODEV; goto init_done; } intf_type = mdp3_ctrl_get_intf_type(mfd); mdp3_session->intf = mdp3_get_display_intf(intf_type); if (!mdp3_session->intf) { rc = -ENODEV; goto init_done; } mdp3_session->panel = dev_get_platdata(&mfd->pdev->dev); mdp3_session->status = 0; mdp3_session->overlay.id = MSMFB_NEW_REQUEST; mdp3_bufq_init(&mdp3_session->bufq_in); mdp3_bufq_init(&mdp3_session->bufq_out); mfd->mdp.private1 = mdp3_session; rc = sysfs_create_group(&dev->kobj, &vsync_fs_attr_group); if (rc) { pr_err("vsync sysfs group creation failed, ret=%d\n", rc); goto init_done; } kobject_uevent(&dev->kobj, KOBJ_ADD); pr_debug("vsync kobject_uevent(KOBJ_ADD)\n"); init_done: if (IS_ERR_VALUE(rc)) kfree(mdp3_session); return rc; }
static int __devinit omap_temp_sensor_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data; struct omap_temp_sensor *temp_sensor; struct resource *mem; int ret = 0, val; if (!pdata) { dev_err(&pdev->dev, "%s: platform data missing\n", __func__); return -EINVAL; } temp_sensor = kzalloc(sizeof(struct omap_temp_sensor), GFP_KERNEL); if (!temp_sensor) return -ENOMEM; spin_lock_init(&temp_sensor->lock); mutex_init(&temp_sensor->sensor_mutex); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "%s:no mem resource\n", __func__); ret = -EINVAL; goto plat_res_err; } temp_sensor->irq = platform_get_irq_byname(pdev, "thermal_alert"); if (temp_sensor->irq < 0) { dev_err(&pdev->dev, "%s:Cannot get thermal alert irq\n", __func__); ret = -EINVAL; goto get_irq_err; } ret = gpio_request_one(OMAP_TSHUT_GPIO, GPIOF_DIR_IN, "thermal_shutdown"); if (ret) { dev_err(&pdev->dev, "%s: Could not get tshut_gpio\n", __func__); goto tshut_gpio_req_err; } temp_sensor->tshut_irq = gpio_to_irq(OMAP_TSHUT_GPIO); if (temp_sensor->tshut_irq < 0) { dev_err(&pdev->dev, "%s:Cannot get thermal shutdown irq\n", __func__); ret = -EINVAL; goto get_tshut_irq_err; } temp_sensor->phy_base = pdata->offset; temp_sensor->pdev = pdev; temp_sensor->dev = dev; pm_runtime_enable(dev); pm_runtime_irq_safe(dev); kobject_uevent(&pdev->dev.kobj, KOBJ_ADD); platform_set_drvdata(pdev, temp_sensor); /* * check if the efuse has a non-zero value if not * it is an untrimmed sample and the temperatures * may not be accurate */ if (omap_readl(OMAP4_CTRL_MODULE_CORE + OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP)) temp_sensor->is_efuse_valid = 1; temp_sensor->clock = clk_get(&temp_sensor->pdev->dev, "fck"); if (IS_ERR(temp_sensor->clock)) { ret = PTR_ERR(temp_sensor->clock); pr_err("%s:Unable to get fclk: %d\n", __func__, ret); ret = -EINVAL; goto clk_get_err; } ret = omap_temp_sensor_enable(temp_sensor); if (ret) { dev_err(&pdev->dev, "%s:Cannot enable temp sensor\n", __func__); goto sensor_enable_err; } temp_sensor->therm_fw = kzalloc(sizeof(struct thermal_dev), GFP_KERNEL); if (temp_sensor->therm_fw) { temp_sensor->therm_fw->name = "omap_ondie_sensor"; temp_sensor->therm_fw->domain_name = "cpu"; temp_sensor->therm_fw->dev = temp_sensor->dev; temp_sensor->therm_fw->dev_ops = &omap_sensor_ops; thermal_sensor_dev_register(temp_sensor->therm_fw); } else { dev_err(&pdev->dev, "%s:Cannot alloc memory for thermal fw\n", __func__); ret = -ENOMEM; goto therm_fw_alloc_err; } omap_enable_continuous_mode(temp_sensor, 1); omap_configure_temp_sensor_thresholds(temp_sensor); /* 1 ms */ omap_configure_temp_sensor_counter(temp_sensor, 1); /* Wait till the first conversion is done wait for at least 1ms */ mdelay(2); /* Read the temperature once due to hw issue*/ omap_report_temp(temp_sensor->therm_fw); /* Set 250 milli-seconds time as default counter */ omap_configure_temp_sensor_counter(temp_sensor, temp_sensor->clk_rate * 250 / 1000); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_sensor_group); if (ret) { dev_err(&pdev->dev, "could not create sysfs files\n"); goto sysfs_create_err; } ret = request_threaded_irq(temp_sensor->irq, NULL, omap_talert_irq_handler, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "temp_sensor", (void *)temp_sensor); if (ret) { dev_err(&pdev->dev, "Request threaded irq failed.\n"); goto req_irq_err; } ret = request_threaded_irq(temp_sensor->tshut_irq, NULL, omap_tshut_irq_handler, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "tshut", (void *)temp_sensor); if (ret) { dev_err(&pdev->dev, "Request threaded irq failed for TSHUT.\n"); goto tshut_irq_req_err; } /* unmask the T_COLD and unmask T_HOT at init */ val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); val |= OMAP4_MASK_COLD_MASK; val |= OMAP4_MASK_HOT_MASK; omap_temp_sensor_writel(temp_sensor, val, BGAP_CTRL_OFFSET); dev_info(&pdev->dev, "%s : '%s'\n", temp_sensor->therm_fw->name, pdata->name); temp_sensor_pm = temp_sensor; return 0; tshut_irq_req_err: free_irq(temp_sensor->irq, temp_sensor); req_irq_err: kobject_uevent(&temp_sensor->dev->kobj, KOBJ_REMOVE); sysfs_remove_group(&temp_sensor->dev->kobj, &omap_temp_sensor_group); sysfs_create_err: thermal_sensor_dev_unregister(temp_sensor->therm_fw); kfree(temp_sensor->therm_fw); if (temp_sensor->clock) clk_put(temp_sensor->clock); platform_set_drvdata(pdev, NULL); therm_fw_alloc_err: omap_temp_sensor_disable(temp_sensor); sensor_enable_err: clk_put(temp_sensor->clock); clk_get_err: pm_runtime_disable(&pdev->dev); get_tshut_irq_err: gpio_free(OMAP_TSHUT_GPIO); tshut_gpio_req_err: get_irq_err: plat_res_err: mutex_destroy(&temp_sensor->sensor_mutex); kfree(temp_sensor); return ret; }
int mdp3_ctrl_init(struct msm_fb_data_type *mfd) { struct device *dev = mfd->fbi->dev; struct msm_mdp_interface *mdp3_interface = &mfd->mdp; struct mdp3_session_data *mdp3_session = NULL; u32 intf_type = MDP3_DMA_OUTPUT_SEL_DSI_VIDEO; int rc; int splash_mismatch = 0; pr_debug("mdp3_ctrl_init\n"); rc = mdp3_parse_dt_splash(mfd); if (rc) splash_mismatch = 1; mdp3_interface->on_fnc = mdp3_ctrl_on; mdp3_interface->off_fnc = mdp3_ctrl_off; mdp3_interface->do_histogram = NULL; mdp3_interface->cursor_update = NULL; mdp3_interface->dma_fnc = mdp3_ctrl_pan_display; mdp3_interface->ioctl_handler = mdp3_ctrl_ioctl_handler; mdp3_interface->kickoff_fnc = mdp3_ctrl_display_commit_kickoff; mdp3_interface->lut_update = mdp3_ctrl_lut_update; mdp3_session = kmalloc(sizeof(struct mdp3_session_data), GFP_KERNEL); if (!mdp3_session) { pr_err("fail to allocate mdp3 private data structure"); return -ENOMEM; } memset(mdp3_session, 0, sizeof(struct mdp3_session_data)); mutex_init(&mdp3_session->lock); mutex_init(&mdp3_session->offlock); INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off); INIT_WORK(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done); atomic_set(&mdp3_session->vsync_countdown, 0); mutex_init(&mdp3_session->histo_lock); mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL); if (!mdp3_session->dma) { rc = -ENODEV; goto init_done; } rc = mdp3_dma_init(mdp3_session->dma); if (rc) { pr_err("fail to init dma\n"); goto init_done; } intf_type = mdp3_ctrl_get_intf_type(mfd); mdp3_session->intf = mdp3_get_display_intf(intf_type); if (!mdp3_session->intf) { rc = -ENODEV; goto init_done; } rc = mdp3_intf_init(mdp3_session->intf); if (rc) { pr_err("fail to init interface\n"); goto init_done; } mdp3_session->dma->output_config.out_sel = intf_type; mdp3_session->mfd = mfd; mdp3_session->panel = dev_get_platdata(&mfd->pdev->dev); mdp3_session->status = mdp3_session->intf->active; mdp3_session->overlay.id = MSMFB_NEW_REQUEST; mdp3_bufq_init(&mdp3_session->bufq_in); mdp3_bufq_init(&mdp3_session->bufq_out); mdp3_session->histo_status = 0; mdp3_session->lut_sel = 0; BLOCKING_INIT_NOTIFIER_HEAD(&mdp3_session->notifier_head); init_timer(&mdp3_session->vsync_timer); mdp3_session->vsync_timer.function = mdp3_vsync_timer_func; mdp3_session->vsync_timer.data = (u32)mdp3_session; mdp3_session->vsync_period = 1000 / mfd->panel_info->mipi.frame_rate; mfd->mdp.private1 = mdp3_session; rc = sysfs_create_group(&dev->kobj, &vsync_fs_attr_group); if (rc) { pr_err("vsync sysfs group creation failed, ret=%d\n", rc); goto init_done; } mdp3_session->vsync_event_sd = sysfs_get_dirent(dev->kobj.sd, NULL, "vsync_event"); if (!mdp3_session->vsync_event_sd) { pr_err("vsync_event sysfs lookup failed\n"); rc = -ENODEV; goto init_done; } rc = mdp3_create_sysfs_link(dev); if (rc) pr_warn("problem creating link to mdp sysfs\n"); kobject_uevent(&dev->kobj, KOBJ_ADD); pr_debug("vsync kobject_uevent(KOBJ_ADD)\n"); if (mdp3_get_cont_spash_en()) { mdp3_session->clk_on = 1; mdp3_ctrl_notifier_register(mdp3_session, &mdp3_session->mfd->mdp_sync_pt_data.notifier); } if (splash_mismatch) { pr_err("splash memory mismatch, stop splash\n"); mdp3_ctrl_off(mfd); } mdp3_session->vsync_before_commit = true; init_done: if (IS_ERR_VALUE(rc)) kfree(mdp3_session); return rc; }
/* * Helper function for ibft_register_kobjects. */ static int __init ibft_create_kobject(struct ibft_table_header *header, struct ibft_hdr *hdr, struct list_head *list) { struct ibft_kobject *ibft_kobj = NULL; struct ibft_nic *nic = (struct ibft_nic *)hdr; struct pci_dev *pci_dev; int rc = 0; ibft_kobj = kzalloc(sizeof(*ibft_kobj), GFP_KERNEL); if (!ibft_kobj) return -ENOMEM; ibft_kobj->header = header; ibft_kobj->hdr = hdr; switch (hdr->id) { case id_initiator: rc = ibft_verify_hdr("initiator", hdr, id_initiator, sizeof(*ibft_kobj->initiator)); break; case id_nic: rc = ibft_verify_hdr("ethernet", hdr, id_nic, sizeof(*ibft_kobj->nic)); break; case id_target: rc = ibft_verify_hdr("target", hdr, id_target, sizeof(*ibft_kobj->tgt)); break; case id_reserved: case id_control: case id_extensions: /* Fields which we don't support. Ignore them */ rc = 1; break; default: printk(KERN_ERR "iBFT has unknown structure type (%d). " \ "Report this bug to %.6s!\n", hdr->id, header->oem_id); rc = 1; break; } if (rc) { /* Skip adding this kobject, but exit with non-fatal error. */ kfree(ibft_kobj); goto out_invalid_struct; } ibft_kobj->kobj.kset = ibft_kset; rc = kobject_init_and_add(&ibft_kobj->kobj, &ibft_ktype, NULL, ibft_id_names[hdr->id], hdr->index); if (rc) { kfree(ibft_kobj); goto out; } kobject_uevent(&ibft_kobj->kobj, KOBJ_ADD); if (hdr->id == id_nic) { /* * We don't search for the device in other domains than * zero. This is because on x86 platforms the BIOS * executes only devices which are in domain 0. Furthermore, the * iBFT spec doesn't have a domain id field :-( */ pci_dev = pci_get_bus_and_slot((nic->pci_bdf & 0xff00) >> 8, (nic->pci_bdf & 0xff)); if (pci_dev) { rc = sysfs_create_link(&ibft_kobj->kobj, &pci_dev->dev.kobj, "device"); pci_dev_put(pci_dev); } }
int blk_register_queue(struct gendisk *disk) { int ret; struct device *dev = disk_to_dev(disk); struct request_queue *q = disk->queue; if (WARN_ON(!q)) return -ENXIO; WARN_ONCE(test_bit(QUEUE_FLAG_REGISTERED, &q->queue_flags), "%s is registering an already registered queue\n", kobject_name(&dev->kobj)); queue_flag_set_unlocked(QUEUE_FLAG_REGISTERED, q); /* * SCSI probing may synchronously create and destroy a lot of * request_queues for non-existent devices. Shutting down a fully * functional queue takes measureable wallclock time as RCU grace * periods are involved. To avoid excessive latency in these * cases, a request_queue starts out in a degraded mode which is * faster to shut down and is made fully functional here as * request_queues for non-existent devices never get registered. */ if (!blk_queue_init_done(q)) { queue_flag_set_unlocked(QUEUE_FLAG_INIT_DONE, q); percpu_ref_switch_to_percpu(&q->q_usage_counter); blk_queue_bypass_end(q); } ret = blk_trace_init_sysfs(dev); if (ret) return ret; /* Prevent changes through sysfs until registration is completed. */ mutex_lock(&q->sysfs_lock); ret = kobject_add(&q->kobj, kobject_get(&dev->kobj), "%s", "queue"); if (ret < 0) { blk_trace_remove_sysfs(dev); goto unlock; } if (q->mq_ops) { __blk_mq_register_dev(dev, q); blk_mq_debugfs_register(q); } kobject_uevent(&q->kobj, KOBJ_ADD); wbt_enable_default(q); blk_throtl_register_queue(q); if (q->request_fn || (q->mq_ops && q->elevator)) { ret = elv_register_queue(q); if (ret) { kobject_uevent(&q->kobj, KOBJ_REMOVE); kobject_del(&q->kobj); blk_trace_remove_sysfs(dev); kobject_put(&dev->kobj); goto unlock; } } ret = 0; unlock: mutex_unlock(&q->sysfs_lock); return ret; }
static void dm_CheckPbcGPIO(_adapter *padapter) { u8 tmp1byte; u8 bPbcPressed = _FALSE; if(!padapter->registrypriv.hw_wps_pbc) return; #ifdef CONFIG_USB_HCI tmp1byte = rtw_read8(padapter, GPIO_IO_SEL); tmp1byte |= (HAL_8192C_HW_GPIO_WPS_BIT); rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); //enable GPIO[2] as output mode tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT); rtw_write8(padapter, GPIO_IN, tmp1byte); //reset the floating voltage level tmp1byte = rtw_read8(padapter, GPIO_IO_SEL); tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT); rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); //enable GPIO[2] as input mode tmp1byte =rtw_read8(padapter, GPIO_IN); if (tmp1byte == 0xff) return ; if (tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT) { bPbcPressed = _TRUE; } #else tmp1byte = rtw_read8(padapter, GPIO_IN); //RT_TRACE(COMP_IO, DBG_TRACE, ("dm_CheckPbcGPIO - %x\n", tmp1byte)); if (tmp1byte == 0xff || padapter->init_adpt_in_progress) return ; if((tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT)==0) { bPbcPressed = _TRUE; } #endif if( _TRUE == bPbcPressed) { // Here we only set bPbcPressed to true // After trigger PBC, the variable will be set to false DBG_8192C("CheckPbcGPIO - PBC is pressed\n"); #ifdef RTK_DMP_PLATFORM #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)) kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_NET_PBC); #else kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_NET_PBC); #endif #else if ( padapter->pid[0] == 0 ) { // 0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver. return; } #ifdef PLATFORM_LINUX rtw_signal_process(padapter->pid[0], SIGUSR1); #endif #endif } }
static int hi6620_tsensor_probe(struct platform_device *pdev) { struct tsensor_devinfo *devinfo = NULL; int ret = 0; printk(KERN_INFO "hi6620_tsensor_probe\n"); /*全局变量初始化 */ tsensor_gov = kzalloc(sizeof(struct tsensor_governor), GFP_KERNEL); if (!tsensor_gov) { printk(KERN_ERR "hi6620_tsensor_probe kzalloc failed\n"); pr_err("%s:Cannot allocate memory\n", __func__); return -ENOMEM; } devinfo = kzalloc(sizeof(struct tsensor_devinfo), GFP_KERNEL); if (!devinfo) { printk(KERN_ERR "hi6620_tsensor_probe kzalloc failed111\n"); pr_err("%s:Cannot allocate memory\n", __func__); goto probe_err; } devinfo->pdev = pdev; devinfo->dev = &pdev->dev; kobject_uevent(&pdev->dev.kobj, KOBJ_ADD); platform_set_drvdata(pdev, devinfo); /*创建sysfs节点 */ ret = sysfs_create_group(&pdev->dev.kobj, &tsensor_group); if (ret) { printk(KERN_ERR "hi6620_tsensor_probe sysfs_create_group failed\n"); dev_err(&pdev->dev, "could not create sysfs files\n"); goto probe_err; } /* Init delayed work to monitor tsensor temperature */ INIT_DELAYED_WORK(&tsensor_gov->tsensor_monitor_work, tsensor_monitor_work_fn); tsensor_gov->average_period = TSENSOR_NORMAL_MONITORING_RATE; mutex_init(&(tsensor_gov->lock)); register_reboot_notifier(&tsensor_reboot_nb); /*printk(KERN_ERR "before tsensor_init\n");*/ /*tsensor初始化,AC核解耦后,该调用放到modem_init.c中,因为要使用邮箱和C核NV,需保证C核初始化完成*/ /*ret = tsensor_init(); if (ret != 0) { dev_err(&pdev->dev, "tsensor_init\n"); goto probe_err; }*/ printk(KERN_INFO "hi6620_tsensor_probe probe success\n"); return ret; probe_err: platform_set_drvdata(pdev, NULL); if (devinfo) { kfree(devinfo); devinfo = NULL; } if (tsensor_gov) { kfree(tsensor_gov); tsensor_gov = NULL; } return ret; }
static void work_handler(struct work_struct * not_used) { kobject_uevent(&recovery_button_driver.recovery_button, KOBJ_OFFLINE); }
static int pm8058_tz_get_temp(struct thermal_zone_device *thermal, unsigned long *temp) { struct pm8058_tm_device *tm = thermal->devdata; DECLARE_COMPLETION_ONSTACK(wait); struct adc_chan_result adc_result = { .physical = 0lu, }; int rc; if (!tm || !temp) return -EINVAL; *temp = tm->temp; rc = adc_channel_request_conv(tm->adc_handle, &wait); if (rc < 0) { pr_err("%s: adc_channel_request_conv() failed, rc = %d\n", __func__, rc); return rc; } wait_for_completion(&wait); rc = adc_channel_read_result(tm->adc_handle, &adc_result); if (rc < 0) { pr_err("%s: adc_channel_read_result() failed, rc = %d\n", __func__, rc); return rc; } *temp = adc_result.physical; tm->temp = adc_result.physical; return 0; } static int pm8058_tz_get_mode(struct thermal_zone_device *thermal, enum thermal_device_mode *mode) { struct pm8058_tm_device *tm = thermal->devdata; if (!tm || !mode) return -EINVAL; *mode = tm->mode; return 0; } static int pm8058_tz_set_mode(struct thermal_zone_device *thermal, enum thermal_device_mode mode) { struct pm8058_tm_device *tm = thermal->devdata; if (!tm) return -EINVAL; if (mode != tm->mode) { if (mode == THERMAL_DEVICE_ENABLED) pm8058_tm_shutdown_override(tm->pm_chip, SOFTWARE_OVERRIDE_ENABLED); else pm8058_tm_shutdown_override(tm->pm_chip, SOFTWARE_OVERRIDE_DISABLED); } tm->mode = mode; return 0; } static int pm8058_tz_get_trip_type(struct thermal_zone_device *thermal, int trip, enum thermal_trip_type *type) { struct pm8058_tm_device *tm = thermal->devdata; if (!tm || trip < 0 || !type) return -EINVAL; switch (trip) { case PM8058_TRIP_STAGE3: *type = THERMAL_TRIP_CRITICAL; break; case PM8058_TRIP_STAGE2: *type = THERMAL_TRIP_HOT; break; case PM8058_TRIP_STAGE1: *type = THERMAL_TRIP_HOT; break; default: return -EINVAL; } return 0; } static int pm8058_tz_get_trip_temp(struct thermal_zone_device *thermal, int trip, unsigned long *temp) { struct pm8058_tm_device *tm = thermal->devdata; int thresh_temp; if (!tm || trip < 0 || !temp) return -EINVAL; thresh_temp = tm->thresh * PM8058_TEMP_THRESH_STEP + PM8058_TEMP_THRESH_MIN; switch (trip) { case PM8058_TRIP_STAGE3: thresh_temp += 2 * PM8058_TEMP_STAGE_STEP; break; case PM8058_TRIP_STAGE2: thresh_temp += PM8058_TEMP_STAGE_STEP; break; case PM8058_TRIP_STAGE1: break; default: return -EINVAL; } *temp = thresh_temp; return 0; } static int pm8058_tz_get_crit_temp(struct thermal_zone_device *thermal, unsigned long *temp) { struct pm8058_tm_device *tm = thermal->devdata; if (!tm || !temp) return -EINVAL; *temp = tm->thresh * PM8058_TEMP_THRESH_STEP + PM8058_TEMP_THRESH_MIN + 2 * PM8058_TEMP_STAGE_STEP; return 0; } static struct thermal_zone_device_ops pm8058_thermal_zone_ops = { .get_temp = pm8058_tz_get_temp, .get_mode = pm8058_tz_get_mode, .set_mode = pm8058_tz_set_mode, .get_trip_type = pm8058_tz_get_trip_type, .get_trip_temp = pm8058_tz_get_trip_temp, .get_crit_temp = pm8058_tz_get_crit_temp, }; static irqreturn_t pm8058_tm_isr(int irq, void *data) { struct pm8058_tm_device *tm = data; int rc; u8 reg; rc = pm8058_tm_read_ctrl(tm->pm_chip, ®); if (rc < 0) goto isr_handled; tm->stage = (reg & PM8058_TEMP_STATUS_MASK) >> PM8058_TEMP_STATUS_SHIFT; tm->thresh = (reg & PM8058_TEMP_THRESH_MASK) >> PM8058_TEMP_THRESH_SHIFT; if (reg & (PM8058_TEMP_ST2_SD | PM8058_TEMP_ST3_SD)) { reg &= ~(PM8058_TEMP_ST2_SD | PM8058_TEMP_ST3_SD | PM8058_TEMP_STATUS_MASK); pm8058_tm_write_ctrl(tm->pm_chip, reg); } thermal_zone_device_update(tm->tz_dev); /* Notify user space */ if (tm->mode == THERMAL_DEVICE_ENABLED) kobject_uevent(&tm->tz_dev->device.kobj, KOBJ_CHANGE); isr_handled: return IRQ_HANDLED; } static int pm8058_tm_init_reg(struct pm8058_tm_device *tm) { int rc; u8 reg; rc = pm8058_tm_read_ctrl(tm->pm_chip, ®); if (rc < 0) return rc; tm->stage = (reg & PM8058_TEMP_STATUS_MASK) >> PM8058_TEMP_STATUS_SHIFT; tm->temp = 0; /* Use temperature threshold set 0: (105, 125, 145) */ tm->thresh = 0; reg = (tm->thresh << PM8058_TEMP_THRESH_SHIFT) & PM8058_TEMP_THRESH_MASK; rc = pm8058_tm_write_ctrl(tm->pm_chip, reg); if (rc < 0) return rc; /* * Set the PMIC alarm module PWM to have a frequency of 8 Hz. This * helps cut down on the number of unnecessary interrupts fired when * changing between thermal stages. Also, Enable the over temperature * PWM whenever the PMIC is enabled. */ reg = 1 << PM8058_TEMP_PWM_EN_SHIFT | 3 << PM8058_TEMP_PWM_PER_PRE_SHIFT | 3 << PM8058_TEMP_PWM_PER_DIV_SHIFT; rc = pm8058_tm_write_pwm(tm->pm_chip, reg); return rc; }
static int __devinit pcb_temp_sensor_probe(struct platform_device *pdev) { struct pcb_temp_sensor_pdata *pdata = pdev->dev.platform_data; struct pcb_temp_sensor *temp_sensor; int ret = 0; if (!pdata) { dev_err(&pdev->dev, "%s: platform data missing\n", __func__); return -EINVAL; } temp_sensor = kzalloc(sizeof(struct pcb_temp_sensor), GFP_KERNEL); if (!temp_sensor) return -ENOMEM; /* Init delayed work for PCB sensor temperature */ INIT_DELAYED_WORK(&temp_sensor->pcb_sensor_work, pcb_sensor_delayed_work_fn); spin_lock_init(&temp_sensor->lock); mutex_init(&temp_sensor->sensor_mutex); temp_sensor->pdev = pdev; temp_sensor->dev = &pdev->dev; kobject_uevent(&pdev->dev.kobj, KOBJ_ADD); platform_set_drvdata(pdev, temp_sensor); temp_sensor->therm_fw = kzalloc(sizeof(struct thermal_dev), GFP_KERNEL); if (temp_sensor->therm_fw) { temp_sensor->therm_fw->name = "pcb_sensor"; temp_sensor->therm_fw->domain_name = "cpu"; temp_sensor->therm_fw->dev = temp_sensor->dev; temp_sensor->therm_fw->dev_ops = &pcb_sensor_ops; thermal_sensor_dev_register(temp_sensor->therm_fw); } else { dev_err(&pdev->dev, "%s:Cannot alloc memory for thermal fw\n", __func__); ret = -ENOMEM; goto therm_fw_alloc_err; } ret = sysfs_create_group(&pdev->dev.kobj, &pcb_temp_sensor_group); if (ret) { dev_err(&pdev->dev, "could not create sysfs files\n"); goto sysfs_create_err; } temp_sensor->work_delay = PCB_REPORT_DELAY_MS; schedule_delayed_work(&temp_sensor->pcb_sensor_work, msecs_to_jiffies(0)); dev_info(&pdev->dev, "%s : '%s'\n", temp_sensor->therm_fw->name, pdata->name); return 0; sysfs_create_err: thermal_sensor_dev_unregister(temp_sensor->therm_fw); kfree(temp_sensor->therm_fw); platform_set_drvdata(pdev, NULL); therm_fw_alloc_err: mutex_destroy(&temp_sensor->sensor_mutex); kfree(temp_sensor); return ret; }
static int init_rq_attribs(void) { int i; int err = 0; const int attr_count = 4; struct attribute **attribs = kzalloc(sizeof(struct attribute *) * attr_count, GFP_KERNEL); if (!attribs) { pr_err("%s: Allocate attribs failed!\n", __func__); goto rel; } rq_info.rq_avg = 0; attribs[0] = MSM_RQ_STATS_RW_ATTRIB(def_timer_ms); attribs[1] = MSM_RQ_STATS_RO_ATTRIB(run_queue_avg); attribs[2] = MSM_RQ_STATS_RW_ATTRIB(run_queue_poll_ms); attribs[3] = NULL; for (i = 0; i < attr_count - 1 ; i++) { if (!attribs[i]) { pr_err("%s: Allocate attribs[%d] failed!\n", __func__, i); goto rel2; } } rq_info.attr_group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL); if (!rq_info.attr_group) { pr_err("%s: Allocate rq_info.attr_group failed!\n", __func__); goto rel3; } rq_info.attr_group->attrs = attribs; /* Create /sys/devices/system/cpu/cpu0/rq-stats/... */ rq_info.kobj = kobject_create_and_add("rq-stats", &get_cpu_sysdev(0)->kobj); if (!rq_info.kobj) { pr_err("%s: Create rq_info.kobj failed!\n", __func__); goto rel3; } err = sysfs_create_group(rq_info.kobj, rq_info.attr_group); if (err) kobject_put(rq_info.kobj); else kobject_uevent(rq_info.kobj, KOBJ_ADD); if (!err) { pr_info("%s: Initialize done.\n", __func__); init_done = 1; return err; } rel3: kfree(rq_info.attr_group); kfree(rq_info.kobj); rel2: for (i = 0; i < attr_count - 1; i++) kfree(attribs[i]); rel: kfree(attribs); return -ENOMEM; }
static ssize_t boot_acl_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct tb *tb = container_of(dev, struct tb, dev); char *str, *s, *uuid_str; ssize_t ret = 0; uuid_t *acl; int i = 0; /* * Make sure the value is not bigger than tb->nboot_acl * UUID * length + commas and optional "\n". Also the smallest allowable * string is tb->nboot_acl * ",". */ if (count > (UUID_STRING_LEN + 1) * tb->nboot_acl + 1) return -EINVAL; if (count < tb->nboot_acl - 1) return -EINVAL; str = kstrdup(buf, GFP_KERNEL); if (!str) return -ENOMEM; acl = kcalloc(tb->nboot_acl, sizeof(uuid_t), GFP_KERNEL); if (!acl) { ret = -ENOMEM; goto err_free_str; } uuid_str = strim(str); while ((s = strsep(&uuid_str, ",")) != NULL && i < tb->nboot_acl) { size_t len = strlen(s); if (len) { if (len != UUID_STRING_LEN) { ret = -EINVAL; goto err_free_acl; } ret = uuid_parse(s, &acl[i]); if (ret) goto err_free_acl; } i++; } if (s || i < tb->nboot_acl) { ret = -EINVAL; goto err_free_acl; } pm_runtime_get_sync(&tb->dev); if (mutex_lock_interruptible(&tb->lock)) { ret = -ERESTARTSYS; goto err_rpm_put; } ret = tb->cm_ops->set_boot_acl(tb, acl, tb->nboot_acl); if (!ret) { /* Notify userspace about the change */ kobject_uevent(&tb->dev.kobj, KOBJ_CHANGE); } mutex_unlock(&tb->lock); err_rpm_put: pm_runtime_mark_last_busy(&tb->dev); pm_runtime_put_autosuspend(&tb->dev); err_free_acl: kfree(acl); err_free_str: kfree(str); return ret ?: count; }