From: Arnd Bergmann <arnd@arndb.de>
All pccard related technologies are obsolete, but there are a couple
that are still used occasionally. Most importantly this includes
32-bit PCI/Cardbus devices on Laptop PCs built between 1997 and 2006
(Pentium MMX through Core Duo) and embedded systems using 16-bit
PCMCIA/Compactflash slots for CF storage with the pata_pcmcia driver,
but usually not the combination of the two.
Separate the two configuration options for simplification and build the
common code into both the pcmcia and cardbus layers, but only allow one
of the two to be enabled in a kernel configuration, in order to allow
further cleanups on top.
This breaks the use of any 16-bit PCMCIA cards in a 32-bit capable
cardbus slot. If anyone relies on support for this configuration
and cannot use a cardbus compatible card instead, this should not
be applied. In almost all cases, a cardbus or USB based card is
superior and available cheaply compared to the older PCMCIA cards.
In particular, CompactFlash cards now require an active card
reader instead of a slow PCMCIA passthrough adapter.
The CONFIG_PCMCIA option is now limited to platforms that actually
shipped with PCMCIA or CF controllers, which is mostly x86 laptops
from the i486 and Pentium eras as well as a couple of embedded
systems. The Apple Powerbook is not included here, because all
models with PCI support have Cardbus controllers and the earlier
ones can not run Linux any more.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/pcmcia/Kconfig | 13 +++++++-----
drivers/pcmcia/Makefile | 10 ++++-----
drivers/pcmcia/cardbus.c | 1 +
drivers/pcmcia/cs.c | 25 +++++-----------------
drivers/pcmcia/cs_internal.h | 1 +
drivers/pcmcia/ds.c | 14 ++++++++++---
drivers/pcmcia/ricoh.h | 2 +-
drivers/pcmcia/yenta_socket.c | 39 +++++++++++++++++++++++------------
include/pcmcia/ss.h | 4 ++--
9 files changed, 60 insertions(+), 49 deletions(-)
@@ -21,6 +21,9 @@ if PCCARD
config PCMCIA
tristate "16-bit PCMCIA support"
select CRC32
+ depends on X86_32 || ARCH_PXA || ARCH_SA1100 || ARCH_OMAP1 || \
+ MIPS_ALCHEMY || PPC_PASEMI || COMPILE_TEST
+ depends on CARDBUS=n
default y
help
This option enables support for 16-bit PCMCIA cards. Most older
@@ -51,8 +54,9 @@ config PCMCIA_LOAD_CIS
If unsure, say Y.
config CARDBUS
- bool "32-bit CardBus support"
+ tristate "32-bit CardBus support"
depends on PCI
+ select YENTA
default y
help
CardBus is a bus mastering architecture for PC-cards, which allows
@@ -71,10 +75,9 @@ config PCMCIA_MAX1600
comment "PC-card bridges"
config YENTA
- tristate "CardBus yenta-compatible bridge support"
- depends on PCI
- select CARDBUS if !EXPERT
- select PCCARD_NONSTATIC if PCMCIA != n
+ tristate "CardBus yenta-compatible bridge support" if EXPERT
+ depends on PCI && CARDBUS
+ default y
help
This option enables support for CardBus host bridges. Virtually
all modern PCMCIA bridges are CardBus compatible. A "bridge" is
@@ -3,17 +3,17 @@
# Makefile for the kernel pcmcia subsystem (c/o David Hinds)
#
-pcmcia_core-y += cs.o socket_sysfs.o
-pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
-obj-$(CONFIG_PCCARD) += pcmcia_core.o
+cardbus_core-y += cardbus.o cs.o socket_sysfs.o rsrc_mgr.o
+obj-$(CONFIG_CARDBUS) += cardbus_core.o
-pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o
+pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o \
+ cs.o socket_sysfs.o
obj-$(CONFIG_PCMCIA) += pcmcia.o
pcmcia_rsrc-y += rsrc_mgr.o
pcmcia_rsrc-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o
pcmcia_rsrc-$(CONFIG_PCCARD_IODYN) += rsrc_iodyn.o
-obj-$(CONFIG_PCCARD) += pcmcia_rsrc.o
+obj-$(CONFIG_PCMCIA) += pcmcia_rsrc.o
# socket drivers
@@ -121,4 +121,5 @@ void cb_free(struct pcmcia_socket *s)
pci_stop_and_remove_bus_device(dev);
pci_unlock_rescan_remove();
+
}
@@ -133,7 +133,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
list_add_tail(&socket->socket_list, &pcmcia_socket_list);
up_write(&pcmcia_socket_list_rwsem);
-#ifndef CONFIG_CARDBUS
+#if !IS_ENABLED(CONFIG_CARDBUS)
/*
* If we do not support Cardbus, ensure that
* the Cardbus socket capability is disabled.
@@ -313,7 +313,7 @@ static void socket_shutdown(struct pcmcia_socket *s)
*/
mutex_unlock(&s->ops_mutex);
-#ifdef CONFIG_CARDBUS
+#if IS_ENABLED(CONFIG_CARDBUS)
cb_free(s);
#endif
@@ -428,7 +428,7 @@ static int socket_insert(struct pcmcia_socket *skt)
(skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
skt->sock);
-#ifdef CONFIG_CARDBUS
+#if IS_ENABLED(CONFIG_CARDBUS)
if (skt->state & SOCKET_CARDBUS) {
cb_alloc(skt);
skt->state |= SOCKET_CARDBUS_CONFIG;
@@ -522,7 +522,7 @@ static int socket_late_resume(struct pcmcia_socket *skt)
static int socket_complete_resume(struct pcmcia_socket *skt)
{
int ret = 0;
-#ifdef CONFIG_CARDBUS
+#if IS_ENABLED(CONFIG_CARDBUS)
if (skt->state & SOCKET_CARDBUS) {
/* We can't be sure the CardBus card is the same
* as the one previously inserted. Therefore, remove
@@ -822,7 +822,7 @@ static int pcmcia_socket_uevent(const struct device *dev,
}
-static struct completion pcmcia_unload;
+static DECLARE_COMPLETION(pcmcia_unload);
static void pcmcia_release_socket_class(struct class *data)
{
@@ -901,18 +901,3 @@ struct class pcmcia_socket_class = {
EXPORT_SYMBOL(pcmcia_socket_class);
-static int __init init_pcmcia_cs(void)
-{
- init_completion(&pcmcia_unload);
- return class_register(&pcmcia_socket_class);
-}
-
-static void __exit exit_pcmcia_cs(void)
-{
- class_unregister(&pcmcia_socket_class);
- wait_for_completion(&pcmcia_unload);
-}
-
-subsys_initcall(init_pcmcia_cs);
-module_exit(exit_pcmcia_cs);
-
@@ -18,6 +18,7 @@
#define _LINUX_CS_INTERNAL_H
#include <linux/kref.h>
+#include <pcmcia/cistpl.h>
/* Flags in client state */
#define CLIENT_WIN_REQ(i) (0x1<<(i))
@@ -1419,9 +1419,16 @@ static int __init init_pcmcia_bus(void)
{
int ret;
+ ret = class_register(&pcmcia_socket_class);
+ if (ret < 0) {
+ printk(KERN_WARNING "pcmcia: class register error %d\n", ret);
+ return ret;
+ }
+
ret = bus_register(&pcmcia_bus_type);
if (ret < 0) {
printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret);
+ class_unregister(&pcmcia_socket_class);
return ret;
}
ret = class_interface_register(&pcmcia_bus_interface);
@@ -1429,20 +1436,21 @@ static int __init init_pcmcia_bus(void)
printk(KERN_WARNING
"pcmcia: class_interface_register error: %d\n", ret);
bus_unregister(&pcmcia_bus_type);
+ class_unregister(&pcmcia_socket_class);
return ret;
}
return 0;
}
-fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
- * pcmcia_socket_class is already registered */
-
+subsys_initcall(init_pcmcia_bus);
static void __exit exit_pcmcia_bus(void)
{
class_interface_unregister(&pcmcia_bus_interface);
bus_unregister(&pcmcia_bus_type);
+
+ class_unregister(&pcmcia_socket_class);
}
module_exit(exit_pcmcia_bus);
@@ -123,7 +123,7 @@
#define RL5C4XX_MISC3 0x00A2 /* 16 bit */
#define RL5C47X_MISC3_CB_CLKRUN_DIS BIT(1)
-#ifdef __YENTA_H
+#if IS_ENABLED(CONFIG_CARDBUS)
#define rl_misc(socket) ((socket)->private[0])
#define rl_ctl(socket) ((socket)->private[1])
@@ -24,6 +24,7 @@
#include "yenta_socket.h"
#include "i82365.h"
+#include "cs_internal.h"
static bool disable_clkrun;
module_param(disable_clkrun, bool, 0444);
@@ -228,17 +229,8 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
} else if (state & CB_16BITCARD) {
- u8 status = exca_readb(socket, I365_STATUS);
- val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
- if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
- val |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
- } else {
- val |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
- val |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
- }
- val |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
- val |= (status & I365_CS_READY) ? SS_READY : 0;
- val |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
+ dev_warn_once(&socket->dev->dev,
+ "16-bit PCMCIA cards are no longer supported\n");
}
*value = val;
@@ -1176,7 +1168,7 @@ static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
/* prepare pcmcia_socket */
socket->socket.ops = ¥ta_socket_operations;
- socket->socket.resource_ops = &pccard_nonstatic_ops;
+ socket->socket.resource_ops = &pccard_static_ops;
socket->socket.dev.parent = &dev->dev;
socket->socket.driver_data = socket;
socket->socket.owner = THIS_MODULE;
@@ -1450,6 +1442,27 @@ static struct pci_driver yenta_cardbus_driver = {
.driver.pm = YENTA_PM_OPS,
};
-module_pci_driver(yenta_cardbus_driver);
+static int __init yenta_init(void)
+{
+ int ret;
+
+ ret = class_register(&pcmcia_socket_class);
+ if (ret)
+ return ret;
+
+ ret = pci_register_driver(¥ta_cardbus_driver);
+ if (ret)
+ class_unregister(&pcmcia_socket_class);
+
+ return ret;
+}
+module_init(yenta_init);
+
+static void __exit yenta_exit(void)
+{
+ pci_unregister_driver(¥ta_cardbus_driver);
+ class_unregister(&pcmcia_socket_class);
+}
+module_exit(yenta_exit);
MODULE_LICENSE("GPL");
@@ -16,7 +16,7 @@
#include <linux/sched.h> /* task_struct, completion */
#include <linux/mutex.h>
-#ifdef CONFIG_CARDBUS
+#if IS_ENABLED(CONFIG_CARDBUS)
#include <linux/pci.h>
#endif
@@ -176,7 +176,7 @@ struct pcmcia_socket {
int (*power_hook)(struct pcmcia_socket *sock, int operation);
/* allows tuning the CB bridge before loading driver for the CB card */
-#ifdef CONFIG_CARDBUS
+#if IS_ENABLED(CONFIG_CARDBUS)
void (*tune_bridge)(struct pcmcia_socket *sock, struct pci_bus *bus);
#endif