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(&notify_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(&notify_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

Reply via email to