Skip to content

Commit 2c4ac99

Browse files
committed
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: drivers/ata/sata_dwc_460ex.c: add missing kfree ata: Add iMX pata support pata_via: disable ATAPI DMA on AVERATEC 3200 [libata] sata_sil: fix used-uninit warning
2 parents 35a21b4 + a081da6 commit 2c4ac99

File tree

6 files changed

+288
-9
lines changed

6 files changed

+288
-9
lines changed

drivers/ata/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,15 @@ config PATA_ICSIDE
468468
interface card. This is not required for ICS partition support.
469469
If you are unsure, say N to this.
470470

471+
config PATA_IMX
472+
tristate "PATA support for Freescale iMX"
473+
depends on ARCH_MXC
474+
help
475+
This option enables support for the PATA host available on Freescale
476+
iMX SoCs.
477+
478+
If unsure, say N.
479+
471480
config PATA_IT8213
472481
tristate "IT8213 PATA support (Experimental)"
473482
depends on PCI && EXPERIMENTAL

drivers/ata/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o
4848
obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o
4949
obj-$(CONFIG_PATA_HPT3X3) += pata_hpt3x3.o
5050
obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o
51+
obj-$(CONFIG_PATA_IMX) += pata_imx.o
5152
obj-$(CONFIG_PATA_IT8213) += pata_it8213.o
5253
obj-$(CONFIG_PATA_IT821X) += pata_it821x.o
5354
obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o

