Blame view

drivers/ata/pata_platform.c 6.62 KB
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
1
2
3
  /*
   * Generic platform device PATA driver
   *
f7fc0ceb4   Paul Mundt   libata: pata_plat...
4
   * Copyright (C) 2006 - 2007  Paul Mundt
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
5
6
7
   *
   * Based on pata_pcmcia:
   *
ab7716300   Alan Cox   ata: Switch all m...
8
   *   Copyright 2005-2006 Red Hat Inc, all rights reserved.
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
9
10
11
12
13
14
15
   *
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   */
  #include <linux/kernel.h>
  #include <linux/module.h>
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
16
17
18
19
20
  #include <linux/blkdev.h>
  #include <scsi/scsi_host.h>
  #include <linux/ata.h>
  #include <linux/libata.h>
  #include <linux/platform_device.h>
0a87e3e92   Jeff Garzik   Rename: linux/pat...
21
  #include <linux/ata_platform.h>
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
22
23
  
  #define DRV_NAME "pata_platform"
f7fc0ceb4   Paul Mundt   libata: pata_plat...
24
  #define DRV_VERSION "1.2"
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
25
26
27
28
29
30
31
  
  static int pio_mask = 1;
  
  /*
   * Provide our own set_mode() as we don't want to change anything that has
   * already been configured..
   */
