.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Driver for Broadcom BRCMSTB, NSP, NS2, Cygnus SPI Controllers |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright 2016 Broadcom |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License, version 2, as |
---|
8 | | - * published by the Free Software Foundation (the "GPL"). |
---|
9 | | - * |
---|
10 | | - * This program is distributed in the hope that it will be useful, but |
---|
11 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
13 | | - * General Public License version 2 (GPLv2) for more details. |
---|
14 | | - * |
---|
15 | | - * You should have received a copy of the GNU General Public License |
---|
16 | | - * version 2 (GPLv2) along with this source code. |
---|
17 | 6 | */ |
---|
18 | 7 | |
---|
19 | 8 | #include <linux/clk.h> |
---|
.. | .. |
---|
102 | 91 | #define MSPI_MSPI_STATUS 0x020 |
---|
103 | 92 | #define MSPI_CPTQP 0x024 |
---|
104 | 93 | #define MSPI_SPCR3 0x028 |
---|
| 94 | +#define MSPI_REV 0x02c |
---|
105 | 95 | #define MSPI_TXRAM 0x040 |
---|
106 | 96 | #define MSPI_RXRAM 0x0c0 |
---|
107 | 97 | #define MSPI_CDRAM 0x140 |
---|
.. | .. |
---|
117 | 107 | #define MSPI_SPCR2_SPE BIT(6) |
---|
118 | 108 | #define MSPI_SPCR2_CONT_AFTER_CMD BIT(7) |
---|
119 | 109 | |
---|
| 110 | +#define MSPI_SPCR3_FASTBR BIT(0) |
---|
| 111 | +#define MSPI_SPCR3_FASTDT BIT(1) |
---|
| 112 | +#define MSPI_SPCR3_SYSCLKSEL_MASK GENMASK(11, 10) |
---|
| 113 | +#define MSPI_SPCR3_SYSCLKSEL_27 (MSPI_SPCR3_SYSCLKSEL_MASK & \ |
---|
| 114 | + ~(BIT(10) | BIT(11))) |
---|
| 115 | +#define MSPI_SPCR3_SYSCLKSEL_108 (MSPI_SPCR3_SYSCLKSEL_MASK & \ |
---|
| 116 | + BIT(11)) |
---|
| 117 | + |
---|
120 | 118 | #define MSPI_MSPI_STATUS_SPIF BIT(0) |
---|
121 | 119 | |
---|
122 | 120 | #define INTR_BASE_BIT_SHIFT 0x02 |
---|
123 | 121 | #define INTR_COUNT 0x07 |
---|
124 | 122 | |
---|
125 | 123 | #define NUM_CHIPSELECT 4 |
---|
126 | | -#define QSPI_SPBR_MIN 8U |
---|
127 | 124 | #define QSPI_SPBR_MAX 255U |
---|
| 125 | +#define MSPI_BASE_FREQ 27000000UL |
---|
128 | 126 | |
---|
129 | 127 | #define OPCODE_DIOR 0xBB |
---|
130 | 128 | #define OPCODE_QIOR 0xEB |
---|
.. | .. |
---|
228 | 226 | struct bcm_qspi_dev_id *dev_ids; |
---|
229 | 227 | struct completion mspi_done; |
---|
230 | 228 | struct completion bspi_done; |
---|
| 229 | + u8 mspi_maj_rev; |
---|
| 230 | + u8 mspi_min_rev; |
---|
| 231 | + bool mspi_spcr3_sysclk; |
---|
231 | 232 | }; |
---|
232 | 233 | |
---|
233 | 234 | static inline bool has_bspi(struct bcm_qspi *qspi) |
---|
234 | 235 | { |
---|
235 | 236 | return qspi->bspi_mode; |
---|
| 237 | +} |
---|
| 238 | + |
---|
| 239 | +/* hardware supports spcr3 and fast baud-rate */ |
---|
| 240 | +static inline bool bcm_qspi_has_fastbr(struct bcm_qspi *qspi) |
---|
| 241 | +{ |
---|
| 242 | + if (!has_bspi(qspi) && |
---|
| 243 | + ((qspi->mspi_maj_rev >= 1) && |
---|
| 244 | + (qspi->mspi_min_rev >= 5))) |
---|
| 245 | + return true; |
---|
| 246 | + |
---|
| 247 | + return false; |
---|
| 248 | +} |
---|
| 249 | + |
---|
| 250 | +/* hardware supports sys clk 108Mhz */ |
---|
| 251 | +static inline bool bcm_qspi_has_sysclk_108(struct bcm_qspi *qspi) |
---|
| 252 | +{ |
---|
| 253 | + if (!has_bspi(qspi) && (qspi->mspi_spcr3_sysclk || |
---|
| 254 | + ((qspi->mspi_maj_rev >= 1) && |
---|
| 255 | + (qspi->mspi_min_rev >= 6)))) |
---|
| 256 | + return true; |
---|
| 257 | + |
---|
| 258 | + return false; |
---|
| 259 | +} |
---|
| 260 | + |
---|
| 261 | +static inline int bcm_qspi_spbr_min(struct bcm_qspi *qspi) |
---|
| 262 | +{ |
---|
| 263 | + if (bcm_qspi_has_fastbr(qspi)) |
---|
| 264 | + return 1; |
---|
| 265 | + else |
---|
| 266 | + return 8; |
---|
236 | 267 | } |
---|
237 | 268 | |
---|
238 | 269 | /* Read qspi controller register*/ |
---|
.. | .. |
---|
542 | 573 | if (xp->speed_hz) |
---|
543 | 574 | spbr = qspi->base_clk / (2 * xp->speed_hz); |
---|
544 | 575 | |
---|
545 | | - spcr = clamp_val(spbr, QSPI_SPBR_MIN, QSPI_SPBR_MAX); |
---|
| 576 | + spcr = clamp_val(spbr, bcm_qspi_spbr_min(qspi), QSPI_SPBR_MAX); |
---|
546 | 577 | bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_LSB, spcr); |
---|
547 | 578 | |
---|
548 | | - spcr = MSPI_MASTER_BIT; |
---|
| 579 | + if (!qspi->mspi_maj_rev) |
---|
| 580 | + /* legacy controller */ |
---|
| 581 | + spcr = MSPI_MASTER_BIT; |
---|
| 582 | + else |
---|
| 583 | + spcr = 0; |
---|
| 584 | + |
---|
549 | 585 | /* for 16 bit the data should be zero */ |
---|
550 | 586 | if (xp->bits_per_word != 16) |
---|
551 | 587 | spcr |= xp->bits_per_word << 2; |
---|
552 | 588 | spcr |= xp->mode & 3; |
---|
| 589 | + |
---|
553 | 590 | bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_MSB, spcr); |
---|
| 591 | + |
---|
| 592 | + if (bcm_qspi_has_fastbr(qspi)) { |
---|
| 593 | + spcr = 0; |
---|
| 594 | + |
---|
| 595 | + /* enable fastbr */ |
---|
| 596 | + spcr |= MSPI_SPCR3_FASTBR; |
---|
| 597 | + |
---|
| 598 | + if (bcm_qspi_has_sysclk_108(qspi)) { |
---|
| 599 | + /* SYSCLK_108 */ |
---|
| 600 | + spcr |= MSPI_SPCR3_SYSCLKSEL_108; |
---|
| 601 | + qspi->base_clk = MSPI_BASE_FREQ * 4; |
---|
| 602 | + /* Change spbr as we changed sysclk */ |
---|
| 603 | + bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_LSB, 4); |
---|
| 604 | + } |
---|
| 605 | + |
---|
| 606 | + bcm_qspi_write(qspi, MSPI, MSPI_SPCR3, spcr); |
---|
| 607 | + } |
---|
554 | 608 | |
---|
555 | 609 | qspi->last_parms = *xp; |
---|
556 | 610 | } |
---|
.. | .. |
---|
623 | 677 | if (qt->trans->cs_change && |
---|
624 | 678 | (flags & TRANS_STATUS_BREAK_CS_CHANGE)) |
---|
625 | 679 | ret |= TRANS_STATUS_BREAK_CS_CHANGE; |
---|
626 | | - if (ret) |
---|
627 | | - goto done; |
---|
628 | 680 | |
---|
629 | | - dev_dbg(&qspi->pdev->dev, "advance msg exit\n"); |
---|
630 | 681 | if (bcm_qspi_mspi_transfer_is_last(qspi, qt)) |
---|
631 | | - ret = TRANS_STATUS_BREAK_EOM; |
---|
| 682 | + ret |= TRANS_STATUS_BREAK_EOM; |
---|
632 | 683 | else |
---|
633 | | - ret = TRANS_STATUS_BREAK_NO_BYTES; |
---|
| 684 | + ret |= TRANS_STATUS_BREAK_NO_BYTES; |
---|
634 | 685 | |
---|
635 | 686 | qt->trans = NULL; |
---|
636 | 687 | } |
---|
637 | 688 | |
---|
638 | | -done: |
---|
639 | 689 | dev_dbg(&qspi->pdev->dev, "trans %p len %d byte %d ret %x\n", |
---|
640 | 690 | qt->trans, qt->trans ? qt->trans->len : 0, qt->byte, ret); |
---|
641 | 691 | return ret; |
---|
.. | .. |
---|
782 | 832 | bcm_qspi_write(qspi, MSPI, MSPI_NEWQP, 0); |
---|
783 | 833 | bcm_qspi_write(qspi, MSPI, MSPI_ENDQP, slot - 1); |
---|
784 | 834 | |
---|
785 | | - if (tstatus & TRANS_STATUS_BREAK_DESELECT) { |
---|
| 835 | + /* |
---|
| 836 | + * case 1) EOM =1, cs_change =0: SSb inactive |
---|
| 837 | + * case 2) EOM =1, cs_change =1: SSb stay active |
---|
| 838 | + * case 3) EOM =0, cs_change =0: SSb stay active |
---|
| 839 | + * case 4) EOM =0, cs_change =1: SSb inactive |
---|
| 840 | + */ |
---|
| 841 | + if (((tstatus & TRANS_STATUS_BREAK_DESELECT) |
---|
| 842 | + == TRANS_STATUS_BREAK_CS_CHANGE) || |
---|
| 843 | + ((tstatus & TRANS_STATUS_BREAK_DESELECT) |
---|
| 844 | + == TRANS_STATUS_BREAK_EOM)) { |
---|
786 | 845 | mspi_cdram = read_cdram_slot(qspi, slot - 1) & |
---|
787 | 846 | ~MSPI_CDRAM_CONT_BIT; |
---|
788 | 847 | write_cdram_slot(qspi, slot - 1, mspi_cdram); |
---|
.. | .. |
---|
814 | 873 | return -EIO; |
---|
815 | 874 | |
---|
816 | 875 | from = op->addr.val; |
---|
817 | | - bcm_qspi_chip_select(qspi, spi->chip_select); |
---|
| 876 | + if (!spi->cs_gpiod) |
---|
| 877 | + bcm_qspi_chip_select(qspi, spi->chip_select); |
---|
818 | 878 | bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0); |
---|
819 | 879 | |
---|
820 | 880 | /* |
---|
.. | .. |
---|
893 | 953 | int slots; |
---|
894 | 954 | unsigned long timeo = msecs_to_jiffies(100); |
---|
895 | 955 | |
---|
896 | | - bcm_qspi_chip_select(qspi, spi->chip_select); |
---|
| 956 | + if (!spi->cs_gpiod) |
---|
| 957 | + bcm_qspi_chip_select(qspi, spi->chip_select); |
---|
897 | 958 | qspi->trans_pos.trans = trans; |
---|
898 | 959 | qspi->trans_pos.byte = 0; |
---|
899 | 960 | |
---|
.. | .. |
---|
908 | 969 | |
---|
909 | 970 | read_from_hw(qspi, slots); |
---|
910 | 971 | } |
---|
| 972 | + bcm_qspi_enable_bspi(qspi); |
---|
911 | 973 | |
---|
912 | 974 | return 0; |
---|
913 | 975 | } |
---|
.. | .. |
---|
970 | 1032 | addr = op->addr.val; |
---|
971 | 1033 | len = op->data.nbytes; |
---|
972 | 1034 | |
---|
973 | | - if (bcm_qspi_bspi_ver_three(qspi) == true) { |
---|
| 1035 | + if (has_bspi(qspi) && bcm_qspi_bspi_ver_three(qspi) == true) { |
---|
974 | 1036 | /* |
---|
975 | 1037 | * The address coming into this function is a raw flash offset. |
---|
976 | 1038 | * But for BSPI <= V3, we need to convert it to a remapped BSPI |
---|
.. | .. |
---|
989 | 1051 | len < 4) |
---|
990 | 1052 | mspi_read = true; |
---|
991 | 1053 | |
---|
992 | | - if (mspi_read) |
---|
| 1054 | + if (!has_bspi(qspi) || mspi_read) |
---|
993 | 1055 | return bcm_qspi_mspi_exec_mem_op(spi, op); |
---|
994 | 1056 | |
---|
995 | 1057 | ret = bcm_qspi_bspi_set_mode(qspi, op, 0); |
---|
.. | .. |
---|
1188 | 1250 | |
---|
1189 | 1251 | static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi) |
---|
1190 | 1252 | { |
---|
| 1253 | + u32 status = bcm_qspi_read(qspi, MSPI, MSPI_MSPI_STATUS); |
---|
| 1254 | + |
---|
1191 | 1255 | bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0); |
---|
1192 | 1256 | if (has_bspi(qspi)) |
---|
1193 | 1257 | bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0); |
---|
1194 | 1258 | |
---|
| 1259 | + /* clear interrupt */ |
---|
| 1260 | + bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status & ~1); |
---|
1195 | 1261 | } |
---|
1196 | 1262 | |
---|
1197 | 1263 | static const struct spi_controller_mem_ops bcm_qspi_mem_ops = { |
---|
1198 | 1264 | .exec_op = bcm_qspi_exec_mem_op, |
---|
1199 | 1265 | }; |
---|
1200 | 1266 | |
---|
| 1267 | +struct bcm_qspi_data { |
---|
| 1268 | + bool has_mspi_rev; |
---|
| 1269 | + bool has_spcr3_sysclk; |
---|
| 1270 | +}; |
---|
| 1271 | + |
---|
| 1272 | +static const struct bcm_qspi_data bcm_qspi_no_rev_data = { |
---|
| 1273 | + .has_mspi_rev = false, |
---|
| 1274 | + .has_spcr3_sysclk = false, |
---|
| 1275 | +}; |
---|
| 1276 | + |
---|
| 1277 | +static const struct bcm_qspi_data bcm_qspi_rev_data = { |
---|
| 1278 | + .has_mspi_rev = true, |
---|
| 1279 | + .has_spcr3_sysclk = false, |
---|
| 1280 | +}; |
---|
| 1281 | + |
---|
| 1282 | +static const struct bcm_qspi_data bcm_qspi_spcr3_data = { |
---|
| 1283 | + .has_mspi_rev = true, |
---|
| 1284 | + .has_spcr3_sysclk = true, |
---|
| 1285 | +}; |
---|
| 1286 | + |
---|
1201 | 1287 | static const struct of_device_id bcm_qspi_of_match[] = { |
---|
1202 | | - { .compatible = "brcm,spi-bcm-qspi" }, |
---|
| 1288 | + { |
---|
| 1289 | + .compatible = "brcm,spi-bcm7445-qspi", |
---|
| 1290 | + .data = &bcm_qspi_rev_data, |
---|
| 1291 | + |
---|
| 1292 | + }, |
---|
| 1293 | + { |
---|
| 1294 | + .compatible = "brcm,spi-bcm-qspi", |
---|
| 1295 | + .data = &bcm_qspi_no_rev_data, |
---|
| 1296 | + }, |
---|
| 1297 | + { |
---|
| 1298 | + .compatible = "brcm,spi-bcm7216-qspi", |
---|
| 1299 | + .data = &bcm_qspi_spcr3_data, |
---|
| 1300 | + }, |
---|
| 1301 | + { |
---|
| 1302 | + .compatible = "brcm,spi-bcm7278-qspi", |
---|
| 1303 | + .data = &bcm_qspi_spcr3_data, |
---|
| 1304 | + }, |
---|
1203 | 1305 | {}, |
---|
1204 | 1306 | }; |
---|
1205 | 1307 | MODULE_DEVICE_TABLE(of, bcm_qspi_of_match); |
---|
.. | .. |
---|
1207 | 1309 | int bcm_qspi_probe(struct platform_device *pdev, |
---|
1208 | 1310 | struct bcm_qspi_soc_intc *soc_intc) |
---|
1209 | 1311 | { |
---|
| 1312 | + const struct of_device_id *of_id = NULL; |
---|
| 1313 | + const struct bcm_qspi_data *data; |
---|
1210 | 1314 | struct device *dev = &pdev->dev; |
---|
1211 | 1315 | struct bcm_qspi *qspi; |
---|
1212 | 1316 | struct spi_master *master; |
---|
1213 | 1317 | struct resource *res; |
---|
1214 | 1318 | int irq, ret = 0, num_ints = 0; |
---|
1215 | 1319 | u32 val; |
---|
| 1320 | + u32 rev = 0; |
---|
1216 | 1321 | const char *name = NULL; |
---|
1217 | 1322 | int num_irqs = ARRAY_SIZE(qspi_irq_tab); |
---|
1218 | 1323 | |
---|
.. | .. |
---|
1220 | 1325 | if (!dev->of_node) |
---|
1221 | 1326 | return -ENODEV; |
---|
1222 | 1327 | |
---|
1223 | | - if (!of_match_node(bcm_qspi_of_match, dev->of_node)) |
---|
| 1328 | + of_id = of_match_node(bcm_qspi_of_match, dev->of_node); |
---|
| 1329 | + if (!of_id) |
---|
1224 | 1330 | return -ENODEV; |
---|
| 1331 | + |
---|
| 1332 | + data = of_id->data; |
---|
1225 | 1333 | |
---|
1226 | 1334 | master = devm_spi_alloc_master(dev, sizeof(struct bcm_qspi)); |
---|
1227 | 1335 | if (!master) { |
---|
.. | .. |
---|
1230 | 1338 | } |
---|
1231 | 1339 | |
---|
1232 | 1340 | qspi = spi_master_get_devdata(master); |
---|
| 1341 | + |
---|
| 1342 | + qspi->clk = devm_clk_get_optional(&pdev->dev, NULL); |
---|
| 1343 | + if (IS_ERR(qspi->clk)) |
---|
| 1344 | + return PTR_ERR(qspi->clk); |
---|
| 1345 | + |
---|
1233 | 1346 | qspi->pdev = pdev; |
---|
1234 | 1347 | qspi->trans_pos.trans = NULL; |
---|
1235 | 1348 | qspi->trans_pos.byte = 0; |
---|
.. | .. |
---|
1244 | 1357 | master->cleanup = bcm_qspi_cleanup; |
---|
1245 | 1358 | master->dev.of_node = dev->of_node; |
---|
1246 | 1359 | master->num_chipselect = NUM_CHIPSELECT; |
---|
| 1360 | + master->use_gpio_descriptors = true; |
---|
1247 | 1361 | |
---|
1248 | 1362 | qspi->big_endian = of_device_is_big_endian(dev->of_node); |
---|
1249 | 1363 | |
---|
.. | .. |
---|
1255 | 1369 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
---|
1256 | 1370 | "mspi"); |
---|
1257 | 1371 | |
---|
1258 | | - if (res) { |
---|
1259 | | - qspi->base[MSPI] = devm_ioremap_resource(dev, res); |
---|
1260 | | - if (IS_ERR(qspi->base[MSPI])) |
---|
1261 | | - return PTR_ERR(qspi->base[MSPI]); |
---|
1262 | | - } else { |
---|
1263 | | - return 0; |
---|
1264 | | - } |
---|
| 1372 | + qspi->base[MSPI] = devm_ioremap_resource(dev, res); |
---|
| 1373 | + if (IS_ERR(qspi->base[MSPI])) |
---|
| 1374 | + return PTR_ERR(qspi->base[MSPI]); |
---|
1265 | 1375 | |
---|
1266 | 1376 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi"); |
---|
1267 | 1377 | if (res) { |
---|
.. | .. |
---|
1287 | 1397 | if (!qspi->dev_ids) |
---|
1288 | 1398 | return -ENOMEM; |
---|
1289 | 1399 | |
---|
| 1400 | + /* |
---|
| 1401 | + * Some SoCs integrate spi controller (e.g., its interrupt bits) |
---|
| 1402 | + * in specific ways |
---|
| 1403 | + */ |
---|
| 1404 | + if (soc_intc) { |
---|
| 1405 | + qspi->soc_intc = soc_intc; |
---|
| 1406 | + soc_intc->bcm_qspi_int_set(soc_intc, MSPI_DONE, true); |
---|
| 1407 | + } else { |
---|
| 1408 | + qspi->soc_intc = NULL; |
---|
| 1409 | + } |
---|
| 1410 | + |
---|
| 1411 | + if (qspi->clk) { |
---|
| 1412 | + ret = clk_prepare_enable(qspi->clk); |
---|
| 1413 | + if (ret) { |
---|
| 1414 | + dev_err(dev, "failed to prepare clock\n"); |
---|
| 1415 | + goto qspi_probe_err; |
---|
| 1416 | + } |
---|
| 1417 | + qspi->base_clk = clk_get_rate(qspi->clk); |
---|
| 1418 | + } else { |
---|
| 1419 | + qspi->base_clk = MSPI_BASE_FREQ; |
---|
| 1420 | + } |
---|
| 1421 | + |
---|
| 1422 | + if (data->has_mspi_rev) { |
---|
| 1423 | + rev = bcm_qspi_read(qspi, MSPI, MSPI_REV); |
---|
| 1424 | + /* some older revs do not have a MSPI_REV register */ |
---|
| 1425 | + if ((rev & 0xff) == 0xff) |
---|
| 1426 | + rev = 0; |
---|
| 1427 | + } |
---|
| 1428 | + |
---|
| 1429 | + qspi->mspi_maj_rev = (rev >> 4) & 0xf; |
---|
| 1430 | + qspi->mspi_min_rev = rev & 0xf; |
---|
| 1431 | + qspi->mspi_spcr3_sysclk = data->has_spcr3_sysclk; |
---|
| 1432 | + |
---|
| 1433 | + qspi->max_speed_hz = qspi->base_clk / (bcm_qspi_spbr_min(qspi) * 2); |
---|
| 1434 | + |
---|
| 1435 | + /* |
---|
| 1436 | + * On SW resets it is possible to have the mask still enabled |
---|
| 1437 | + * Need to disable the mask and clear the status while we init |
---|
| 1438 | + */ |
---|
| 1439 | + bcm_qspi_hw_uninit(qspi); |
---|
| 1440 | + |
---|
1290 | 1441 | for (val = 0; val < num_irqs; val++) { |
---|
1291 | 1442 | irq = -1; |
---|
1292 | 1443 | name = qspi_irq_tab[val].irq_name; |
---|
1293 | 1444 | if (qspi_irq_tab[val].irq_source == SINGLE_L2) { |
---|
1294 | 1445 | /* get the l2 interrupts */ |
---|
1295 | | - irq = platform_get_irq_byname(pdev, name); |
---|
| 1446 | + irq = platform_get_irq_byname_optional(pdev, name); |
---|
1296 | 1447 | } else if (!num_ints && soc_intc) { |
---|
1297 | 1448 | /* all mspi, bspi intrs muxed to one L1 intr */ |
---|
1298 | 1449 | irq = platform_get_irq(pdev, 0); |
---|
.. | .. |
---|
1322 | 1473 | ret = -EINVAL; |
---|
1323 | 1474 | goto qspi_unprepare_err; |
---|
1324 | 1475 | } |
---|
1325 | | - |
---|
1326 | | - /* |
---|
1327 | | - * Some SoCs integrate spi controller (e.g., its interrupt bits) |
---|
1328 | | - * in specific ways |
---|
1329 | | - */ |
---|
1330 | | - if (soc_intc) { |
---|
1331 | | - qspi->soc_intc = soc_intc; |
---|
1332 | | - soc_intc->bcm_qspi_int_set(soc_intc, MSPI_DONE, true); |
---|
1333 | | - } else { |
---|
1334 | | - qspi->soc_intc = NULL; |
---|
1335 | | - } |
---|
1336 | | - |
---|
1337 | | - qspi->clk = devm_clk_get(&pdev->dev, NULL); |
---|
1338 | | - if (IS_ERR(qspi->clk)) { |
---|
1339 | | - dev_warn(dev, "unable to get clock\n"); |
---|
1340 | | - ret = PTR_ERR(qspi->clk); |
---|
1341 | | - goto qspi_probe_err; |
---|
1342 | | - } |
---|
1343 | | - |
---|
1344 | | - ret = clk_prepare_enable(qspi->clk); |
---|
1345 | | - if (ret) { |
---|
1346 | | - dev_err(dev, "failed to prepare clock\n"); |
---|
1347 | | - goto qspi_probe_err; |
---|
1348 | | - } |
---|
1349 | | - |
---|
1350 | | - qspi->base_clk = clk_get_rate(qspi->clk); |
---|
1351 | | - qspi->max_speed_hz = qspi->base_clk / (QSPI_SPBR_MIN * 2); |
---|
1352 | 1476 | |
---|
1353 | 1477 | bcm_qspi_hw_init(qspi); |
---|
1354 | 1478 | init_completion(&qspi->mspi_done); |
---|
.. | .. |
---|
1404 | 1528 | bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); |
---|
1405 | 1529 | |
---|
1406 | 1530 | spi_master_suspend(qspi->master); |
---|
1407 | | - clk_disable(qspi->clk); |
---|
| 1531 | + clk_disable_unprepare(qspi->clk); |
---|
1408 | 1532 | bcm_qspi_hw_uninit(qspi); |
---|
1409 | 1533 | |
---|
1410 | 1534 | return 0; |
---|
.. | .. |
---|
1422 | 1546 | qspi->soc_intc->bcm_qspi_int_set(qspi->soc_intc, MSPI_DONE, |
---|
1423 | 1547 | true); |
---|
1424 | 1548 | |
---|
1425 | | - ret = clk_enable(qspi->clk); |
---|
| 1549 | + ret = clk_prepare_enable(qspi->clk); |
---|
1426 | 1550 | if (!ret) |
---|
1427 | 1551 | spi_master_resume(qspi->master); |
---|
1428 | 1552 | |
---|