drivers/ata/pata_imx.c

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
/*
2+
* Freescale iMX PATA driver
3+
*
4+
* Copyright (C) 2011 Arnaud Patard <[email protected]>
5+
*
6+
* Based on pata_platform - Copyright (C) 2006 - 2007 Paul Mundt
7+
*
8+
* This file is subject to the terms and conditions of the GNU General Public
9+
* License. See the file "COPYING" in the main directory of this archive
10+
* for more details.
11+
*
12+
* TODO:
13+
* - dmaengine support
14+
* - check if timing stuff needed
15+
*/
16+
#include <linux/kernel.h>
17+
#include <linux/module.h>
18+
#include <linux/init.h>
19+
#include <linux/blkdev.h>
20+
#include <scsi/scsi_host.h>
21+
#include <linux/ata.h>
22+
#include <linux/libata.h>
23+
#include <linux/platform_device.h>
24+
#include <linux/clk.h>
25+
26+
#define DRV_NAME "pata_imx"
27+
28+
#define PATA_IMX_ATA_CONTROL 0x24
29+
#define PATA_IMX_ATA_CTRL_FIFO_RST_B (1<<7)
30+
#define PATA_IMX_ATA_CTRL_ATA_RST_B (1<<6)
31+
#define PATA_IMX_ATA_CTRL_IORDY_EN (1<<0)
32+
#define PATA_IMX_ATA_INT_EN 0x2C
33+
#define PATA_IMX_ATA_INTR_ATA_INTRQ2 (1<<3)
34+
#define PATA_IMX_DRIVE_DATA 0xA0
35+
#define PATA_IMX_DRIVE_CONTROL 0xD8
36+
37+
struct pata_imx_priv {
38+
struct clk *clk;
39+
/* timings/interrupt/control regs */
40+
u8 *host_regs;
41+
u32 ata_ctl;
42+
};
43+
44+
static int pata_imx_set_mode(struct ata_link *link, struct ata_device **unused)
45+
{
46+
struct ata_device *dev;
47+
struct ata_port *ap = link->ap;
48+
struct pata_imx_priv *priv = ap->host->private_data;
49+
u32 val;
50+
51+
ata_for_each_dev(dev, link, ENABLED) {
52+
dev->pio_mode = dev->xfer_mode = XFER_PIO_0;
53+
dev->xfer_shift = ATA_SHIFT_PIO;
54+
dev->flags |= ATA_DFLAG_PIO;
55+
56+
val = __raw_readl(priv->host_regs + PATA_IMX_ATA_CONTROL);
57+
if (ata_pio_need_iordy(dev))
58+
val |= PATA_IMX_ATA_CTRL_IORDY_EN;
59+
else
60+
val &= ~PATA_IMX_ATA_CTRL_IORDY_EN;
61+
__raw_writel(val, priv->host_regs + PATA_IMX_ATA_CONTROL);
62+
63+
ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
64+
}
65+
return 0;
66+
}
67+
68+
static struct scsi_host_template pata_imx_sht = {
69+
ATA_PIO_SHT(DRV_NAME),
70+
};
71+
72+
static struct ata_port_operations pata_imx_port_ops = {
73+
.inherits = &ata_sff_port_ops,
74+
.sff_data_xfer = ata_sff_data_xfer_noirq,
75+
.cable_detect = ata_cable_unknown,
76+
.set_mode = pata_imx_set_mode,
77+
};
78+
79+
static void pata_imx_setup_port(struct ata_ioports *ioaddr)
80+
{
81+
/* Fixup the port shift for platforms that need it */
82+
ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << 2);
83+
ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << 2);
84+
ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << 2);
85+
ioaddr->nsect_addr = ioaddr->cmd_addr + (ATA_REG_NSECT << 2);
86+
ioaddr->lbal_addr = ioaddr->cmd_addr + (ATA_REG_LBAL << 2);
87+
ioaddr->lbam_addr = ioaddr->cmd_addr + (ATA_REG_LBAM << 2);
88+
ioaddr->lbah_addr = ioaddr->cmd_addr + (ATA_REG_LBAH << 2);
89+
ioaddr->device_addr = ioaddr->cmd_addr + (ATA_REG_DEVICE << 2);
90+
ioaddr->status_addr = ioaddr->cmd_addr + (ATA_REG_STATUS << 2);
91+
ioaddr->command_addr = ioaddr->cmd_addr + (ATA_REG_CMD << 2);
92+
}
93+
94+
static int __devinit pata_imx_probe(struct platform_device *pdev)
95+
{
96+
struct ata_host *host;
97+
struct ata_port *ap;
98+
struct pata_imx_priv *priv;
99+
int irq = 0;
100+
struct resource *io_res;
101+
102+
io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
103+
if (io_res == NULL)
104+
return -EINVAL;
105+
106+
irq = platform_get_irq(pdev, 0);
107+
if (irq <= 0)
108+
return -EINVAL;
109+
110+
priv = devm_kzalloc(&pdev->dev,
111+
sizeof(struct pata_imx_priv), GFP_KERNEL);
112+
if (!priv)
113+
return -ENOMEM;
114+
115+
priv->clk = clk_get(&pdev->dev, NULL);
116+
if (IS_ERR(priv->clk)) {
117+
dev_err(&pdev->dev, "Failed to get clock\n");
118+
return PTR_ERR(priv->clk);
119+
}
120+
121+
clk_enable(priv->clk);
122+
123+
host = ata_host_alloc(&pdev->dev, 1);
124+
if (!host)
125+
goto free_priv;
126+
127+
host->private_data = priv;
128+
ap = host->ports[0];
129+
130+
ap->ops = &pata_imx_port_ops;
131+
ap->pio_mask = ATA_PIO0;
132+
ap->flags |= ATA_FLAG_SLAVE_POSS;
133+
134+
priv->host_regs = devm_ioremap(&pdev->dev, io_res->start,
135+
resource_size(io_res));
136+
if (!priv->host_regs) {
137+
dev_err(&pdev->dev, "failed to map IO/CTL base\n");
138+
goto free_priv;
139+
}
140+
141+
ap->ioaddr.cmd_addr = priv->host_regs + PATA_IMX_DRIVE_DATA;
142+
ap->ioaddr.ctl_addr = priv->host_regs + PATA_IMX_DRIVE_CONTROL;
143+
144+
ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
145+
146+
pata_imx_setup_port(&ap->ioaddr);
147+
148+
ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
149+
(unsigned long long)io_res->start + PATA_IMX_DRIVE_DATA,
150+
(unsigned long long)io_res->start + PATA_IMX_DRIVE_CONTROL);
151+
152+
/* deassert resets */
153+
__raw_writel(PATA_IMX_ATA_CTRL_FIFO_RST_B |
154+
PATA_IMX_ATA_CTRL_ATA_RST_B,
155+
priv->host_regs + PATA_IMX_ATA_CONTROL);
156+
/* enable interrupts */
157+
__raw_writel(PATA_IMX_ATA_INTR_ATA_INTRQ2,
158+
priv->host_regs + PATA_IMX_ATA_INT_EN);
159+
160+
/* activate */
161+
return ata_host_activate(host, irq, ata_sff_interrupt, 0,
162+
&pata_imx_sht);
163+
164+
free_priv:
165+
clk_disable(priv->clk);
166+
clk_put(priv->clk);
167+
return -ENOMEM;
168+
}
169+
170+
static int __devexit pata_imx_remove(struct platform_device *pdev)
171+
{
172+
struct ata_host *host = dev_get_drvdata(&pdev->dev);
173+
struct pata_imx_priv *priv = host->private_data;
174+
175+
ata_host_detach(host);
176+
177+
__raw_writel(0, priv->host_regs + PATA_IMX_ATA_INT_EN);
178+
179+
clk_disable(priv->clk);
180+
clk_put(priv->clk);
181+
182+
return 0;
183+
}
184+
185+
#ifdef CONFIG_PM
186+
static int pata_imx_suspend(struct device *dev)
187+
{
188+
struct ata_host *host = dev_get_drvdata(dev);
189+
struct pata_imx_priv *priv = host->private_data;
190+
int ret;
191+
192+
ret = ata_host_suspend(host, PMSG_SUSPEND);
193+
if (!ret) {
194+
__raw_writel(0, priv->host_regs + PATA_IMX_ATA_INT_EN);
195+
priv->ata_ctl =
196+
__raw_readl(priv->host_regs + PATA_IMX_ATA_CONTROL);
197+
clk_disable(priv->clk);
198+
}
199+
200+
return ret;
201+
}
202+
203+
static int pata_imx_resume(struct device *dev)
204+
{
205+
struct ata_host *host = dev_get_drvdata(dev);
206+
struct pata_imx_priv *priv = host->private_data;
207+
208+
clk_enable(priv->clk);
209+
210+
__raw_writel(priv->ata_ctl, priv->host_regs + PATA_IMX_ATA_CONTROL);
211+
212+
__raw_writel(PATA_IMX_ATA_INTR_ATA_INTRQ2,
213+
priv->host_regs + PATA_IMX_ATA_INT_EN);
214+
215+
ata_host_resume(host);
216+
217+
return 0;
218+
}
219+
220+
static const struct dev_pm_ops pata_imx_pm_ops = {
221+
.suspend = pata_imx_suspend,
222+
.resume = pata_imx_resume,
223+
};
224+
#endif
225+
226+
static struct platform_driver pata_imx_driver = {
227+
.probe = pata_imx_probe,
228+
.remove = __devexit_p(pata_imx_remove),
229+
.driver = {
230+
.name = DRV_NAME,
231+
.owner = THIS_MODULE,
232+
#ifdef CONFIG_PM
233+
.pm = &pata_imx_pm_ops,
234+
#endif
235+
},
236+
};
237+
238+
static int __init pata_imx_init(void)
239+
{
240+
return platform_driver_register(&pata_imx_driver);
241+
}
242+
243+
static void __exit pata_imx_exit(void)
244+
{
245+
platform_driver_unregister(&pata_imx_driver);
246+
}
247+
module_init(pata_imx_init);
248+
module_exit(pata_imx_exit);
249+
250+
MODULE_AUTHOR("Arnaud Patard <[email protected]>");
251+
MODULE_DESCRIPTION("low-level driver for iMX PATA");
252+
MODULE_LICENSE("GPL");
253+
MODULE_ALIAS("platform:" DRV_NAME);