0260731f0   Tejun Heo   libata-link: link...
32
  static int pata_platform_set_mode(struct ata_link *link, struct ata_device **unused)
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
33
  {
f58229f80   Tejun Heo   libata-link: impl...
34
  	struct ata_device *dev;
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
35

1eca4365b   Tejun Heo   libata: beef up i...
36
37
38
39
40
  	ata_for_each_dev(dev, link, ENABLED) {
  		/* We don't really care */
  		dev->pio_mode = dev->xfer_mode = XFER_PIO_0;
  		dev->xfer_shift = ATA_SHIFT_PIO;
  		dev->flags |= ATA_DFLAG_PIO;
a9a79dfec   Joe Perches   ata: Convert ata_...
41
42
  		ata_dev_info(dev, "configured for PIO
  ");
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
43
  	}
161c888b0   Al Viro   [PATCH] pata_plat...
44
  	return 0;
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
45
  }
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
46
  static struct scsi_host_template pata_platform_sht = {
68d1d07b5   Tejun Heo   libata: implement...
47
  	ATA_PIO_SHT(DRV_NAME),
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
48
  };
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
49
  static void pata_platform_setup_port(struct ata_ioports *ioaddr,
cf03613e9   Anton Vorontsov   libata: pata_plat...
50
  				     unsigned int shift)
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
51
  {
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
52
  	/* Fixup the port shift for platforms that need it */
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
53
54
55
56
57
58
59
60
61
62
63
64
65
  	ioaddr->data_addr	= ioaddr->cmd_addr + (ATA_REG_DATA    << shift);
  	ioaddr->error_addr	= ioaddr->cmd_addr + (ATA_REG_ERR     << shift);
  	ioaddr->feature_addr	= ioaddr->cmd_addr + (ATA_REG_FEATURE << shift);
  	ioaddr->nsect_addr	= ioaddr->cmd_addr + (ATA_REG_NSECT   << shift);
  	ioaddr->lbal_addr	= ioaddr->cmd_addr + (ATA_REG_LBAL    << shift);
  	ioaddr->lbam_addr	= ioaddr->cmd_addr + (ATA_REG_LBAM    << shift);
  	ioaddr->lbah_addr	= ioaddr->cmd_addr + (ATA_REG_LBAH    << shift);
  	ioaddr->device_addr	= ioaddr->cmd_addr + (ATA_REG_DEVICE  << shift);
  	ioaddr->status_addr	= ioaddr->cmd_addr + (ATA_REG_STATUS  << shift);
  	ioaddr->command_addr	= ioaddr->cmd_addr + (ATA_REG_CMD     << shift);
  }
  
  /**
cf03613e9   Anton Vorontsov   libata: pata_plat...
66
67
68
69
70
71
72
   *	__pata_platform_probe		-	attach a platform interface
   *	@dev: device
   *	@io_res: Resource representing I/O base
   *	@ctl_res: Resource representing CTL base
   *	@irq_res: Resource representing IRQ and its flags
   *	@ioport_shift: I/O port shift
   *	@__pio_mask: PIO mask
172639053   Akinobu Mita   ata: pata_platfor...
73
   *	@sht: scsi_host_template to use when registering
f3d5e4f18   Alexander Shiyan   ata: pata_of_plat...
74
   *	@use16bit: Flag to indicate 16-bit IO instead of 32-bit
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
75
76
77
78
   *
   *	Register a platform bus IDE interface. Such interfaces are PIO and we
   *	assume do not support IRQ sharing.
   *
f7fc0ceb4   Paul Mundt   libata: pata_plat...
79
   *	Platform devices are expected to contain at least 2 resources per port:
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
80
81
82
   *
   *		- I/O Base (IORESOURCE_IO or IORESOURCE_MEM)
   *		- CTL Base (IORESOURCE_IO or IORESOURCE_MEM)
f7fc0ceb4   Paul Mundt   libata: pata_plat...
83
84
85
   *
   *	and optionally:
   *
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
86
87
88
89
90
   *		- IRQ	   (IORESOURCE_IRQ)
   *
   *	If the base resources are both mem types, the ioremap() is handled
   *	here. For IORESOURCE_IO, it's assumed that there's no remapping
   *	necessary.
f7fc0ceb4   Paul Mundt   libata: pata_plat...
91
92
   *
   *	If no IRQ resource is present, PIO polling mode is used instead.
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
93
   */
0ec249146   Greg Kroah-Hartman   Drivers: ata: rem...
94
95
  int __pata_platform_probe(struct device *dev, struct resource *io_res,
  			  struct resource *ctl_res, struct resource *irq_res,
172639053   Akinobu Mita   ata: pata_platfor...
96
  			  unsigned int ioport_shift, int __pio_mask,
f3d5e4f18   Alexander Shiyan   ata: pata_of_plat...
97
  			  struct scsi_host_template *sht, bool use16bit)
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
98
  {
5d728824e   Tejun Heo   libata: convert t...
99
100
  	struct ata_host *host;
  	struct ata_port *ap;
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
101
  	unsigned int mmio;
cf03613e9   Anton Vorontsov   libata: pata_plat...
102
103
  	int irq = 0;
  	int irq_flags = 0;
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
104
105
106
107
108
109
110
111
  
  	/*
  	 * Check for MMIO
  	 */
  	mmio = (( io_res->flags == IORESOURCE_MEM) &&
  		(ctl_res->flags == IORESOURCE_MEM));
  
  	/*
f7fc0ceb4   Paul Mundt   libata: pata_plat...
112
113
  	 * And the IRQ
  	 */
cf03613e9   Anton Vorontsov   libata: pata_plat...
114
115
  	if (irq_res && irq_res->start > 0) {
  		irq = irq_res->start;
baac9ce1f   Alexander Shiyan   ata: pata_platfor...
116
  		irq_flags = (irq_res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED;
cf03613e9   Anton Vorontsov   libata: pata_plat...
117
  	}
f7fc0ceb4   Paul Mundt   libata: pata_plat...
118
119
  
  	/*
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
120
121
  	 * Now that that's out of the way, wire up the port..
  	 */
cf03613e9   Anton Vorontsov   libata: pata_plat...
122
  	host = ata_host_alloc(dev, 1);
5d728824e   Tejun Heo   libata: convert t...
123
124
125
  	if (!host)
  		return -ENOMEM;
  	ap = host->ports[0];
f3d5e4f18   Alexander Shiyan   ata: pata_of_plat...
126
127
128
129
130
131
132
133
  	ap->ops = devm_kzalloc(dev, sizeof(*ap->ops), GFP_KERNEL);
  	ap->ops->inherits = &ata_sff_port_ops;
  	ap->ops->cable_detect = ata_cable_unknown;
  	ap->ops->set_mode = pata_platform_set_mode;
  	if (use16bit)
  		ap->ops->sff_data_xfer = ata_sff_data_xfer;
  	else
  		ap->ops->sff_data_xfer = ata_sff_data_xfer32;
cf03613e9   Anton Vorontsov   libata: pata_plat...
134
  	ap->pio_mask = __pio_mask;
5d728824e   Tejun Heo   libata: convert t...
135
  	ap->flags |= ATA_FLAG_SLAVE_POSS;
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
136
137
  
  	/*
f7fc0ceb4   Paul Mundt   libata: pata_plat...
138
139
140
141
142
143
144
145
  	 * Use polling mode if there's no IRQ
  	 */
  	if (!irq) {
  		ap->flags |= ATA_FLAG_PIO_POLLING;
  		ata_port_desc(ap, "no IRQ, using PIO polling");
  	}
  
  	/*
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
146
147
148
  	 * Handle the MMIO case
  	 */
  	if (mmio) {
cf03613e9   Anton Vorontsov   libata: pata_plat...
149
  		ap->ioaddr.cmd_addr = devm_ioremap(dev, io_res->start,
041b5eac2   Julia Lawall   drivers/ata: use ...
150
  				resource_size(io_res));
cf03613e9   Anton Vorontsov   libata: pata_plat...
151
  		ap->ioaddr.ctl_addr = devm_ioremap(dev, ctl_res->start,
041b5eac2   Julia Lawall   drivers/ata: use ...
152
  				resource_size(ctl_res));
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
153
  	} else {
cf03613e9   Anton Vorontsov   libata: pata_plat...
154
  		ap->ioaddr.cmd_addr = devm_ioport_map(dev, io_res->start,
041b5eac2   Julia Lawall   drivers/ata: use ...
155
  				resource_size(io_res));
cf03613e9   Anton Vorontsov   libata: pata_plat...
156
  		ap->ioaddr.ctl_addr = devm_ioport_map(dev, ctl_res->start,
041b5eac2   Julia Lawall   drivers/ata: use ...
157
  				resource_size(ctl_res));
0d5ff5667   Tejun Heo   libata: convert t...
158
  	}
5d728824e   Tejun Heo   libata: convert t...
159
  	if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) {
cf03613e9   Anton Vorontsov   libata: pata_plat...
160
161
  		dev_err(dev, "failed to map IO/CTL base
  ");
0d5ff5667   Tejun Heo   libata: convert t...
162
  		return -ENOMEM;
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
163
  	}
5d728824e   Tejun Heo   libata: convert t...
164
  	ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
165

cf03613e9   Anton Vorontsov   libata: pata_plat...
166
  	pata_platform_setup_port(&ap->ioaddr, ioport_shift);
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
167

cbcdd8759   Tejun Heo   libata: implement...
168
169
170
  	ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport",
  		      (unsigned long long)io_res->start,
  		      (unsigned long long)ctl_res->start);
5d728824e   Tejun Heo   libata: convert t...
171
  	/* activate */
9363c3825   Tejun Heo   libata: rename SF...
172
  	return ata_host_activate(host, irq, irq ? ata_sff_interrupt : NULL,
172639053   Akinobu Mita   ata: pata_platfor...
173
  				 irq_flags, sht);
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
174
  }
cf03613e9   Anton Vorontsov   libata: pata_plat...
175
  EXPORT_SYMBOL_GPL(__pata_platform_probe);
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
176

0ec249146   Greg Kroah-Hartman   Drivers: ata: rem...
177
  static int pata_platform_probe(struct platform_device *pdev)
cf03613e9   Anton Vorontsov   libata: pata_plat...
178
179
180
181
  {
  	struct resource *io_res;
  	struct resource *ctl_res;
  	struct resource *irq_res;
61b8c345a   Jingoo Han   ata: use dev_get_...
182
  	struct pata_platform_info *pp_info = dev_get_platdata(&pdev->dev);
cf03613e9   Anton Vorontsov   libata: pata_plat...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  
  	/*
  	 * Simple resource validation ..
  	 */
  	if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) {
  		dev_err(&pdev->dev, "invalid number of resources
  ");
  		return -EINVAL;
  	}
  
  	/*
  	 * Get the I/O base first
  	 */
  	io_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
  	if (io_res == NULL) {
  		io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  		if (unlikely(io_res == NULL))
  			return -EINVAL;
  	}
  
  	/*
  	 * Then the CTL base
  	 */
  	ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1);
  	if (ctl_res == NULL) {
  		ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  		if (unlikely(ctl_res == NULL))
  			return -EINVAL;
  	}
  
  	/*
  	 * And the IRQ
  	 */
  	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
cf03613e9   Anton Vorontsov   libata: pata_plat...
217
218
219
  
  	return __pata_platform_probe(&pdev->dev, io_res, ctl_res, irq_res,
  				     pp_info ? pp_info->ioport_shift : 0,
f3d5e4f18   Alexander Shiyan   ata: pata_of_plat...
220
  				     pio_mask, &pata_platform_sht, false);
cf03613e9   Anton Vorontsov   libata: pata_plat...
221
  }
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
222
223
  static struct platform_driver pata_platform_driver = {
  	.probe		= pata_platform_probe,
ccd1196a9   Brian Norris   pata_platform: ut...
224
  	.remove		= ata_platform_remove_one,
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
225
226
  	.driver = {
  		.name		= DRV_NAME,
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
227
228
  	},
  };
99c8ea3e5   Axel Lin   SATA/PATA: conver...
229
  module_platform_driver(pata_platform_driver);
a20c9e820   Paul Mundt   [PATCH] ata: Gene...
230
231
232
233
234
235
236
  
  module_param(pio_mask, int, 0);
  
  MODULE_AUTHOR("Paul Mundt");
  MODULE_DESCRIPTION("low-level driver for platform device ATA");
  MODULE_LICENSE("GPL");
  MODULE_VERSION(DRV_VERSION);
458622fcd   Kay Sievers   ATA/IDE: fix plat...
237
  MODULE_ALIAS("platform:" DRV_NAME);