hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/ata/ahci_qoriq.c
....@@ -1,15 +1,12 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Freescale QorIQ AHCI SATA platform driver
34 *
45 * Copyright 2015 Freescale, Inc.
56 * Tang Yuantian <Yuantian.Tang@freescale.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2, or (at your option)
10
- * any later version.
117 */
128
9
+#include <linux/acpi.h>
1310 #include <linux/kernel.h>
1411 #include <linux/module.h>
1512 #include <linux/pm.h>
....@@ -53,11 +50,13 @@
5350
5451 enum ahci_qoriq_type {
5552 AHCI_LS1021A,
53
+ AHCI_LS1028A,
5654 AHCI_LS1043A,
5755 AHCI_LS2080A,
5856 AHCI_LS1046A,
5957 AHCI_LS1088A,
6058 AHCI_LS2088A,
59
+ AHCI_LX2160A,
6160 };
6261
6362 struct ahci_qoriq_priv {
....@@ -67,16 +66,26 @@
6766 bool is_dmacoherent;
6867 };
6968
69
+static bool ecc_initialized;
70
+
7071 static const struct of_device_id ahci_qoriq_of_match[] = {
7172 { .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A},
73
+ { .compatible = "fsl,ls1028a-ahci", .data = (void *)AHCI_LS1028A},
7274 { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
7375 { .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A},
7476 { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A},
7577 { .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A},
7678 { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
79
+ { .compatible = "fsl,lx2160a-ahci", .data = (void *)AHCI_LX2160A},
7780 {},
7881 };
7982 MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
83
+
84
+static const struct acpi_device_id ahci_qoriq_acpi_match[] = {
85
+ {"NXP0004", .driver_data = (kernel_ulong_t)AHCI_LX2160A},
86
+ { }
87
+};
88
+MODULE_DEVICE_TABLE(acpi, ahci_qoriq_acpi_match);
8089
8190 static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class,
8291 unsigned long deadline)
....@@ -165,9 +174,10 @@
165174
166175 switch (qpriv->type) {
167176 case AHCI_LS1021A:
168
- if (!qpriv->ecc_addr)
177
+ if (!(qpriv->ecc_addr || ecc_initialized))
169178 return -EINVAL;
170
- writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
179
+ else if (qpriv->ecc_addr && !ecc_initialized)
180
+ writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
171181 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
172182 writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2);
173183 writel(LS1021A_PORT_PHY3, reg_base + PORT_PHY3);
....@@ -180,10 +190,12 @@
180190 break;
181191
182192 case AHCI_LS1043A:
183
- if (!qpriv->ecc_addr)
193
+ if (!(qpriv->ecc_addr || ecc_initialized))
184194 return -EINVAL;
185
- writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
186
- qpriv->ecc_addr);
195
+ else if (qpriv->ecc_addr && !ecc_initialized)
196
+ writel(readl(qpriv->ecc_addr) |
197
+ ECC_DIS_ARMV8_CH2,
198
+ qpriv->ecc_addr);
187199 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
188200 writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2);
189201 writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3);
....@@ -202,10 +214,12 @@
202214 break;
203215
204216 case AHCI_LS1046A:
205
- if (!qpriv->ecc_addr)
217
+ if (!(qpriv->ecc_addr || ecc_initialized))
206218 return -EINVAL;
207
- writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
208
- qpriv->ecc_addr);
219
+ else if (qpriv->ecc_addr && !ecc_initialized)
220
+ writel(readl(qpriv->ecc_addr) |
221
+ ECC_DIS_ARMV8_CH2,
222
+ qpriv->ecc_addr);
209223 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
210224 writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2);
211225 writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3);
....@@ -214,11 +228,15 @@
214228 writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
215229 break;
216230
231
+ case AHCI_LS1028A:
217232 case AHCI_LS1088A:
218
- if (!qpriv->ecc_addr)
233
+ case AHCI_LX2160A:
234
+ if (!(qpriv->ecc_addr || ecc_initialized))
219235 return -EINVAL;
220
- writel(readl(qpriv->ecc_addr) | ECC_DIS_LS1088A,
221
- qpriv->ecc_addr);
236
+ else if (qpriv->ecc_addr && !ecc_initialized)
237
+ writel(readl(qpriv->ecc_addr) |
238
+ ECC_DIS_LS1088A,
239
+ qpriv->ecc_addr);
222240 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
223241 writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2);
224242 writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3);
....@@ -237,12 +255,14 @@
237255 break;
238256 }
239257
258
+ ecc_initialized = true;
240259 return 0;
241260 }
242261
243262 static int ahci_qoriq_probe(struct platform_device *pdev)
244263 {
245264 struct device_node *np = pdev->dev.of_node;
265
+ const struct acpi_device_id *acpi_id;
246266 struct device *dev = &pdev->dev;
247267 struct ahci_host_priv *hpriv;
248268 struct ahci_qoriq_priv *qoriq_priv;
....@@ -255,23 +275,33 @@
255275 return PTR_ERR(hpriv);
256276
257277 of_id = of_match_node(ahci_qoriq_of_match, np);
258
- if (!of_id)
278
+ acpi_id = acpi_match_device(ahci_qoriq_acpi_match, &pdev->dev);
279
+ if (!(of_id || acpi_id))
259280 return -ENODEV;
260281
261282 qoriq_priv = devm_kzalloc(dev, sizeof(*qoriq_priv), GFP_KERNEL);
262283 if (!qoriq_priv)
263284 return -ENOMEM;
264285
265
- qoriq_priv->type = (enum ahci_qoriq_type)of_id->data;
286
+ if (of_id)
287
+ qoriq_priv->type = (enum ahci_qoriq_type)of_id->data;
288
+ else
289
+ qoriq_priv->type = (enum ahci_qoriq_type)acpi_id->driver_data;
266290
267
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
268
- "sata-ecc");
269
- if (res) {
270
- qoriq_priv->ecc_addr = devm_ioremap_resource(dev, res);
271
- if (IS_ERR(qoriq_priv->ecc_addr))
272
- return PTR_ERR(qoriq_priv->ecc_addr);
291
+ if (unlikely(!ecc_initialized)) {
292
+ res = platform_get_resource_byname(pdev,
293
+ IORESOURCE_MEM,
294
+ "sata-ecc");
295
+ if (res) {
296
+ qoriq_priv->ecc_addr =
297
+ devm_ioremap_resource(dev, res);
298
+ if (IS_ERR(qoriq_priv->ecc_addr))
299
+ return PTR_ERR(qoriq_priv->ecc_addr);
300
+ }
273301 }
274
- qoriq_priv->is_dmacoherent = of_dma_is_coherent(np);
302
+
303
+ if (device_get_dma_attr(&pdev->dev) == DEV_DMA_COHERENT)
304
+ qoriq_priv->is_dmacoherent = true;
275305
276306 rc = ahci_platform_enable_resources(hpriv);
277307 if (rc)
....@@ -337,6 +367,7 @@
337367 .driver = {
338368 .name = DRV_NAME,
339369 .of_match_table = ahci_qoriq_of_match,
370
+ .acpi_match_table = ahci_qoriq_acpi_match,
340371 .pm = &ahci_qoriq_pm_ops,
341372 },
342373 };