aboutsummaryrefslogtreecommitdiff
path: root/drivers/sdio/stack/platform/sdioplatformdriver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sdio/stack/platform/sdioplatformdriver.c')
-rw-r--r--drivers/sdio/stack/platform/sdioplatformdriver.c300
1 files changed, 300 insertions, 0 deletions
diff --git a/drivers/sdio/stack/platform/sdioplatformdriver.c b/drivers/sdio/stack/platform/sdioplatformdriver.c
new file mode 100644
index 00000000000..d5520fc2908
--- /dev/null
+++ b/drivers/sdio/stack/platform/sdioplatformdriver.c
@@ -0,0 +1,300 @@
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+@file: sdioplatformdriver.c
+
+@abstract: Linux implementation module for SDIO pltaform driver
+
+#notes:
+
+@notice: Copyright (c), 2006 Atheros Communications, Inc.
+
+@license: 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.
+
+
+
+ *
+ * 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;
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Portions of this code were developed with information supplied from the
+ * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
+ *
+ * The following conditions apply to the release of the SD simplified specification (�Simplified
+ * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
+ * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
+ * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
+ * Specification may require a license from the SD Card Association or other third parties.
+ * Disclaimers:
+ * The information contained in the Simplified Specification is presented only as a standard
+ * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
+ * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
+ * any damages, any infringements of patents or other right of the SD Card Association or any third
+ * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
+ * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
+ * be construed as an obligation by the SD Card Association to disclose or distribute any technical
+ * information, know-how or other confidential information to any third party.
+ *
+ *
+ * The initial developers of the original code are Seung Yi and Paul Lever
+ *
+ * sdio@atheros.com
+ *
+ *
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+#define DESCRIPTION "SDIO Platform Driver"
+#define AUTHOR "Atheros Communications, Inc."
+
+//??for .h
+
+struct sdioplatform_peripheral {
+ struct list_head node;
+ struct sdioplatform_controller *controller;
+ struct device dev;
+};
+struct sdioplatform_driver {
+ struct device_driver drv;
+ int (*probe)(struct sdioplatform_peripheral *);
+ void (*remove)(struct sdioplatform_peripheral *);
+ int (*suspend)(struct sdioplatform_peripheral *, pm_message_t);
+ int (*resume)(struct sdioplatform_peripheral *);
+};
+
+
+struct sdioplatform_controller {
+ struct device *dev;
+};
+struct sdioplatform_controller_driver {
+ struct device_driver drv;
+ int (*probe)(struct sdioplatform_controller *);
+ void (*remove)(struct sdioplatform_controller *);
+ int (*suspend)(struct sdioplatform_controller *, pm_message_t);
+ int (*resume)(struct sdioplatform_controller *);
+};
+
+
+
+#define device_to_sdioplatform_peripheral(d) container_of(d, struct sdioplatform_peripheral, dev)
+#define driver_to_sdioplatform_driver(d) container_of(d, struct sdioplatform_driver, drv)
+
+#define device_to_sdioplatform_controller(d) container_of(d, struct sdioplatform_controller, dev)
+#define driver_to_sdioplatform_controller_driver(d) container_of(d, struct sdioplatform_controller_driver, drv)
+
+#define SDIOPLATFORM_ATTR(name, fmt, args...) \
+static ssize_t sdio_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+ struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev); \
+ return sprintf(buf, fmt, args); \
+}
+
+SDIOPLATFORM_ATTR(bus_id, "%s\n", bus_id);
+#define SDIOPLATFORM_ATTR_RO(name) __ATTR(name, S_IRUGO, sdioplatform_##name##_show, NULL)
+
+static struct device_attribute sdioplatform_dev_attrs[] = {
+ SDIOPLATFORM_ATTR_RO(bus_id),
+ __ATTR_NULL
+};
+
+static struct bus_type sdioplatform_bus_type = {
+ .name = "sdioplatform",
+ .dev_attrs = sdioplatform_dev_attrs,
+ .match = sdioplatform_bus_match,
+ .hotplug = NULL,
+ .suspend = sdioplatform_bus_suspend,
+ .resume = sdioplatform_bus_resume,
+};
+
+
+/* controller functions */
+static int sdioplatform_controllerdrv_probe(struct device *dev)
+{
+ struct sdioplatform_controller_driver *drv = driver_to_sdioplatform_controller_driver(dev->driver);
+ struct sdioplatform_controller *controller = device_to_sdioplatform_controller(dev);
+
+ return drv->probe(controller);
+}
+
+static int sdioplatform_controllerdrv_remove(struct device *dev)
+{
+ struct sdioplatform_controller_driver *drv = driver_to_sdioplatform_controller_driver(dev->driver);
+ struct sdioplatform_controller *controller = device_to_sdioplatform_controller(dev);
+
+ return drv->remove(controller);
+}
+
+/*
+ * sdioplatform_register_controller_driver - register a controller driver
+ */
+int sdioplatform_register_controller_driver(struct sdioplatform_controller_driver *drv)
+{
+ drv->drv.bus = &sdioplatform_bus_type;
+ drv->drv.probe = sdioplatform_controllerdrv_probe;
+ drv->drv.remove = sdioplatform_controllerdrv_remove;
+ return driver_register(&drv->drv);
+}
+
+/*
+ * sdioplatform_unregister_controller_driver - unregister a controller driver
+ */
+void sdioplatform_unregister_controller_driver(struct sdioplatform_driver *drv)
+{
+ driver_unregister(&drv->drv);
+}
+
+/*
+ * sdioplatform_add_controller - register a controller device
+ */
+int sdioplatform_add_controller(char *name, struct sdioplatform_controller *dev)
+{
+ if (!dev) {
+ return -EINVAL;
+ }
+ strncpy(dev->dev.bus_id, BUS_ID_SIZE, name);
+ return device_register(&dev->dev);
+}
+
+/*
+ * sdioplatform_remove_controller - unregister a controller device
+ */
+int sdioplatform_remove_controller(char *name, struct sdioplatform_controller *dev)
+{
+ if (!dev) {
+ return -EINVAL;
+ }
+ return device_unregister(&dev->dev);
+}
+
+/* peripheral functions */
+static int sdioplatform_drv_probe(struct device *dev)
+{
+ struct sdioplatform_driver *drv = driver_to_sdioplatform_driver(dev->driver);
+ struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev);
+
+ return drv->probe(peripheral);
+}
+
+static int sdioplatform_controllerdrv_remove(struct device *dev)
+{
+ struct sdioplatform_controller_driver *drv = driver_to_sdioplatform_controller_driver(dev->driver);
+ struct sdioplatform_controller *controller = device_to_sdioplatform_controller(dev);
+
+ return drv->remove(controller);
+}
+
+/*
+ * sdioplatform_register_driver - register a driver
+ */
+int sdioplatform_register_driver(struct sdioplatform_driver *drv)
+{
+ drv->drv.bus = &sdioplatform_bus_type;
+ drv->drv.probe = sdioplatform_drv_probe;
+ drv->drv.remove = sdioplatform_drv_remove;
+ return driver_register(&drv->drv);
+}
+
+/*
+ * sdioplatform_unregister_driver - unregister a driver
+ */
+void sdioplatform_unregister_driver(struct sdioplatform_driver *drv)
+{
+ driver_unregister(&drv->drv);
+}
+
+/*
+ * sdioplatform_add_peripheral - register a peripheral device
+ */
+int sdioplatform_add_peripheral(char *name, struct sdioplatform_peripheral *dev)
+{
+ if (!dev) {
+ return -EINVAL;
+ }
+ strncpy(dev->dev.bus_id, BUS_ID_SIZE, name);
+ return device_register(&dev->dev);
+}
+
+/*
+ * sdioplatform_remove_peripheral - unregister a peripheral device
+ */
+int sdioplatform_remove_peripheral(char *name, struct sdioplatform_peripheral *dev)
+{
+ if (!dev) {
+ return -EINVAL;
+ }
+ return device_unregister(&dev->dev);
+}
+
+
+
+
+
+static int sdioplatform_bus_match(struct device *dev, struct device_driver *drv)
+{
+ /* probes handle the matching */
+ return 1;
+}
+
+static int sdioplatform_bus_suspend(struct device *dev, pm_message_t state)
+{
+ struct sdioplatform_driver *drv = driver_to_sdioplatform_driver(dev->driver);
+ struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev);
+ int ret = 0;
+
+ if (peripheral->driver && drv->suspend) {
+ ret = drv->suspend(peripheral, state);
+ }
+ return ret;
+}
+
+static int sdioplatform_bus_resume(struct device *dev)
+{
+ struct sdioplatform_driver *drv = driver_to_sdioplatform_driver(dev->driver);
+ struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev);
+ int ret = 0;
+
+ if (peripheral->driver && drv->resume) {
+ ret = drv->resume(card);
+ }
+ return ret;
+}
+
+/*
+ * module init
+*/
+static int __init sdio_platformdriver_init(void) {
+ int ret = bus_register(&sdioplatform_bus_type);
+ return ret;
+}
+
+/*
+ * module cleanup
+*/
+static void __exit sdio_platformdriver_cleanup(void) {
+ REL_PRINT(SDDBG_TRACE, ("SDIO unloaded\n"));
+ _SDIO_BusDriverCleanup();
+}
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(DESCRIPTION);
+MODULE_AUTHOR(AUTHOR);
+
+module_init(sdio_platformdriver_init);
+module_exit(sdio_platformdriver_cleanup);
+EXPORT_SYMBOL(sdioplatform_register_controller_driver);
+EXPORT_SYMBOL(sdioplatform_unregister_controller_driver);
+EXPORT_SYMBOL(sdioplatform_add_controller);
+EXPORT_SYMBOL(sdioplatform_remove_controller);
+EXPORT_SYMBOL(sdioplatform_register_driver);
+EXPORT_SYMBOL(sdioplatform_unregister_driver);
+EXPORT_SYMBOL(sdioplatform_add_peripheral);
+EXPORT_SYMBOL(sdioplatform_remove_peripheral);
+
+
+