diff options
| author | David S. Miller <davem@sunset.davemloft.net> | 2007-07-19 02:15:04 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-20 20:15:35 -0400 |
| commit | 0fe85d504b47267bcdb25a563c535aa2ae075ff4 (patch) | |
| tree | 6c91dffa8bc2c06f6621cff468c26210f174e1ce /include | |
| parent | 3adf55ad5c0fcabf1c53bb274f39953cb1d6698f (diff) | |
[SPARC64]: Convert parport to of_platform_driver.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-sparc64/parport.h | 233 |
1 files changed, 133 insertions, 100 deletions
diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h index 23cc63f049a8..600afe5ae2e3 100644 --- a/include/asm-sparc64/parport.h +++ b/include/asm-sparc64/parport.h | |||
| @@ -8,8 +8,9 @@ | |||
| 8 | #define _ASM_SPARC64_PARPORT_H 1 | 8 | #define _ASM_SPARC64_PARPORT_H 1 |
| 9 | 9 | ||
| 10 | #include <asm/ebus.h> | 10 | #include <asm/ebus.h> |
| 11 | #include <asm/isa.h> | ||
| 12 | #include <asm/ns87303.h> | 11 | #include <asm/ns87303.h> |
| 12 | #include <asm/of_device.h> | ||
| 13 | #include <asm/prom.h> | ||
| 13 | 14 | ||
| 14 | #define PARPORT_PC_MAX_PORTS PARPORT_MAX | 15 | #define PARPORT_PC_MAX_PORTS PARPORT_MAX |
| 15 | 16 | ||
| @@ -35,8 +36,12 @@ static struct sparc_ebus_info { | |||
| 35 | unsigned int addr; | 36 | unsigned int addr; |
| 36 | unsigned int count; | 37 | unsigned int count; |
| 37 | int lock; | 38 | int lock; |
| 39 | |||
| 40 | struct parport *port; | ||
| 38 | } sparc_ebus_dmas[PARPORT_PC_MAX_PORTS]; | 41 | } sparc_ebus_dmas[PARPORT_PC_MAX_PORTS]; |
| 39 | 42 | ||
| 43 | static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS); | ||
| 44 | |||
| 40 | static __inline__ int request_dma(unsigned int dmanr, const char *device_id) | 45 | static __inline__ int request_dma(unsigned int dmanr, const char *device_id) |
| 41 | { | 46 | { |
| 42 | if (dmanr >= PARPORT_PC_MAX_PORTS) | 47 | if (dmanr >= PARPORT_PC_MAX_PORTS) |
| @@ -98,117 +103,145 @@ static __inline__ unsigned int get_dma_residue(unsigned int dmanr) | |||
| 98 | return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); | 103 | return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); |
| 99 | } | 104 | } |
| 100 | 105 | ||
| 101 | static int ebus_ecpp_p(struct linux_ebus_device *edev) | 106 | static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id *match) |
| 102 | { | 107 | { |
| 103 | if (!strcmp(edev->prom_node->name, "ecpp")) | 108 | unsigned long base = op->resource[0].start; |
| 104 | return 1; | 109 | unsigned long config = op->resource[1].start; |
| 105 | if (!strcmp(edev->prom_node->name, "parallel")) { | 110 | unsigned long d_base = op->resource[2].start; |
| 106 | const char *compat; | 111 | unsigned long d_len; |
| 107 | 112 | struct device_node *parent; | |
| 108 | compat = of_get_property(edev->prom_node, | 113 | struct parport *p; |
| 109 | "compatible", NULL); | 114 | int slot, err; |
| 110 | if (compat && | 115 | |
| 111 | (!strcmp(compat, "ecpp") || | 116 | parent = op->node->parent; |
| 112 | !strcmp(compat, "ns87317-ecpp") || | 117 | if (!strcmp(parent->name, "dma")) { |
| 113 | !strcmp(compat + 13, "ecpp"))) | 118 | p = parport_pc_probe_port(base, base + 0x400, |
| 114 | return 1; | 119 | op->irqs[0], PARPORT_DMA_NOFIFO, |
| 120 | op->dev.parent); | ||
| 121 | if (!p) | ||
| 122 | return -ENOMEM; | ||
| 123 | dev_set_drvdata(&op->dev, p); | ||
| 124 | return 0; | ||
| 115 | } | 125 | } |
| 126 | |||
| 127 | for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) { | ||
| 128 | if (!test_and_set_bit(slot, dma_slot_map)) | ||
| 129 | break; | ||
| 130 | } | ||
| 131 | err = -ENODEV; | ||
| 132 | if (slot >= PARPORT_PC_MAX_PORTS) | ||
| 133 | goto out_err; | ||
| 134 | |||
| 135 | spin_lock_init(&sparc_ebus_dmas[slot].info.lock); | ||
| 136 | |||
| 137 | d_len = (op->resource[2].end - d_base) + 1UL; | ||
| 138 | sparc_ebus_dmas[slot].info.regs = | ||
| 139 | of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA"); | ||
| 140 | |||
| 141 | if (!sparc_ebus_dmas[slot].info.regs) | ||
| 142 | goto out_clear_map; | ||
| 143 | |||
| 144 | sparc_ebus_dmas[slot].info.flags = 0; | ||
| 145 | sparc_ebus_dmas[slot].info.callback = NULL; | ||
| 146 | sparc_ebus_dmas[slot].info.client_cookie = NULL; | ||
| 147 | sparc_ebus_dmas[slot].info.irq = 0xdeadbeef; | ||
| 148 | strcpy(sparc_ebus_dmas[slot].info.name, "parport"); | ||
| 149 | if (ebus_dma_register(&sparc_ebus_dmas[slot].info)) | ||
| 150 | goto out_unmap_regs; | ||
| 151 | |||
| 152 | ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1); | ||
| 153 | |||
| 154 | /* Configure IRQ to Push Pull, Level Low */ | ||
| 155 | /* Enable ECP, set bit 2 of the CTR first */ | ||
| 156 | outb(0x04, base + 0x02); | ||
| 157 | ns87303_modify(config, PCR, | ||
| 158 | PCR_EPP_ENABLE | | ||
| 159 | PCR_IRQ_ODRAIN, | ||
| 160 | PCR_ECP_ENABLE | | ||
| 161 | PCR_ECP_CLK_ENA | | ||
| 162 | PCR_IRQ_POLAR); | ||
| 163 | |||
| 164 | /* CTR bit 5 controls direction of port */ | ||
| 165 | ns87303_modify(config, PTR, | ||
| 166 | 0, PTR_LPT_REG_DIR); | ||
| 167 | |||
| 168 | p = parport_pc_probe_port(base, base + 0x400, | ||
| 169 | op->irqs[0], | ||
| 170 | slot, | ||
| 171 | op->dev.parent); | ||
| 172 | err = -ENOMEM; | ||
| 173 | if (!p) | ||
| 174 | goto out_disable_irq; | ||
| 175 | |||
| 176 | dev_set_drvdata(&op->dev, p); | ||
| 177 | |||
| 116 | return 0; | 178 | return 0; |
| 179 | |||
| 180 | out_disable_irq: | ||
| 181 | ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0); | ||
| 182 | ebus_dma_unregister(&sparc_ebus_dmas[slot].info); | ||
| 183 | |||
| 184 | out_unmap_regs: | ||
| 185 | of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len); | ||
| 186 | |||
| 187 | out_clear_map: | ||
| 188 | clear_bit(slot, dma_slot_map); | ||
| 189 | |||
| 190 | out_err: | ||
| 191 | return err; | ||
| 117 | } | 192 | } |
| 118 | 193 | ||
| 119 | static int parport_isa_probe(int count) | 194 | static int __devexit ecpp_remove(struct of_device *op) |
| 120 | { | 195 | { |
| 121 | struct sparc_isa_bridge *isa_br; | 196 | struct parport *p = dev_get_drvdata(&op->dev); |
| 122 | struct sparc_isa_device *isa_dev; | 197 | int slot = p->dma; |
| 123 | 198 | ||
| 124 | for_each_isa(isa_br) { | 199 | parport_pc_unregister_port(p); |
| 125 | for_each_isadev(isa_dev, isa_br) { | 200 | |
| 126 | struct sparc_isa_device *child; | 201 | if (slot != PARPORT_DMA_NOFIFO) { |
| 127 | unsigned long base; | 202 | unsigned long d_base = op->resource[2].start; |
| 128 | 203 | unsigned long d_len; | |
| 129 | if (strcmp(isa_dev->prom_node->name, "dma")) | 204 | |
| 130 | continue; | 205 | d_len = (op->resource[2].end - d_base) + 1UL; |
| 131 | 206 | ||
| 132 | child = isa_dev->child; | 207 | ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0); |
| 133 | while (child) { | 208 | ebus_dma_unregister(&sparc_ebus_dmas[slot].info); |
| 134 | if (!strcmp(child->prom_node->name, "parallel")) | 209 | of_iounmap(&op->resource[2], |
| 135 | break; | 210 | sparc_ebus_dmas[slot].info.regs, |
| 136 | child = child->next; | 211 | d_len); |
| 137 | } | 212 | clear_bit(slot, dma_slot_map); |
| 138 | if (!child) | ||
| 139 | continue; | ||
| 140 | |||
| 141 | base = child->resource.start; | ||
| 142 | |||
| 143 | /* No DMA, see commentary in | ||
| 144 | * asm-sparc64/floppy.h:isa_floppy_init() | ||
| 145 | */ | ||
| 146 | if (parport_pc_probe_port(base, base + 0x400, | ||
| 147 | child->irq, PARPORT_DMA_NOFIFO, | ||
| 148 | &child->bus->self->dev)) | ||
| 149 | count++; | ||
| 150 | } | ||
| 151 | } | 213 | } |
| 152 | 214 | ||
| 153 | return count; | 215 | return 0; |
| 154 | } | 216 | } |
| 155 | 217 | ||
| 156 | static int parport_pc_find_nonpci_ports (int autoirq, int autodma) | 218 | static struct of_device_id ecpp_match[] = { |
| 219 | { | ||
| 220 | .name = "ecpp", | ||
| 221 | }, | ||
| 22 | |||
