From: Jim Liu <jim....@intel.com> Add Hotplug Device's envent notification.
Signed-off-by: Jim Liu <jim....@intel.com> Signed-off-by: Hitesh K. Patel <hitesh.k.pa...@intel.com> --- drivers/staging/mrst/drv/mdfld_msic.c | 87 +++++++++++++++++++++++------ drivers/staging/mrst/drv/mdfld_msic.h | 1 + drivers/staging/mrst/drv/psb_drv.c | 18 ++++++ drivers/staging/mrst/drv/psb_drv.h | 1 + drivers/staging/mrst/drv/psb_hotplug.c | 19 ++++-- drivers/staging/mrst/drv/psb_intel_hdmi.c | 31 ++++++++--- drivers/staging/mrst/drv/psb_socket.c | 2 +- drivers/staging/mrst/drv/psb_umevents.c | 7 ++ drivers/staging/mrst/drv/psb_umevents.h | 2 + 9 files changed, 136 insertions(+), 32 deletions(-) diff --git a/drivers/staging/mrst/drv/mdfld_msic.c b/drivers/staging/mrst/drv/mdfld_msic.c index 6c904d1..c0fa4df 100644 --- a/drivers/staging/mrst/drv/mdfld_msic.c +++ b/drivers/staging/mrst/drv/mdfld_msic.c @@ -45,11 +45,61 @@ void mdfld_msic_init(struct mid_intel_hdmi_priv *p_hdmi_priv) } /** + * hpd_notify_um + */ +void hpd_notify_um (void) +{ + struct drm_device *dev = hdmi_priv ? hdmi_priv->dev : 0; + struct drm_psb_private *dev_priv = psb_priv(dev); + struct pci_dev *pdev = NULL; + struct device *ddev = NULL; + struct kobject *kobj = NULL; + + if (dev) + PSB_DEBUG_ENTRY("\n"); + + dev_priv->hdmi_done_reading_edid = false; + + /*find handle to drm kboject*/ + if(dev == NULL){ + DRM_ERROR("%s: dev == NULL. \n", __FUNCTION__); + return; + } + pdev = dev->pdev; + + if(pdev == NULL){ + DRM_ERROR("%s: pdev == NULL. \n", __FUNCTION__); + return; + } + ddev = &pdev->dev; + + if(ddev == NULL){ + DRM_ERROR("%s: ddev == NULL. \n", __FUNCTION__); + return; + } + kobj = &ddev->kobj; + + if(kobj == NULL){ + DRM_ERROR("%s: kobj == NULL. \n", __FUNCTION__); + return; + } + + if (dev_priv->psb_hotplug_state) { + DRM_INFO("%s: HPD interrupt. \n", __FUNCTION__); + psb_hotplug_notify_change_um("hpd_hdmi", dev_priv->psb_hotplug_state); + } else { + DRM_ERROR("%s: Hotplug comm layer isn't initialized! \n", __FUNCTION__); + } + + return; +} + +/** * msic_vreg_handler */ irqreturn_t msic_vreg_handler(int irq, void *dev_id) { -#ifdef CONFIG_X86_MRST + struct drm_device *dev = hdmi_priv ? hdmi_priv->dev : 0; u8 data = 0; /* Need to add lock later.*/ @@ -58,26 +108,19 @@ irqreturn_t msic_vreg_handler(int irq, void *dev_id) if (sram_vreg_addr) data = readb(sram_vreg_addr); else - printk(KERN_INFO"%s: sram_vreg_addr = 0x%x. \n", __FUNCTION__, (u32) sram_vreg_addr); + DRM_ERROR("%s: sram_vreg_addr = 0x%x. \n", __FUNCTION__, (u32) sram_vreg_addr); - /* intel_scu_ipc_ioread8(MSIC_VRINT_STATUS, &data); */ - /* Clear VREG interrupt status register */ - /* intel_scu_ipc_iowrite8(MSIC_VRINT_STATUS, data); */ + if (dev) + PSB_DEBUG_ENTRY("data = 0x%x.\n", data); /* handle HDMI HPD interrupts. */ if (data & HDMI_HPD_STATUS) { - /* Read HPD signal status register */ - intel_scu_ipc_ioread8(MSIC_HDMI_STATUS, &data); - - if (data & HPD_SIGNAL_STATUS) { - printk(KERN_INFO"%s: HDMI is connected. data = 0x%x. \n", __FUNCTION__, data); - } else { - printk(KERN_INFO"%s: HDMI is disconnected. data = 0x%x. \n", __FUNCTION__, data); - } + DRM_INFO("%s: HPD interrupt. data = 0x%x. \n", __FUNCTION__, data); + hpd_notify_um(); } /* handle other msic vreq interrupts when necessary. */ -#endif + return IRQ_HANDLED; } @@ -102,11 +145,21 @@ static int __devinit msic_probe(struct pci_dev *pdev, sram_vreg_addr = ioremap_nocache(SRAM_MSIC_VRINT_ADDR, 0x2); ret = request_irq(pdev->irq, msic_vreg_handler, IRQF_SHARED, "msic_hdmi_driver",(void *)&hdmi_priv); } else - printk(KERN_INFO"%s: pciid = 0x%x is not msic_hdmi pciid. \n", __FUNCTION__, pdev->device); + DRM_ERROR("%s: pciid = 0x%x is not msic_hdmi pciid. \n", __FUNCTION__, pdev->device); if (!ret) { -#ifdef CONFIG_X86_MRST +#if 0 /* #ifdef CONFIG_X86_MRST may still be necessary*/ u8 data = 0; + + /* clear HDMI HPD */ + intel_scu_ipc_ioread8(MSIC_VRINT_STATUS, &data); + intel_scu_ipc_iowrite8(MSIC_VRINT_STATUS, data); + + /* clear MSIC first level VREG interrupt. */ + intel_scu_ipc_ioread8(MSIC_IRQLVL1_STATUS, &data); + data &= VREG_STATUS; + intel_scu_ipc_iowrite8(MSIC_IRQLVL1_STATUS, data); + /* enable HDMI HPD */ intel_scu_ipc_ioread8(MSIC_VRINT_MASK, &data); data &= ~HDMI_HPD_MASK; @@ -120,7 +173,7 @@ static int __devinit msic_probe(struct pci_dev *pdev, #endif } else { pci_dev_put(pdev); - printk(KERN_INFO"%s: request_irq failed. ret = 0x%x. \n", __FUNCTION__, ret); + DRM_ERROR("%s: request_irq failed. ret = 0x%x. \n", __FUNCTION__, ret); } } diff --git a/drivers/staging/mrst/drv/mdfld_msic.h b/drivers/staging/mrst/drv/mdfld_msic.h index f488346..e60f992 100644 --- a/drivers/staging/mrst/drv/mdfld_msic.h +++ b/drivers/staging/mrst/drv/mdfld_msic.h @@ -28,3 +28,4 @@ int msic_regsiter_driver(void); int msic_unregister_driver(void); +extern void hpd_notify_um (void); diff --git a/drivers/staging/mrst/drv/psb_drv.c b/drivers/staging/mrst/drv/psb_drv.c index b496562..c106aec 100644 --- a/drivers/staging/mrst/drv/psb_drv.c +++ b/drivers/staging/mrst/drv/psb_drv.c @@ -1208,6 +1208,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) /*init DPST umcomm to NULL*/ dev_priv->psb_dpst_state = NULL; dev_priv->psb_hotplug_state = NULL; + dev_priv->hdmi_done_reading_edid = false; dev_priv->dev = dev; bdev = &dev_priv->bdev; @@ -1485,6 +1486,23 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (ret) return ret; + /* initialize HDMI Hotplug interrupt forwarding + * notifications for user mode + */ + if (IS_MDFLD(dev)) + { + struct pci_dev *pdev = NULL; + struct device *ddev = NULL; + struct kobject *kobj = NULL; + + /*find handle to drm kboject*/ + pdev = dev->pdev; + ddev = &pdev->dev; + kobj = &ddev->kobj; + + dev_priv->psb_hotplug_state = psb_hotplug_init(kobj); + } + /*enable runtime pm at last*/ pm_runtime_enable(&dev->pdev->dev); pm_runtime_set_active(&dev->pdev->dev); diff --git a/drivers/staging/mrst/drv/psb_drv.h b/drivers/staging/mrst/drv/psb_drv.h index 2b79282..8f92758 100644 --- a/drivers/staging/mrst/drv/psb_drv.h +++ b/drivers/staging/mrst/drv/psb_drv.h @@ -935,6 +935,7 @@ struct drm_psb_private { struct timer_list dsr_timer; bool dsi_device_ready; + bool hdmi_done_reading_edid; uint32_t tmds_clock_khz; had_event_call_back mdfld_had_event_callbacks; diff --git a/drivers/staging/mrst/drv/psb_hotplug.c b/drivers/staging/mrst/drv/psb_hotplug.c index 0e7f6d2..c35b4c4 100644 --- a/drivers/staging/mrst/drv/psb_hotplug.c +++ b/drivers/staging/mrst/drv/psb_hotplug.c @@ -191,10 +191,17 @@ struct hotplug_state *psb_hotplug_init(struct kobject *parent_kobj) { struct hotplug_state *state; state = kzalloc(sizeof(struct hotplug_state), GFP_KERNEL); + + if (!state) + return state; + state->list = NULL; state->list = psb_hotplug_device_pool_create_and_init( parent_kobj, state); + + psb_hotplug_create_and_notify_um("hpd_hdmi", state); + return state; } /** @@ -237,8 +244,8 @@ void psb_hotplug_dev_create_wq(struct work_struct *work) wq_data->dev_name_arry_rw_status [wq_data->dev_name_read] = DRM_HOTPLUG_READ_COMPLETE; - psb_umevent_notify - (wq_working_hotplug_disp_obj); + /* psb_umevent_notify + (wq_working_hotplug_disp_obj);*/ } wq_data->dev_name_read++; } @@ -255,8 +262,8 @@ void psb_hotplug_dev_create_wq(struct work_struct *work) wq_data->dev_name_arry_rw_status [wq_data->dev_name_read] = DRM_HOTPLUG_READ_COMPLETE; - psb_umevent_notify - (wq_working_hotplug_disp_obj); + /*psb_umevent_notify + (wq_working_hotplug_disp_obj);*/ } wq_data->dev_name_read++; } @@ -273,8 +280,8 @@ void psb_hotplug_dev_create_wq(struct work_struct *work) wq_data->dev_name_arry_rw_status [wq_data->dev_name_read] = DRM_HOTPLUG_READ_COMPLETE; - psb_umevent_notify - (wq_working_hotplug_disp_obj); + /*psb_umevent_notify + (wq_working_hotplug_disp_obj);*/ } wq_data->dev_name_read++; } diff --git a/drivers/staging/mrst/drv/psb_intel_hdmi.c b/drivers/staging/mrst/drv/psb_intel_hdmi.c index f024b6e..0c1b9df 100644 --- a/drivers/staging/mrst/drv/psb_intel_hdmi.c +++ b/drivers/staging/mrst/drv/psb_intel_hdmi.c @@ -582,6 +582,9 @@ static int mdfld_hdmi_create_eeld_packet(struct drm_connector *connector) static enum drm_connector_status mdfld_hdmi_edid_detect(struct drm_connector *connector) { + struct drm_device *dev = connector->dev; + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; struct psb_intel_output *output = to_psb_intel_output(connector); struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; struct edid *edid = NULL; @@ -648,6 +651,8 @@ mdfld_hdmi_edid_detect(struct drm_connector *connector) hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); mdfld_hdmi_create_eeld_packet(connector); } + + dev_priv->hdmi_done_reading_edid = true; } #endif return status; @@ -656,17 +661,27 @@ mdfld_hdmi_edid_detect(struct drm_connector *connector) static enum drm_connector_status mdfld_hdmi_detect(struct drm_connector *connector) { - PSB_DEBUG_ENTRY("\n"); +#ifdef CONFIG_X86_MRST + struct drm_device *dev = connector->dev; + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; + u8 data = 0; + + /* Check if monitor is attached to HDMI connector. */ + intel_scu_ipc_ioread8(MSIC_HDMI_STATUS, &data); + + if (data & HPD_SIGNAL_STATUS) { + DRM_INFO("%s: HPD connected data = 0x%x. \n", __FUNCTION__, data); -/* FIXME_HDMI_JLIU7 add a variable in priv data to track the HDMI HDP/connection status. Add a variable to check if an HDMI device is connected. if it is HDMI device, we neend to enable HDMI audio. */ -#if 0 /*FIXME_JLIU7 HDMI */ - struct psb_intel_output *intel_output = to_psb_intel_output(connector); - struct mid_intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; + if (dev_priv->hdmi_done_reading_edid) + return connector_status_connected; + else + return mdfld_hdmi_edid_detect(connector); - if(hdmi_priv->has_hdmi_sink && hdmi_priv->hdmi_device_connected) { - return mdfld_hdmi_edid_detect(connector); } else { - return connector_status_disconnected; + DRM_INFO("%s: HPD disconnected data = 0x%x. \n", __FUNCTION__, data); + return mdfld_hdmi_edid_detect(connector); /* Remove it later.*/ + /* return connector_status_disconnected; */ } #else return mdfld_hdmi_edid_detect(connector); diff --git a/drivers/staging/mrst/drv/psb_socket.c b/drivers/staging/mrst/drv/psb_socket.c index 75d6d03..60604ce 100644 --- a/drivers/staging/mrst/drv/psb_socket.c +++ b/drivers/staging/mrst/drv/psb_socket.c @@ -360,7 +360,7 @@ int __init psb_kobject_uevent_init(void) NULL, NULL, THIS_MODULE); */ uevent_sock = netlink_kernel_create(&init_net, NETLINK_PSB_KOBJECT_UEVENT, - 0x1, /* 3 is for hotplug & dpst */ + 0x3, /* 3 is for hotplug & dpst */ NULL, NULL, THIS_MODULE); if (!uevent_sock) { diff --git a/drivers/staging/mrst/drv/psb_umevents.c b/drivers/staging/mrst/drv/psb_umevents.c index 9b66863..86396b7 100644 --- a/drivers/staging/mrst/drv/psb_umevents.c +++ b/drivers/staging/mrst/drv/psb_umevents.c @@ -242,6 +242,13 @@ void psb_umevent_notify(struct umevent_obj *notify_disp_obj) kobject_uevent(¬ify_disp_obj->kobj, KOBJ_ADD); } /*EXPORT_SYMBOL(psb_umevent_notify); */ + +void psb_umevent_notify_gfxsock(struct umevent_obj *notify_disp_obj, + int dst_group_id) +{ + psb_kobject_uevent(¬ify_disp_obj->kobj, KOBJ_ADD, dst_group_id); +} +/*EXPORT_SYMBOL(psb_umevent_notify_gfxsock);*/ /** * psb_umevent_notify_change - notify user mode of a change to a device * diff --git a/drivers/staging/mrst/drv/psb_umevents.h b/drivers/staging/mrst/drv/psb_umevents.h index 6d4f0af..80651a2 100644 --- a/drivers/staging/mrst/drv/psb_umevents.h +++ b/drivers/staging/mrst/drv/psb_umevents.h @@ -125,6 +125,8 @@ extern void psb_umevent_add_to_list(struct umevent_list *list, extern void psb_umevent_destroy_list(struct umevent_list *list); extern struct umevent_list *psb_umevent_create_list(void); extern void psb_umevent_notify(struct umevent_obj *notify_disp_obj); +extern void psb_umevent_notify_gfxsock(struct umevent_obj *notify_disp_obj, + int dst_group_id); extern void psb_umevent_obj_release(struct kobject *kobj); extern void psb_umevent_remove_from_list(struct umevent_list *list, const char *disp_to_remove); -- 1.7.1 _______________________________________________ MeeGo-kernel mailing list MeeGo-kernel@lists.meego.com http://lists.meego.com/listinfo/meego-kernel