0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/compiler.h>
0013 #include <linux/dma-mapping.h>
0014 #include <linux/errno.h>
0015 #include <linux/init.h>
0016 #include <linux/ioport.h>
0017 #include <linux/kernel.h>
0018 #include <linux/list.h>
0019 #include <linux/module.h>
0020 #include <linux/slab.h>
0021 #include <linux/string.h>
0022 #include <linux/tc.h>
0023 #include <linux/types.h>
0024
0025 #include <asm/io.h>
0026
0027 static struct tc_bus tc_bus = {
0028 .name = "TURBOchannel",
0029 };
0030
0031
0032
0033
0034 static void __init tc_bus_add_devices(struct tc_bus *tbus)
0035 {
0036 resource_size_t slotsize = tbus->info.slot_size << 20;
0037 resource_size_t extslotsize = tbus->ext_slot_size;
0038 resource_size_t slotaddr;
0039 resource_size_t extslotaddr;
0040 resource_size_t devsize;
0041 void __iomem *module;
0042 struct tc_dev *tdev;
0043 int i, slot, err;
0044 u8 pattern[4];
0045 long offset;
0046
0047 for (slot = 0; slot < tbus->num_tcslots; slot++) {
0048 slotaddr = tbus->slot_base + slot * slotsize;
0049 extslotaddr = tbus->ext_slot_base + slot * extslotsize;
0050 module = ioremap(slotaddr, slotsize);
0051 BUG_ON(!module);
0052
0053 offset = TC_OLDCARD;
0054
0055 err = 0;
0056 err |= tc_preadb(pattern + 0, module + offset + TC_PATTERN0);
0057 err |= tc_preadb(pattern + 1, module + offset + TC_PATTERN1);
0058 err |= tc_preadb(pattern + 2, module + offset + TC_PATTERN2);
0059 err |= tc_preadb(pattern + 3, module + offset + TC_PATTERN3);
0060 if (err)
0061 goto out_err;
0062
0063 if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
0064 pattern[2] != 0xaa || pattern[3] != 0xff) {
0065 offset = TC_NEWCARD;
0066
0067 err = 0;
0068 err |= tc_preadb(pattern + 0,
0069 module + offset + TC_PATTERN0);
0070 err |= tc_preadb(pattern + 1,
0071 module + offset + TC_PATTERN1);
0072 err |= tc_preadb(pattern + 2,
0073 module + offset + TC_PATTERN2);
0074 err |= tc_preadb(pattern + 3,
0075 module + offset + TC_PATTERN3);
0076 if (err)
0077 goto out_err;
0078 }
0079
0080 if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
0081 pattern[2] != 0xaa || pattern[3] != 0xff)
0082 goto out_err;
0083
0084
0085 tdev = kzalloc(sizeof(*tdev), GFP_KERNEL);
0086 if (!tdev) {
0087 pr_err("tc%x: unable to allocate tc_dev\n", slot);
0088 goto out_err;
0089 }
0090 dev_set_name(&tdev->dev, "tc%x", slot);
0091 tdev->bus = tbus;
0092 tdev->dev.parent = &tbus->dev;
0093 tdev->dev.bus = &tc_bus_type;
0094 tdev->slot = slot;
0095
0096
0097 tdev->dma_mask = DMA_BIT_MASK(34);
0098 tdev->dev.dma_mask = &tdev->dma_mask;
0099 tdev->dev.coherent_dma_mask = DMA_BIT_MASK(34);
0100
0101 for (i = 0; i < 8; i++) {
0102 tdev->firmware[i] =
0103 readb(module + offset + TC_FIRM_VER + 4 * i);
0104 tdev->vendor[i] =
0105 readb(module + offset + TC_VENDOR + 4 * i);
0106 tdev->name[i] =
0107 readb(module + offset + TC_MODULE + 4 * i);
0108 }
0109 tdev->firmware[8] = 0;
0110 tdev->vendor[8] = 0;
0111 tdev->name[8] = 0;
0112
0113 pr_info("%s: %s %s %s\n", dev_name(&tdev->dev), tdev->vendor,
0114 tdev->name, tdev->firmware);
0115
0116 devsize = readb(module + offset + TC_SLOT_SIZE);
0117 devsize <<= 22;
0118 if (devsize <= slotsize) {
0119 tdev->resource.start = slotaddr;
0120 tdev->resource.end = slotaddr + devsize - 1;
0121 } else if (devsize <= extslotsize) {
0122 tdev->resource.start = extslotaddr;
0123 tdev->resource.end = extslotaddr + devsize - 1;
0124 } else {
0125 pr_err("%s: Cannot provide slot space "
0126 "(%ldMiB required, up to %ldMiB supported)\n",
0127 dev_name(&tdev->dev), (long)(devsize >> 20),
0128 (long)(max(slotsize, extslotsize) >> 20));
0129 kfree(tdev);
0130 goto out_err;
0131 }
0132 tdev->resource.name = tdev->name;
0133 tdev->resource.flags = IORESOURCE_MEM;
0134
0135 tc_device_get_irq(tdev);
0136
0137 if (device_register(&tdev->dev)) {
0138 put_device(&tdev->dev);
0139 goto out_err;
0140 }
0141 list_add_tail(&tdev->node, &tbus->devices);
0142
0143 out_err:
0144 iounmap(module);
0145 }
0146 }
0147
0148
0149
0150
0151 static int __init tc_init(void)
0152 {
0153
0154 if (tc_bus_get_info(&tc_bus))
0155 goto out_err;
0156
0157 INIT_LIST_HEAD(&tc_bus.devices);
0158 dev_set_name(&tc_bus.dev, "tc");
0159 if (device_register(&tc_bus.dev))
0160 goto out_err_device;
0161
0162 if (tc_bus.info.slot_size) {
0163 unsigned int tc_clock = tc_get_speed(&tc_bus) / 100000;
0164
0165 pr_info("tc: TURBOchannel rev. %d at %d.%d MHz "
0166 "(with%s parity)\n", tc_bus.info.revision,
0167 tc_clock / 10, tc_clock % 10,
0168 tc_bus.info.parity ? "" : "out");
0169
0170 tc_bus.resource[0].start = tc_bus.slot_base;
0171 tc_bus.resource[0].end = tc_bus.slot_base +
0172 (tc_bus.info.slot_size << 20) *
0173 tc_bus.num_tcslots - 1;
0174 tc_bus.resource[0].name = tc_bus.name;
0175 tc_bus.resource[0].flags = IORESOURCE_MEM;
0176 if (request_resource(&iomem_resource,
0177 &tc_bus.resource[0]) < 0) {
0178 pr_err("tc: Cannot reserve resource\n");
0179 goto out_err_device;
0180 }
0181 if (tc_bus.ext_slot_size) {
0182 tc_bus.resource[1].start = tc_bus.ext_slot_base;
0183 tc_bus.resource[1].end = tc_bus.ext_slot_base +
0184 tc_bus.ext_slot_size *
0185 tc_bus.num_tcslots - 1;
0186 tc_bus.resource[1].name = tc_bus.name;
0187 tc_bus.resource[1].flags = IORESOURCE_MEM;
0188 if (request_resource(&iomem_resource,
0189 &tc_bus.resource[1]) < 0) {
0190 pr_err("tc: Cannot reserve resource\n");
0191 goto out_err_resource;
0192 }
0193 }
0194
0195 tc_bus_add_devices(&tc_bus);
0196 }
0197
0198 return 0;
0199
0200 out_err_resource:
0201 release_resource(&tc_bus.resource[0]);
0202 out_err_device:
0203 put_device(&tc_bus.dev);
0204 out_err:
0205 return 0;
0206 }
0207
0208 subsys_initcall(tc_init);