summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/Makefile1
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c1
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c1
-rw-r--r--drivers/pcmcia/ds.c3
-rw-r--r--drivers/pcmcia/o2micro.h4
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c38
-rw-r--r--drivers/pcmcia/pcmcia_resource.c6
-rw-r--r--drivers/pcmcia/pxa2xx_base.c18
-rw-r--r--drivers/pcmcia/pxa2xx_palmtc.c230
-rw-r--r--drivers/pcmcia/sa1100_jornada720.c156
-rw-r--r--drivers/pcmcia/yenta_socket.c18
11 files changed, 365 insertions, 111 deletions
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 047394d98ac2..3247828aa203 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -71,6 +71,7 @@ pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o
pxa2xx-obj-$(CONFIG_ARCH_VIPER) += pxa2xx_viper.o
pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps4.o
pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
+pxa2xx-obj-$(CONFIG_MACH_PALMTC) += pxa2xx_palmtc.o
pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o
pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o
pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index d6b4bd1db7d7..b1984ed72d1d 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -26,7 +26,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
-#include <linux/tqueue.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index 9627390835ca..b43d47b50819 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -30,7 +30,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
-#include <linux/tqueue.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 304ff6d5cf3b..9f300d3cb125 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -236,7 +236,6 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count)
if (!dynid)
return -ENOMEM;
- INIT_LIST_HEAD(&dynid->node);
dynid->id.match_flags = match_flags;
dynid->id.manf_id = manf_id;
dynid->id.card_id = card_id;
@@ -246,7 +245,7 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count)
memcpy(dynid->id.prod_id_hash, prod_id_hash, sizeof(__u32) * 4);
spin_lock(&pdrv->dynids.lock);
- list_add_tail(&pdrv->dynids.list, &dynid->node);
+ list_add_tail(&dynid->node, &pdrv->dynids.list);
spin_unlock(&pdrv->dynids.lock);
if (get_driver(&pdrv->drv)) {
diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h
index 5554015a7813..72188c462c9c 100644
--- a/drivers/pcmcia/o2micro.h
+++ b/drivers/pcmcia/o2micro.h
@@ -48,6 +48,9 @@
#ifndef PCI_DEVICE_ID_O2_6812
#define PCI_DEVICE_ID_O2_6812 0x6872
#endif
+#ifndef PCI_DEVICE_ID_O2_6933
+#define PCI_DEVICE_ID_O2_6933 0x6933
+#endif
/* Additional PCI configuration registers */
@@ -154,6 +157,7 @@ static int o2micro_override(struct yenta_socket *socket)
case PCI_DEVICE_ID_O2_6812:
case PCI_DEVICE_ID_O2_6832:
case PCI_DEVICE_ID_O2_6836:
+ case PCI_DEVICE_ID_O2_6933:
dev_printk(KERN_INFO, &socket->dev->dev,
"Yenta O2: old bridge, disabling read "
"prefetch/write burst\n");
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 6095f8daecd7..32c44040c1e8 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -27,6 +27,7 @@
#include <linux/proc_fs.h>
#include <linux/poll.h>
#include <linux/pci.h>
+#include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <linux/workqueue.h>
@@ -105,37 +106,40 @@ static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
#ifdef CONFIG_PROC_FS
static struct proc_dir_entry *proc_pccard = NULL;
-static int proc_read_drivers_callback(struct device_driver *driver, void *d)
+static int proc_read_drivers_callback(struct device_driver *driver, void *_m)
{
- char **p = d;
+ struct seq_file *m = _m;
struct pcmcia_driver *p_drv = container_of(driver,
struct pcmcia_driver, drv);
- *p += sprintf(*p, "%-24.24s 1 %d\n", p_drv->drv.name,
+ seq_printf(m, "%-24.24s 1 %d\n", p_drv->drv.name,
#ifdef CONFIG_MODULE_UNLOAD
(p_drv->owner) ? module_refcount(p_drv->owner) : 1
#else
1
#endif
);
- d = (void *) p;
-
return 0;
}
-static int proc_read_drivers(char *buf, char **start, off_t pos,
- int count, int *eof, void *data)
+static int pccard_drivers_proc_show(struct seq_file *m, void *v)
{
- char *p = buf;
- int rc;
-
- rc = bus_for_each_drv(&pcmcia_bus_type, NULL,
- (void *) &p, proc_read_drivers_callback);
- if (rc < 0)
- return rc;
+ return bus_for_each_drv(&pcmcia_bus_type, NULL,
+ m, proc_read_drivers_callback);
+}
- return (p - buf);
+static int pccard_drivers_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pccard_drivers_proc_show, NULL);
}
+
+static const struct file_operations pccard_drivers_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = pccard_drivers_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
#endif
@@ -286,7 +290,7 @@ static int pccard_get_status(struct pcmcia_socket *s,
return 0;
} /* pccard_get_status */
-int pccard_get_configuration_info(struct pcmcia_socket *s,
+static int pccard_get_configuration_info(struct pcmcia_socket *s,
struct pcmcia_device *p_dev,
config_info_t *config)
{
@@ -1011,7 +1015,7 @@ void __init pcmcia_setup_ioctl(void) {
#ifdef CONFIG_PROC_FS
proc_pccard = proc_mkdir("bus/pccard", NULL);
if (proc_pccard)
- create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
+ proc_create("drivers", 0, proc_pccard, &pccard_drivers_proc_fops);
#endif
}
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index f5d0ba8e22d5..d919e96c0afd 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -489,7 +489,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
pccard_io_map iomap;
if (!(s->state & SOCKET_PRESENT))
- return -ENODEV;;
+ return -ENODEV;
if (req->IntType & INT_CARDBUS) {
ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n");
@@ -902,7 +902,7 @@ struct pcmcia_cfg_mem {
*
* pcmcia_loop_config() loops over all configuration options, and calls
* the driver-specific conf_check() for each one, checking whether
- * it is a valid one.
+ * it is a valid one. Returns 0 on success or errorcode otherwise.
*/
int pcmcia_loop_config(struct pcmcia_device *p_dev,
int (*conf_check) (struct pcmcia_device *p_dev,
@@ -915,7 +915,7 @@ int pcmcia_loop_config(struct pcmcia_device *p_dev,
struct pcmcia_cfg_mem *cfg_mem;
tuple_t *tuple;
- int ret = -ENODEV;
+ int ret;
unsigned int vcc;
cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index c49a7269f6d1..87e22ef8eb02 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -300,25 +300,29 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
return soc_common_drv_pcmcia_remove(&dev->dev);
}
-static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t state)
+static int pxa2xx_drv_pcmcia_suspend(struct device *dev)
{
- return pcmcia_socket_dev_suspend(&dev->dev, state);
+ return pcmcia_socket_dev_suspend(dev, PMSG_SUSPEND);
}
-static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev)
+static int pxa2xx_drv_pcmcia_resume(struct device *dev)
{
- pxa2xx_configure_sockets(&dev->dev);
- return pcmcia_socket_dev_resume(&dev->dev);
+ pxa2xx_configure_sockets(dev);
+ return pcmcia_socket_dev_resume(dev);
}
+static struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = {
+ .suspend = pxa2xx_drv_pcmcia_suspend,
+ .resume = pxa2xx_drv_pcmcia_resume,
+};
+
static struct platform_driver pxa2xx_pcmcia_driver = {
.probe = pxa2xx_drv_pcmcia_probe,
.remove = pxa2xx_drv_pcmcia_remove,
- .suspend = pxa2xx_drv_pcmcia_suspend,
- .resume = pxa2xx_drv_pcmcia_resume,
.driver = {
.name = "pxa2xx-pcmcia",
.owner = THIS_MODULE,
+ .pm = &pxa2xx_drv_pcmcia_pm_ops,
},
};
diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c
new file mode 100644
index 000000000000..3a8993ed5621
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_palmtc.c
@@ -0,0 +1,230 @@
+/*
+ * linux/drivers/pcmcia/pxa2xx_palmtc.c
+ *
+ * Driver for Palm Tungsten|C PCMCIA
+ *
+ * Copyright (C) 2008 Alex Osborne <ato@meshy.org>
+ * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h>
+#include <mach/palmtc.h>
+#include "soc_common.h"
+
+static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER1, "PCMCIA PWR1");
+ if (ret)
+ goto err1;
+ ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER1, 0);
+ if (ret)
+ goto err2;
+
+ ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER2, "PCMCIA PWR2");
+ if (ret)
+ goto err2;
+ ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER2, 0);
+ if (ret)
+ goto err3;
+
+ ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER3, "PCMCIA PWR3");
+ if (ret)
+ goto err3;
+ ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER3, 0);
+ if (ret)
+ goto err4;
+
+ ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_RESET, "PCMCIA RST");
+ if (ret)
+ goto err4;
+ ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
+ if (ret)
+ goto err5;
+
+ ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_READY, "PCMCIA RDY");
+ if (ret)
+ goto err5;
+ ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_READY);
+ if (ret)
+ goto err6;
+
+ ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_PWRREADY, "PCMCIA PWRRDY");
+ if (ret)
+ goto err6;
+ ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
+ if (ret)
+ goto err7;
+
+ skt->irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY);
+ return 0;
+
+err7:
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
+err6:
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_READY);
+err5:
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET);
+err4:
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3);
+err3:
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2);
+err2:
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1);
+err1:
+ return ret;
+}
+
+static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_READY);
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET);
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3);
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2);
+ gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1);
+}
+
+static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+ struct pcmcia_state *state)
+{
+ state->detect = 1; /* always inserted */
+ state->ready = !!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_READY);
+ state->bvd1 = 1;
+ state->bvd2 = 1;
+ state->wrprot = 0;
+ state->vs_3v = 1;
+ state->vs_Xv = 0;
+}
+
+static int palmtc_wifi_powerdown(void)
+{
+ gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
+ gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER2, 0);
+ mdelay(40);
+ gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER1, 0);
+ return 0;
+}
+
+static int palmtc_wifi_powerup(void)
+{
+ int timeout = 50;
+
+ gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER3, 1);
+ mdelay(50);
+
+ /* Power up the card, 1.8V first, after a while 3.3V */
+ gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER1, 1);
+ mdelay(100);
+ gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER2, 1);
+
+ /* Wait till the card is ready */
+ while (!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_PWRREADY) &&
+ timeout) {
+ mdelay(1);
+ timeout--;
+ }
+
+ /* Power down the WiFi in case of error */
+ if (!timeout) {
+ palmtc_wifi_powerdown();
+ return 1;
+ }
+
+ /* Reset the card */
+ gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
+ mdelay(20);
+ gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 0);
+ mdelay(25);
+
+ gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER3, 0);
+
+ return 0;
+}
+
+static int palmtc_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+ const socket_state_t *state)
+{
+ int ret = 1;
+
+ if (state->Vcc == 0)
+ ret = palmtc_wifi_powerdown();
+ else if (state->Vcc == 33)
+ ret = palmtc_wifi_powerup();
+
+ return ret;
+}
+
+static void palmtc_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void palmtc_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+static struct pcmcia_low_level palmtc_pcmcia_ops = {
+ .owner = THIS_MODULE,
+
+ .first = 0,
+ .nr = 1,
+
+ .hw_init = palmtc_pcmcia_hw_init,
+ .hw_shutdown = palmtc_pcmcia_hw_shutdown,
+
+ .socket_state = palmtc_pcmcia_socket_state,
+ .configure_socket = palmtc_pcmcia_configure_socket,
+
+ .socket_init = palmtc_pcmcia_socket_init,
+ .socket_suspend = palmtc_pcmcia_socket_suspend,
+};
+
+static struct platform_device *palmtc_pcmcia_device;
+
+static int __init palmtc_pcmcia_init(void)
+{
+ int ret;
+
+ if (!machine_is_palmtc())
+ return -ENODEV;
+
+ palmtc_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+ if (!palmtc_pcmcia_device)
+ return -ENOMEM;
+
+ ret = platform_device_add_data(palmtc_pcmcia_device, &palmtc_pcmcia_ops,
+ sizeof(palmtc_pcmcia_ops));
+
+ if (!ret)
+ ret = platform_device_add(palmtc_pcmcia_device);
+
+ if (ret)
+ platform_device_put(palmtc_pcmcia_device);
+
+ return ret;
+}
+
+static void __exit palmtc_pcmcia_exit(void)
+{
+ platform_device_unregister(palmtc_pcmcia_device);
+}
+
+module_init(palmtc_pcmcia_init);
+module_exit(palmtc_pcmcia_exit);
+
+MODULE_AUTHOR("Alex Osborne <ato@meshy.org>,"
+ " Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("PCMCIA support for Palm Tungsten|C");
+MODULE_ALIAS("platform:pxa2xx-pcmcia");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1100_jornada720.c
index 57ca085473d5..7eedb42f800c 100644
--- a/drivers/pcmcia/sa1100_jornada720.c
+++ b/drivers/pcmcia/sa1100_jornada720.c
@@ -16,89 +16,103 @@
#include "sa1111_generic.h"
-#define SOCKET0_POWER GPIO_GPIO0
-#define SOCKET0_3V GPIO_GPIO2
-#define SOCKET1_POWER (GPIO_GPIO1 | GPIO_GPIO3)
-#warning *** Does SOCKET1_3V actually do anything?
+/* Does SOCKET1_3V actually do anything? */
+#define SOCKET0_POWER GPIO_GPIO0
+#define SOCKET0_3V GPIO_GPIO2
+#define SOCKET1_POWER (GPIO_GPIO1 | GPIO_GPIO3)
#define SOCKET1_3V GPIO_GPIO3
static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
- /*
- * What is all this crap for?
- */
- GRER |= 0x00000002;
- /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
- sa1111_set_io_dir(SA1111_DEV(skt->dev), GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
- sa1111_set_io(SA1111_DEV(skt->dev), GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
- sa1111_set_sleep_io(SA1111_DEV(skt->dev), GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-
- return sa1111_pcmcia_hw_init(skt);
+ unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
+
+ /*
+ * What is all this crap for?
+ */
+ GRER |= 0x00000002;
+ /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
+ sa1111_set_io_dir(SA1111_DEV(skt->dev), pin, 0, 0);
+ sa1111_set_io(SA1111_DEV(skt->dev), pin, 0);
+ sa1111_set_sleep_io(SA1111_DEV(skt->dev), pin, 0);
+
+ return sa1111_pcmcia_hw_init(skt);
}
static int
jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
- unsigned int pa_dwr_mask, pa_dwr_set;
- int ret;
-
-printk("%s(): config socket %d vcc %d vpp %d\n", __func__,
- skt->nr, state->Vcc, state->Vpp);
-
- switch (skt->nr) {
- case 0:
- pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
-
- switch (state->Vcc) {
- default:
- case 0: pa_dwr_set = 0; break;
- case 33: pa_dwr_set = SOCKET0_POWER | SOCKET0_3V; break;
- case 50: pa_dwr_set = SOCKET0_POWER; break;
- }
- break;
-
- case 1:
- pa_dwr_mask = SOCKET1_POWER;
-
- switch (state->Vcc) {
- default:
- case 0: pa_dwr_set = 0; break;
- case 33: pa_dwr_set = SOCKET1_POWER; break;
- case 50: pa_dwr_set = SOCKET1_POWER; break;
- }
- break;
-
- default:
- return -1;
- }
-
- if (state->Vpp != state->Vcc && state->Vpp != 0) {
- printk(KERN_ERR "%s(): slot cannot support VPP %u\n",
- __func__, state->Vpp);
- return -1;
- }
-
- ret = sa1111_pcmcia_configure_socket(skt, state);
- if (ret == 0) {
- unsigned long flags;
-
- local_irq_save(flags);
- sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
- local_irq_restore(flags);
- }
-
- return ret;
+ unsigned int pa_dwr_mask, pa_dwr_set;
+ int ret;
+
+ printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__,
+ skt->nr, state->Vcc, state->Vpp);
+
+ switch (skt->nr) {
+ case 0:
+ pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
+
+ switch (state->Vcc) {
+ default:
+ case 0:
+ pa_dwr_set = 0;
+ break;
+ case 33:
+ pa_dwr_set = SOCKET0_POWER | SOCKET0_3V;
+ break;
+ case 50:
+ pa_dwr_set = SOCKET0_POWER;
+ break;
+ }
+ break;
+
+ case 1:
+ pa_dwr_mask = SOCKET1_POWER;
+
+ switch (state->Vcc) {
+ default:
+ case 0:
+ pa_dwr_set = 0;
+ break;
+ case 33:
+ pa_dwr_set = SOCKET1_POWER;
+ break;
+ case 50:
+ pa_dwr_set = SOCKET1_POWER;
+ break;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+
+ if (state->Vpp != state->Vcc && state->Vpp != 0) {
+ printk(KERN_ERR "%s(): slot cannot support VPP %u\n",
+ __func__, state->Vpp);
+ return -EPERM;
+ }
+
+ ret = sa1111_pcmcia_configure_socket(skt, state);
+ if (ret == 0) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
+ local_irq_restore(flags);
+ }
+
+ return ret;
}
static struct pcmcia_low_level jornada720_pcmcia_ops = {
- .owner = THIS_MODULE,
- .hw_init = jornada720_pcmcia_hw_init,
- .hw_shutdown = sa1111_pcmcia_hw_shutdown,
- .socket_state = sa1111_pcmcia_socket_state,
- .configure_socket = jornada720_pcmcia_configure_socket,
-
- .socket_init = sa1111_pcmcia_socket_init,
- .socket_suspend = sa1111_pcmcia_socket_suspend,
+ .owner = THIS_MODULE,
+ .hw_init = jornada720_pcmcia_hw_init,
+ .hw_shutdown = sa1111_pcmcia_hw_shutdown,
+ .socket_state = sa1111_pcmcia_socket_state,
+ .configure_socket = jornada720_pcmcia_configure_socket,
+
+ .socket_init = sa1111_pcmcia_socket_init,
+ .socket_suspend = sa1111_pcmcia_socket_suspend,
};
int __devinit pcmcia_jornada720_init(struct device *dev)
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 3ecd7c99d8eb..b459e87a30ac 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -622,11 +622,12 @@ static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end)
{
- struct resource *root, *res;
+ struct pci_dev *dev = socket->dev;
+ struct resource *res;
struct pci_bus_region region;
unsigned mask;
- res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
+ res = dev->resource + PCI_BRIDGE_RESOURCES + nr;
/* Already allocated? */
if (res->parent)
return 0;
@@ -636,17 +637,16 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
if (type & IORESOURCE_IO)
mask = ~3;
- res->name = socket->dev->subordinate->name;
+ res->name = dev->subordinate->name;
res->flags = type;
region.start = config_readl(socket, addr_start) & mask;
region.end = config_readl(socket, addr_end) | ~mask;
if (region.start && region.end > region.start && !override_bios) {
- pcibios_bus_to_resource(socket->dev, res, &region);
- root = pci_find_parent_resource(socket->dev, res);
- if (root && (request_resource(root, res) == 0))
+ pcibios_bus_to_resource(dev, res, &region);
+ if (pci_claim_resource(dev, PCI_BRIDGE_RESOURCES + nr) == 0)
return 0;
- dev_printk(KERN_INFO, &socket->dev->dev,
+ dev_printk(KERN_INFO, &dev->dev,
"Preassigned resource %d busy or not available, "
"reconfiguring...\n",
nr);
@@ -672,7 +672,7 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
return 1;
}
- dev_printk(KERN_INFO, &socket->dev->dev,
+ dev_printk(KERN_INFO, &dev->dev,
"no resource of type %x available, trying to continue...\n",
type);
res->start = res->end = res->flags = 0;
@@ -717,7 +717,7 @@ static void yenta_free_resources(struct yenta_socket *socket)
/*
* Close it down - release our resources and go home..
*/
-static void yenta_close(struct pci_dev *dev)
+static void __devexit yenta_close(struct pci_dev *dev)
{
struct yenta_socket *sock = pci_get_drvdata(dev);