]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/gpu/vga/vga_switcheroo.c
vga_switcheroo: add reprobe hook for fbcon to recheck connected outputs.
[mv-sheeva.git] / drivers / gpu / vga / vga_switcheroo.c
index c8768f38511e823afb863b88e8a55db9246fa929..2b8e1d25e8d00c5d6d6762ff712fe7168295fdf5 100644 (file)
@@ -33,6 +33,7 @@ struct vga_switcheroo_client {
        struct fb_info *fb_info;
        int pwr_state;
        void (*set_gpu_state)(struct pci_dev *pdev, enum vga_switcheroo_state);
+       void (*reprobe)(struct pci_dev *pdev);
        bool (*can_switch)(struct pci_dev *pdev);
        int id;
        bool active;
@@ -103,6 +104,7 @@ static void vga_switcheroo_enable(void)
 
 int vga_switcheroo_register_client(struct pci_dev *pdev,
                                   void (*set_gpu_state)(struct pci_dev *pdev, enum vga_switcheroo_state),
+                                  void (*reprobe)(struct pci_dev *pdev),
                                   bool (*can_switch)(struct pci_dev *pdev))
 {
        int index;
@@ -117,6 +119,7 @@ int vga_switcheroo_register_client(struct pci_dev *pdev,
        vgasr_priv.clients[index].pwr_state = VGA_SWITCHEROO_ON;
        vgasr_priv.clients[index].pdev = pdev;
        vgasr_priv.clients[index].set_gpu_state = set_gpu_state;
+       vgasr_priv.clients[index].reprobe = reprobe;
        vgasr_priv.clients[index].can_switch = can_switch;
        vgasr_priv.clients[index].id = -1;
        if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
@@ -174,7 +177,8 @@ static int vga_switcheroo_show(struct seq_file *m, void *v)
        int i;
        mutex_lock(&vgasr_mutex);
        for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
-               seq_printf(m, "%d:%c:%s:%s\n", i,
+               seq_printf(m, "%d:%s:%c:%s:%s\n", i,
+                          vgasr_priv.clients[i].id == VGA_SWITCHEROO_DIS ? "DIS" : "IGD",
                           vgasr_priv.clients[i].active ? '+' : ' ',
                           vgasr_priv.clients[i].pwr_state ? "Pwr" : "Off",
                           pci_name(vgasr_priv.clients[i].pdev));
@@ -190,9 +194,8 @@ static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)
 
 static int vga_switchon(struct vga_switcheroo_client *client)
 {
-       int ret;
-
-       ret = vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
+       if (vgasr_priv.handler->power_state)
+               vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
        /* call the driver callback to turn on device */
        client->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
        client->pwr_state = VGA_SWITCHEROO_ON;
@@ -203,7 +206,8 @@ static int vga_switchoff(struct vga_switcheroo_client *client)
 {
        /* call the driver callback to turn off device */
        client->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
-       vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
+       if (vgasr_priv.handler->power_state)
+               vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
        client->pwr_state = VGA_SWITCHEROO_OFF;
        return 0;
 }
@@ -250,6 +254,9 @@ static int vga_switchto(struct vga_switcheroo_client *new_client)
        if (ret)
                return ret;
 
+       if (new_client->reprobe)
+               new_client->reprobe(new_client->pdev);
+
        if (active->pwr_state == VGA_SWITCHEROO_ON)
                vga_switchoff(active);
 
@@ -265,6 +272,7 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
        const char *pdev_name;
        int i, ret;
        bool delay = false, can_switch;
+       bool just_mux = false;
        int client_id = -1;
        struct vga_switcheroo_client *client = NULL;
 
@@ -319,6 +327,15 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
        if (strncmp(usercmd, "DIS", 3) == 0)
                client_id = VGA_SWITCHEROO_DIS;
 
+       if (strncmp(usercmd, "MIGD", 3) == 0) {
+               just_mux = true;
+               client_id = VGA_SWITCHEROO_IGD;
+       }
+       if (strncmp(usercmd, "MDIS", 3) == 0) {
+               just_mux = true;
+               client_id = VGA_SWITCHEROO_DIS;
+       }
+
        if (client_id == -1)
                goto out;
 
@@ -330,6 +347,12 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
        }
 
        vgasr_priv.delayed_switch_active = false;
+
+       if (just_mux) {
+               ret = vgasr_priv.handler->switchto(client_id);
+               goto out;
+       }
+
        /* okay we want a switch - test if devices are willing to switch */
        can_switch = true;
        for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {