vserver 1.9.5.x5
[linux-2.6.git] / drivers / pcmcia / yenta_socket.c
index d6974a1..9fae06a 100644 (file)
@@ -28,6 +28,9 @@
 #include "yenta_socket.h"
 #include "i82365.h"
 
+static int disable_clkrun;
+module_param(disable_clkrun, bool, 0444);
+MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option");
 
 #if 0
 #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
 static int yenta_probe_cb_irq(struct yenta_socket *socket);
 
 
+static unsigned int override_bios;
+module_param(override_bios, uint, 0000);
+MODULE_PARM_DESC (override_bios, "yenta ignore bios resource allocation");
+
 /*
  * Generate easy-to-use ways of reading a cardbus sockets
  * regular memory space ("cb_xxx"), configuration space
@@ -551,7 +558,7 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
 
        start = config_readl(socket, offset) & mask;
        end = config_readl(socket, offset+4) | ~mask;
-       if (start && end > start) {
+       if (start && end > start && !override_bios) {
                res->start = start;
                res->end = end;
                if (request_resource(root, res) == 0)
@@ -653,6 +660,7 @@ static void yenta_close(struct pci_dev *dev)
        yenta_free_resources(sock);
 
        pci_release_regions(dev);
+       pci_disable_device(dev);
        pci_set_drvdata(dev, NULL);
 }
 
@@ -688,7 +696,7 @@ enum {
  * Different cardbus controllers have slightly different
  * initialization sequences etc details. List them here..
  */
-struct cardbus_type cardbus_type[] = {
+static struct cardbus_type cardbus_type[] = {
        [CARDBUS_TYPE_TI]       = {
                .override       = ti_override,
                .save_state     = ti_save_state,
@@ -827,8 +835,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
        cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
        cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
        
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(HZ/10);
+       msleep(100);
 
        /* disable interrupts */
        cb_writel(socket, CB_SOCKET_MASK, 0);
@@ -914,6 +921,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
 
        /* prepare pcmcia_socket */
        socket->socket.ops = &yenta_socket_operations;
+       socket->socket.resource_ops = &pccard_nonstatic_ops;
        socket->socket.dev.dev = &dev->dev;
        socket->socket.driver_data = socket;
        socket->socket.owner = THIS_MODULE;
@@ -1023,10 +1031,16 @@ static int yenta_dev_suspend (struct pci_dev *dev, u32 state)
                        socket->type->save_state(socket);
 
                /* FIXME: pci_save_state needs to have a better interface */
-               pci_save_state(dev, socket->saved_state);
-               pci_read_config_dword(dev, 16*4, &socket->saved_state[16]);
-               pci_read_config_dword(dev, 17*4, &socket->saved_state[17]);
-               pci_set_power_state(dev, 3);
+               pci_save_state(dev);
+               pci_read_config_dword(dev, 16*4, &socket->saved_state[0]);
+               pci_read_config_dword(dev, 17*4, &socket->saved_state[1]);
+
+               /*
+                * Some laptops (IBM T22) do not like us putting the Cardbus
+                * bridge into D3.  At a guess, some other laptop will
+                * probably require this, so leave it commented out for now.
+                */
+               /* pci_set_power_state(dev, 3); */
        }
 
        return ret;
@@ -1040,9 +1054,9 @@ static int yenta_dev_resume (struct pci_dev *dev)
        if (socket) {
                pci_set_power_state(dev, 0);
                /* FIXME: pci_restore_state needs to have a better interface */
-               pci_restore_state(dev, socket->saved_state);
-               pci_write_config_dword(dev, 16*4, socket->saved_state[16]);
-               pci_write_config_dword(dev, 17*4, socket->saved_state[17]);
+               pci_restore_state(dev);
+               pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
+               pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
 
                if (socket->type && socket->type->restore_state)
                        socket->type->restore_state(socket);