Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*======================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)     Device driver for the PCMCIA control functionality of StrongARM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)     SA-1100 microprocessors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)     The contents of this file are subject to the Mozilla Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)     License Version 1.1 (the "License"); you may not use this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)     except in compliance with the License. You may obtain a copy of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)     the License at http://www.mozilla.org/MPL/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)     Software distributed under the License is distributed on an "AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)     IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)     implied. See the License for the specific language governing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)     rights and limitations under the License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)     The initial developer of the original code is John G. Dorsey
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)     <john+@cs.cmu.edu>.  Portions created by John G. Dorsey are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)     Copyright (C) 1999 John G. Dorsey.  All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)     Alternatively, the contents of this file may be used under the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)     terms of the GNU Public License version 2 (the "GPL"), in which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)     case the provisions of the GPL are applicable instead of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)     above.  If you wish to allow the use of your version of this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)     only under the terms of the GPL and not to allow others to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)     your version of this file under the MPL, indicate your decision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)     by deleting the provisions above and replace them with the notice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)     and other provisions required by the GPL.  If you do not delete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)     the provisions above, a recipient may use your version of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)     file under either the MPL or the GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) ======================================================================*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <pcmcia/ss.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include <asm/hardware/scoop.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include "sa1100_generic.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static const char *sa11x0_cf_gpio_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	[SOC_STAT_CD] = "detect",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	[SOC_STAT_BVD1] = "bvd1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	[SOC_STAT_BVD2] = "bvd2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	[SOC_STAT_RDY] = "ready",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static int sa11x0_cf_hw_init(struct soc_pcmcia_socket *skt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	struct device *dev = skt->socket.dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	skt->gpio_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (IS_ERR(skt->gpio_reset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		return PTR_ERR(skt->gpio_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	skt->gpio_bus_enable = devm_gpiod_get_optional(dev, "bus-enable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 						       GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	if (IS_ERR(skt->gpio_bus_enable))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		return PTR_ERR(skt->gpio_bus_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	skt->vcc.reg = devm_regulator_get_optional(dev, "vcc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	if (IS_ERR(skt->vcc.reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		return PTR_ERR(skt->vcc.reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (!skt->vcc.reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			 "no Vcc regulator provided, ignoring Vcc controls\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	for (i = 0; i < ARRAY_SIZE(sa11x0_cf_gpio_names); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		skt->stat[i].name = sa11x0_cf_gpio_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		skt->stat[i].desc = devm_gpiod_get_optional(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 					sa11x0_cf_gpio_names[i], GPIOD_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		if (IS_ERR(skt->stat[i].desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			return PTR_ERR(skt->stat[i].desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) static int sa11x0_cf_configure_socket(struct soc_pcmcia_socket *skt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	const socket_state_t *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	return soc_pcmcia_regulator_set(skt, &skt->vcc, state->Vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) static struct pcmcia_low_level sa11x0_cf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	.hw_init = sa11x0_cf_hw_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	.socket_state = soc_common_cf_socket_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	.configure_socket = sa11x0_cf_configure_socket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) int __init pcmcia_collie_init(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	pcmcia_h3600_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #ifdef CONFIG_SA1100_SIMPAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	pcmcia_simpad_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #ifdef CONFIG_SA1100_COLLIE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)        pcmcia_collie_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int sa11x0_drv_pcmcia_legacy_probe(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	int i, ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	 * Initialise any "on-board" PCMCIA sockets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_legacy_hw_init); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		ret = sa11x0_pcmcia_legacy_hw_init[i](&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int sa11x0_drv_pcmcia_legacy_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	struct skt_dev_info *sinfo = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	platform_set_drvdata(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	for (i = 0; i < sinfo->nskt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		soc_pcmcia_remove_one(&sinfo->skt[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int sa11x0_drv_pcmcia_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct soc_pcmcia_socket *skt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (pdev->id == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		return sa11x0_drv_pcmcia_legacy_probe(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	skt = devm_kzalloc(dev, sizeof(*skt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	if (!skt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	platform_set_drvdata(pdev, skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	skt->nr = pdev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	skt->clk = devm_clk_get(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (IS_ERR(skt->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		return PTR_ERR(skt->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	sa11xx_drv_pcmcia_ops(&sa11x0_cf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	soc_pcmcia_init_one(skt, &sa11x0_cf_ops, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	return sa11xx_drv_pcmcia_add_one(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	struct soc_pcmcia_socket *skt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (dev->id == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		return sa11x0_drv_pcmcia_legacy_remove(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	skt = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	soc_pcmcia_remove_one(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static struct platform_driver sa11x0_pcmcia_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		.name		= "sa11x0-pcmcia",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	.probe		= sa11x0_drv_pcmcia_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	.remove		= sa11x0_drv_pcmcia_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* sa11x0_pcmcia_init()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  * ^^^^^^^^^^^^^^^^^^^^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  * This routine performs low-level PCMCIA initialization and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  * registers this socket driver with Card Services.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  * Returns: 0 on success, -ve error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static int __init sa11x0_pcmcia_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	return platform_driver_register(&sa11x0_pcmcia_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* sa11x0_pcmcia_exit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  * ^^^^^^^^^^^^^^^^^^^^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  * Invokes the low-level kernel service to free IRQs associated with this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  * socket controller and reset GPIO edge detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static void __exit sa11x0_pcmcia_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	platform_driver_unregister(&sa11x0_pcmcia_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-11x0 Socket Controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) MODULE_LICENSE("Dual MPL/GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) fs_initcall(sa11x0_pcmcia_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) module_exit(sa11x0_pcmcia_exit);