drivers/ata/pata_via.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ static const struct via_isa_bridge {
124124
{ NULL }
125125
};
126126

127+
static const struct dmi_system_id no_atapi_dma_dmi_table[] = {
128+
{
129+
.ident = "AVERATEC 3200",
130+
.matches = {
131+
DMI_MATCH(DMI_BOARD_VENDOR, "AVERATEC"),
132+
DMI_MATCH(DMI_BOARD_NAME, "3200"),
133+
},
134+
},
135+
{ }
136+
};
137+
127138
struct via_port {
128139
u8 cached_device;
129140
};
@@ -355,6 +366,13 @@ static unsigned long via_mode_filter(struct ata_device *dev, unsigned long mask)
355366
mask &= ~ ATA_MASK_UDMA;
356367
}
357368
}
369+
370+
if (dev->class == ATA_DEV_ATAPI &&
371+
dmi_check_system(no_atapi_dma_dmi_table)) {
372+
ata_dev_warn(dev, "controller locks up on ATAPI DMA, forcing PIO\n");
373+
mask &= ATA_MASK_PIO;
374+
}
375+
358376
return mask;
359377
}
360378

drivers/ata/sata_dwc_460ex.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,7 @@ static int sata_dwc_port_start(struct ata_port *ap)
13291329
dev_err(ap->dev, "%s: dma_alloc_coherent failed\n",
13301330
__func__);
13311331
err = -ENOMEM;
1332-
goto CLEANUP;
1332+
goto CLEANUP_ALLOC;
13331333
}
13341334
}
13351335

@@ -1349,15 +1349,13 @@ static int sata_dwc_port_start(struct ata_port *ap)
13491349
/* Clear any error bits before libata starts issuing commands */
13501350
clear_serror();
13511351
ap->private_data = hsdevp;
1352+
dev_dbg(ap->dev, "%s: done\n", __func__);
1353+
return 0;
13521354

1355+
CLEANUP_ALLOC:
1356+
kfree(hsdevp);
13531357
CLEANUP:
1354-
if (err) {
1355-
sata_dwc_port_stop(ap);
1356-
dev_dbg(ap->dev, "%s: fail\n", __func__);
1357-
} else {
1358-
dev_dbg(ap->dev, "%s: done\n", __func__);
1359-
}
1360-
1358+
dev_dbg(ap->dev, "%s: fail. ap->id = %d\n", __func__, ap->print_id);
13611359
return err;
13621360
}
13631361

drivers/ata/sata_sil.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
438438
u8 status;
439439

440440
if (unlikely(bmdma2 & SIL_DMA_SATA_IRQ)) {
441-
u32 serror;
441+
u32 serror = 0xffffffff;
442442

443443
/* SIEN doesn't mask SATA IRQs on some 3112s. Those
444444
* controllers continue to assert IRQ as long as

0 commit comments

Comments
 (0)