162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Zorro Driver Services 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2003 Geert Uytterhoeven 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Loosely based on drivers/pci/pci-driver.c 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 962306a36Sopenharmony_ci * License. See the file COPYING in the main directory of this archive 1062306a36Sopenharmony_ci * for more details. 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/init.h> 1462306a36Sopenharmony_ci#include <linux/module.h> 1562306a36Sopenharmony_ci#include <linux/zorro.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include "zorro.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci /** 2162306a36Sopenharmony_ci * zorro_match_device - Tell if a Zorro device structure has a matching 2262306a36Sopenharmony_ci * Zorro device id structure 2362306a36Sopenharmony_ci * @ids: array of Zorro device id structures to search in 2462306a36Sopenharmony_ci * @dev: the Zorro device structure to match against 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * Used by a driver to check whether a Zorro device present in the 2762306a36Sopenharmony_ci * system is in its list of supported devices. Returns the matching 2862306a36Sopenharmony_ci * zorro_device_id structure or %NULL if there is no match. 2962306a36Sopenharmony_ci */ 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic const struct zorro_device_id * 3262306a36Sopenharmony_cizorro_match_device(const struct zorro_device_id *ids, 3362306a36Sopenharmony_ci const struct zorro_dev *z) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci while (ids->id) { 3662306a36Sopenharmony_ci if (ids->id == ZORRO_WILDCARD || ids->id == z->id) 3762306a36Sopenharmony_ci return ids; 3862306a36Sopenharmony_ci ids++; 3962306a36Sopenharmony_ci } 4062306a36Sopenharmony_ci return NULL; 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistatic int zorro_device_probe(struct device *dev) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci int error = 0; 4762306a36Sopenharmony_ci struct zorro_driver *drv = to_zorro_driver(dev->driver); 4862306a36Sopenharmony_ci struct zorro_dev *z = to_zorro_dev(dev); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci if (drv->probe) { 5162306a36Sopenharmony_ci const struct zorro_device_id *id; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci id = zorro_match_device(drv->id_table, z); 5462306a36Sopenharmony_ci if (id) 5562306a36Sopenharmony_ci error = drv->probe(z, id); 5662306a36Sopenharmony_ci if (error >= 0) 5762306a36Sopenharmony_ci error = 0; 5862306a36Sopenharmony_ci } 5962306a36Sopenharmony_ci return error; 6062306a36Sopenharmony_ci} 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistatic void zorro_device_remove(struct device *dev) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci struct zorro_dev *z = to_zorro_dev(dev); 6662306a36Sopenharmony_ci struct zorro_driver *drv = to_zorro_driver(dev->driver); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci if (drv->remove) 6962306a36Sopenharmony_ci drv->remove(z); 7062306a36Sopenharmony_ci} 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci /** 7462306a36Sopenharmony_ci * zorro_register_driver - register a new Zorro driver 7562306a36Sopenharmony_ci * @drv: the driver structure to register 7662306a36Sopenharmony_ci * 7762306a36Sopenharmony_ci * Adds the driver structure to the list of registered drivers 7862306a36Sopenharmony_ci * Returns zero or a negative error value. 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ciint zorro_register_driver(struct zorro_driver *drv) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci /* initialize common driver fields */ 8462306a36Sopenharmony_ci drv->driver.name = drv->name; 8562306a36Sopenharmony_ci drv->driver.bus = &zorro_bus_type; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci /* register with core */ 8862306a36Sopenharmony_ci return driver_register(&drv->driver); 8962306a36Sopenharmony_ci} 9062306a36Sopenharmony_ciEXPORT_SYMBOL(zorro_register_driver); 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci /** 9462306a36Sopenharmony_ci * zorro_unregister_driver - unregister a zorro driver 9562306a36Sopenharmony_ci * @drv: the driver structure to unregister 9662306a36Sopenharmony_ci * 9762306a36Sopenharmony_ci * Deletes the driver structure from the list of registered Zorro drivers, 9862306a36Sopenharmony_ci * gives it a chance to clean up by calling its remove() function for 9962306a36Sopenharmony_ci * each device it was responsible for, and marks those devices as 10062306a36Sopenharmony_ci * driverless. 10162306a36Sopenharmony_ci */ 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_civoid zorro_unregister_driver(struct zorro_driver *drv) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci driver_unregister(&drv->driver); 10662306a36Sopenharmony_ci} 10762306a36Sopenharmony_ciEXPORT_SYMBOL(zorro_unregister_driver); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci /** 11162306a36Sopenharmony_ci * zorro_bus_match - Tell if a Zorro device structure has a matching Zorro 11262306a36Sopenharmony_ci * device id structure 11362306a36Sopenharmony_ci * @ids: array of Zorro device id structures to search in 11462306a36Sopenharmony_ci * @dev: the Zorro device structure to match against 11562306a36Sopenharmony_ci * 11662306a36Sopenharmony_ci * Used by the driver core to check whether a Zorro device present in the 11762306a36Sopenharmony_ci * system is in a driver's list of supported devices. Returns 1 if 11862306a36Sopenharmony_ci * supported, and 0 if there is no match. 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic int zorro_bus_match(struct device *dev, struct device_driver *drv) 12262306a36Sopenharmony_ci{ 12362306a36Sopenharmony_ci struct zorro_dev *z = to_zorro_dev(dev); 12462306a36Sopenharmony_ci struct zorro_driver *zorro_drv = to_zorro_driver(drv); 12562306a36Sopenharmony_ci const struct zorro_device_id *ids = zorro_drv->id_table; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci if (!ids) 12862306a36Sopenharmony_ci return 0; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci return !!zorro_match_device(ids, z); 13162306a36Sopenharmony_ci} 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistatic int zorro_uevent(const struct device *dev, struct kobj_uevent_env *env) 13462306a36Sopenharmony_ci{ 13562306a36Sopenharmony_ci const struct zorro_dev *z; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci if (!dev) 13862306a36Sopenharmony_ci return -ENODEV; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci z = to_zorro_dev(dev); 14162306a36Sopenharmony_ci if (!z) 14262306a36Sopenharmony_ci return -ENODEV; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci if (add_uevent_var(env, "ZORRO_ID=%08X", z->id) || 14562306a36Sopenharmony_ci add_uevent_var(env, "ZORRO_SLOT_NAME=%s", dev_name(dev)) || 14662306a36Sopenharmony_ci add_uevent_var(env, "ZORRO_SLOT_ADDR=%04X", z->slotaddr) || 14762306a36Sopenharmony_ci add_uevent_var(env, "MODALIAS=" ZORRO_DEVICE_MODALIAS_FMT, z->id)) 14862306a36Sopenharmony_ci return -ENOMEM; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci return 0; 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistruct bus_type zorro_bus_type = { 15462306a36Sopenharmony_ci .name = "zorro", 15562306a36Sopenharmony_ci .dev_name = "zorro", 15662306a36Sopenharmony_ci .dev_groups = zorro_device_attribute_groups, 15762306a36Sopenharmony_ci .match = zorro_bus_match, 15862306a36Sopenharmony_ci .uevent = zorro_uevent, 15962306a36Sopenharmony_ci .probe = zorro_device_probe, 16062306a36Sopenharmony_ci .remove = zorro_device_remove, 16162306a36Sopenharmony_ci}; 16262306a36Sopenharmony_ciEXPORT_SYMBOL(zorro_bus_type); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic int __init zorro_driver_init(void) 16662306a36Sopenharmony_ci{ 16762306a36Sopenharmony_ci return bus_register(&zorro_bus_type); 16862306a36Sopenharmony_ci} 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cipostcore_initcall(zorro_driver_init); 17162306a36Sopenharmony_ci 172