Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge remote-tracking branch 'spi/for-5.20' into spi-6.0

+112 -39
+1 -1
Documentation/devicetree/bindings/spi/cdns,qspi-nor-peripheral-props.yaml
··· 10 10 See spi-peripheral-props.yaml for more info. 11 11 12 12 maintainers: 13 - - Pratyush Yadav <p.yadav@ti.com> 13 + - Vaishnav Achath <vaishnav.a@ti.com> 14 14 15 15 properties: 16 16 # cdns,qspi-nor.yaml
+1 -1
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
··· 7 7 title: Cadence Quad SPI controller 8 8 9 9 maintainers: 10 - - Pratyush Yadav <p.yadav@ti.com> 10 + - Vaishnav Achath <vaishnav.a@ti.com> 11 11 12 12 allOf: 13 13 - $ref: spi-controller.yaml#
+1 -1
Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
··· 16 16 their own separate schema that should be referenced from here. 17 17 18 18 maintainers: 19 - - Pratyush Yadav <p.yadav@ti.com> 19 + - Mark Brown <broonie@kernel.org> 20 20 21 21 properties: 22 22 reg:
+1 -1
MAINTAINERS
··· 2178 2178 M: Nick Hawkins <nick.hawkins@hpe.com> 2179 2179 S: Maintained 2180 2180 F: Documentation/devicetree/bindings/arm/hpe,gxp.yaml 2181 - F: Documentation/devicetree/bindings/spi/hpe,gxp-spi.yaml 2181 + F: Documentation/devicetree/bindings/spi/hpe,gxp-spifi.yaml 2182 2182 F: Documentation/devicetree/bindings/timer/hpe,gxp-timer.yaml 2183 2183 F: arch/arm/boot/dts/hpe-bmc* 2184 2184 F: arch/arm/boot/dts/hpe-gxp*
+101 -28
drivers/spi/spi-meson-spicc.c
··· 156 156 void __iomem *base; 157 157 struct clk *core; 158 158 struct clk *pclk; 159 + struct clk_divider pow2_div; 159 160 struct clk *clk; 160 161 struct spi_message *message; 161 162 struct spi_transfer *xfer; ··· 168 167 unsigned long rx_remain; 169 168 unsigned long xfer_remain; 170 169 }; 170 + 171 + #define pow2_clk_to_spicc(_div) container_of(_div, struct meson_spicc_device, pow2_div) 171 172 172 173 static void meson_spicc_oen_enable(struct meson_spicc_device *spicc) 173 174 { ··· 424 421 { 425 422 struct meson_spicc_device *spicc = spi_master_get_devdata(master); 426 423 struct spi_device *spi = message->spi; 427 - u32 conf = 0; 424 + u32 conf = readl_relaxed(spicc->base + SPICC_CONREG) & SPICC_DATARATE_MASK; 428 425 429 426 /* Store current message */ 430 427 spicc->message = message; ··· 461 458 /* Select CS */ 462 459 conf |= FIELD_PREP(SPICC_CS_MASK, spi->chip_select); 463 460 464 - /* Default Clock rate core/4 */ 465 - 466 461 /* Default 8bit word */ 467 462 conf |= FIELD_PREP(SPICC_BITLENGTH_MASK, 8 - 1); 468 463 ··· 477 476 static int meson_spicc_unprepare_transfer(struct spi_master *master) 478 477 { 479 478 struct meson_spicc_device *spicc = spi_master_get_devdata(master); 479 + u32 conf = readl_relaxed(spicc->base + SPICC_CONREG) & SPICC_DATARATE_MASK; 480 480 481 481 /* Disable all IRQs */ 482 482 writel(0, spicc->base + SPICC_INTREG); 483 483 484 484 device_reset_optional(&spicc->pdev->dev); 485 + 486 + /* Set default configuration, keeping datarate field */ 487 + writel_relaxed(conf, spicc->base + SPICC_CONREG); 485 488 486 489 return 0; 487 490 } ··· 523 518 * Clk path for G12A series: 524 519 * pclk -> pow2 fixed div -> pow2 div -> mux -> out 525 520 * pclk -> enh fixed div -> enh div -> mux -> out 521 + * 522 + * The pow2 divider is tied to the controller HW state, and the 523 + * divider is only valid when the controller is initialized. 524 + * 525 + * A set of clock ops is added to make sure we don't read/set this 526 + * clock rate while the controller is in an unknown state. 526 527 */ 527 528 528 - static int meson_spicc_clk_init(struct meson_spicc_device *spicc) 529 + static unsigned long meson_spicc_pow2_recalc_rate(struct clk_hw *hw, 530 + unsigned long parent_rate) 531 + { 532 + struct clk_divider *divider = to_clk_divider(hw); 533 + struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); 534 + 535 + if (!spicc->master->cur_msg || !spicc->master->busy) 536 + return 0; 537 + 538 + return clk_divider_ops.recalc_rate(hw, parent_rate); 539 + } 540 + 541 + static int meson_spicc_pow2_determine_rate(struct clk_hw *hw, 542 + struct clk_rate_request *req) 543 + { 544 + struct clk_divider *divider = to_clk_divider(hw); 545 + struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); 546 + 547 + if (!spicc->master->cur_msg || !spicc->master->busy) 548 + return -EINVAL; 549 + 550 + return clk_divider_ops.determine_rate(hw, req); 551 + } 552 + 553 + static int meson_spicc_pow2_set_rate(struct clk_hw *hw, unsigned long rate, 554 + unsigned long parent_rate) 555 + { 556 + struct clk_divider *divider = to_clk_divider(hw); 557 + struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); 558 + 559 + if (!spicc->master->cur_msg || !spicc->master->busy) 560 + return -EINVAL; 561 + 562 + return clk_divider_ops.set_rate(hw, rate, parent_rate); 563 + } 564 + 565 + const struct clk_ops meson_spicc_pow2_clk_ops = { 566 + .recalc_rate = meson_spicc_pow2_recalc_rate, 567 + .determine_rate = meson_spicc_pow2_determine_rate, 568 + .set_rate = meson_spicc_pow2_set_rate, 569 + }; 570 + 571 + static int meson_spicc_pow2_clk_init(struct meson_spicc_device *spicc) 529 572 { 530 573 struct device *dev = &spicc->pdev->dev; 531 - struct clk_fixed_factor *pow2_fixed_div, *enh_fixed_div; 532 - struct clk_divider *pow2_div, *enh_div; 533 - struct clk_mux *mux; 574 + struct clk_fixed_factor *pow2_fixed_div; 534 575 struct clk_init_data init; 535 576 struct clk *clk; 536 577 struct clk_parent_data parent_data[2]; ··· 611 560 if (WARN_ON(IS_ERR(clk))) 612 561 return PTR_ERR(clk); 613 562 614 - pow2_div = devm_kzalloc(dev, sizeof(*pow2_div), GFP_KERNEL); 615 - if (!pow2_div) 616 - return -ENOMEM; 617 - 618 563 snprintf(name, sizeof(name), "%s#pow2_div", dev_name(dev)); 619 564 init.name = name; 620 - init.ops = &clk_divider_ops; 621 - init.flags = CLK_SET_RATE_PARENT; 565 + init.ops = &meson_spicc_pow2_clk_ops; 566 + /* 567 + * Set NOCACHE here to make sure we read the actual HW value 568 + * since we reset the HW after each transfer. 569 + */ 570 + init.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE; 622 571 parent_data[0].hw = &pow2_fixed_div->hw; 623 572 init.num_parents = 1; 624 573 625 - pow2_div->shift = 16, 626 - pow2_div->width = 3, 627 - pow2_div->flags = CLK_DIVIDER_POWER_OF_TWO, 628 - pow2_div->reg = spicc->base + SPICC_CONREG; 629 - pow2_div->hw.init = &init; 574 + spicc->pow2_div.shift = 16, 575 + spicc->pow2_div.width = 3, 576 + spicc->pow2_div.flags = CLK_DIVIDER_POWER_OF_TWO, 577 + spicc->pow2_div.reg = spicc->base + SPICC_CONREG; 578 + spicc->pow2_div.hw.init = &init; 630 579 631 - clk = devm_clk_register(dev, &pow2_div->hw); 632 - if (WARN_ON(IS_ERR(clk))) 633 - return PTR_ERR(clk); 580 + spicc->clk = devm_clk_register(dev, &spicc->pow2_div.hw); 581 + if (WARN_ON(IS_ERR(spicc->clk))) 582 + return PTR_ERR(spicc->clk); 634 583 635 - if (!spicc->data->has_enhance_clk_div) { 636 - spicc->clk = clk; 637 - return 0; 638 - } 584 + return 0; 585 + } 586 + 587 + static int meson_spicc_enh_clk_init(struct meson_spicc_device *spicc) 588 + { 589 + struct device *dev = &spicc->pdev->dev; 590 + struct clk_fixed_factor *enh_fixed_div; 591 + struct clk_divider *enh_div; 592 + struct clk_mux *mux; 593 + struct clk_init_data init; 594 + struct clk *clk; 595 + struct clk_parent_data parent_data[2]; 596 + char name[64]; 597 + 598 + memset(&init, 0, sizeof(init)); 599 + memset(&parent_data, 0, sizeof(parent_data)); 600 + 601 + init.parent_data = parent_data; 639 602 640 603 /* algorithm for enh div: rate = freq / 2 / (N + 1) */ 641 604 ··· 702 637 snprintf(name, sizeof(name), "%s#sel", dev_name(dev)); 703 638 init.name = name; 704 639 init.ops = &clk_mux_ops; 705 - parent_data[0].hw = &pow2_div->hw; 640 + parent_data[0].hw = &spicc->pow2_div.hw; 706 641 parent_data[1].hw = &enh_div->hw; 707 642 init.num_parents = 2; 708 643 init.flags = CLK_SET_RATE_PARENT; ··· 819 754 820 755 meson_spicc_oen_enable(spicc); 821 756 822 - ret = meson_spicc_clk_init(spicc); 757 + ret = meson_spicc_pow2_clk_init(spicc); 823 758 if (ret) { 824 - dev_err(&pdev->dev, "clock registration failed\n"); 759 + dev_err(&pdev->dev, "pow2 clock registration failed\n"); 825 760 goto out_clk; 761 + } 762 + 763 + if (spicc->data->has_enhance_clk_div) { 764 + ret = meson_spicc_enh_clk_init(spicc); 765 + if (ret) { 766 + dev_err(&pdev->dev, "clock registration failed\n"); 767 + goto out_clk; 768 + } 826 769 } 827 770 828 771 ret = devm_spi_register_master(&pdev->dev, master);
+7 -7
drivers/spi/spi.c
··· 95 95 } 96 96 static DEVICE_ATTR_RW(driver_override); 97 97 98 - static struct spi_statistics *spi_alloc_pcpu_stats(struct device *dev) 98 + static struct spi_statistics __percpu *spi_alloc_pcpu_stats(struct device *dev) 99 99 { 100 100 struct spi_statistics __percpu *pcpu_stats; 101 101 ··· 162 162 } 163 163 164 164 #define SPI_STATISTICS_SHOW_NAME(name, file, field) \ 165 - static ssize_t spi_statistics_##name##_show(struct spi_statistics *stat, \ 165 + static ssize_t spi_statistics_##name##_show(struct spi_statistics __percpu *stat, \ 166 166 char *buf) \ 167 167 { \ 168 168 ssize_t len; \ ··· 309 309 NULL, 310 310 }; 311 311 312 - static void spi_statistics_add_transfer_stats(struct spi_statistics *pcpu_stats, 312 + static void spi_statistics_add_transfer_stats(struct spi_statistics __percpu *pcpu_stats, 313 313 struct spi_transfer *xfer, 314 314 struct spi_controller *ctlr) 315 315 { ··· 1275 1275 struct spi_message *msg, 1276 1276 struct spi_transfer *xfer) 1277 1277 { 1278 - struct spi_statistics *statm = ctlr->pcpu_statistics; 1279 - struct spi_statistics *stats = msg->spi->pcpu_statistics; 1278 + struct spi_statistics __percpu *statm = ctlr->pcpu_statistics; 1279 + struct spi_statistics __percpu *stats = msg->spi->pcpu_statistics; 1280 1280 u32 speed_hz = xfer->speed_hz; 1281 1281 unsigned long long ms; 1282 1282 ··· 1432 1432 struct spi_transfer *xfer; 1433 1433 bool keep_cs = false; 1434 1434 int ret = 0; 1435 - struct spi_statistics *statm = ctlr->pcpu_statistics; 1436 - struct spi_statistics *stats = msg->spi->pcpu_statistics; 1435 + struct spi_statistics __percpu *statm = ctlr->pcpu_statistics; 1436 + struct spi_statistics __percpu *stats = msg->spi->pcpu_statistics; 1437 1437 1438 1438 spi_set_cs(msg->spi, true, false); 1439 1439