tangled
alpha
login
or
join now
tjh.dev
/
kernel
1
fork
atom
Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1
fork
atom
overview
issues
pulls
pipelines
Merge remote-tracking branch 'spi/for-5.20' into spi-6.0
Mark Brown
3 years ago
75c971dd
568035b0
+112
-39
6 changed files
expand all
collapse all
unified
split
Documentation
devicetree
bindings
spi
cdns,qspi-nor-peripheral-props.yaml
cdns,qspi-nor.yaml
spi-peripheral-props.yaml
MAINTAINERS
drivers
spi
spi-meson-spicc.c
spi.c
+1
-1
Documentation/devicetree/bindings/spi/cdns,qspi-nor-peripheral-props.yaml
reviewed
···
10
10
See spi-peripheral-props.yaml for more info.
11
11
12
12
maintainers:
13
13
-
- Pratyush Yadav <p.yadav@ti.com>
13
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
reviewed
···
7
7
title: Cadence Quad SPI controller
8
8
9
9
maintainers:
10
10
-
- Pratyush Yadav <p.yadav@ti.com>
10
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
reviewed
···
16
16
their own separate schema that should be referenced from here.
17
17
18
18
maintainers:
19
19
-
- Pratyush Yadav <p.yadav@ti.com>
19
19
+
- Mark Brown <broonie@kernel.org>
20
20
21
21
properties:
22
22
reg:
+1
-1
MAINTAINERS
reviewed
···
2178
2178
M: Nick Hawkins <nick.hawkins@hpe.com>
2179
2179
S: Maintained
2180
2180
F: Documentation/devicetree/bindings/arm/hpe,gxp.yaml
2181
2181
-
F: Documentation/devicetree/bindings/spi/hpe,gxp-spi.yaml
2181
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
reviewed
···
156
156
void __iomem *base;
157
157
struct clk *core;
158
158
struct clk *pclk;
159
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
170
+
171
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
427
-
u32 conf = 0;
424
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
464
-
/* Default Clock rate core/4 */
465
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
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
485
+
486
486
+
/* Set default configuration, keeping datarate field */
487
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
521
+
*
522
522
+
* The pow2 divider is tied to the controller HW state, and the
523
523
+
* divider is only valid when the controller is initialized.
524
524
+
*
525
525
+
* A set of clock ops is added to make sure we don't read/set this
526
526
+
* clock rate while the controller is in an unknown state.
526
527
*/
527
528
528
528
-
static int meson_spicc_clk_init(struct meson_spicc_device *spicc)
529
529
+
static unsigned long meson_spicc_pow2_recalc_rate(struct clk_hw *hw,
530
530
+
unsigned long parent_rate)
531
531
+
{
532
532
+
struct clk_divider *divider = to_clk_divider(hw);
533
533
+
struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
534
534
+
535
535
+
if (!spicc->master->cur_msg || !spicc->master->busy)
536
536
+
return 0;
537
537
+
538
538
+
return clk_divider_ops.recalc_rate(hw, parent_rate);
539
539
+
}
540
540
+
541
541
+
static int meson_spicc_pow2_determine_rate(struct clk_hw *hw,
542
542
+
struct clk_rate_request *req)
543
543
+
{
544
544
+
struct clk_divider *divider = to_clk_divider(hw);
545
545
+
struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
546
546
+
547
547
+
if (!spicc->master->cur_msg || !spicc->master->busy)
548
548
+
return -EINVAL;
549
549
+
550
550
+
return clk_divider_ops.determine_rate(hw, req);
551
551
+
}
552
552
+
553
553
+
static int meson_spicc_pow2_set_rate(struct clk_hw *hw, unsigned long rate,
554
554
+
unsigned long parent_rate)
555
555
+
{
556
556
+
struct clk_divider *divider = to_clk_divider(hw);
557
557
+
struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
558
558
+
559
559
+
if (!spicc->master->cur_msg || !spicc->master->busy)
560
560
+
return -EINVAL;
561
561
+
562
562
+
return clk_divider_ops.set_rate(hw, rate, parent_rate);
563
563
+
}
564
564
+
565
565
+
const struct clk_ops meson_spicc_pow2_clk_ops = {
566
566
+
.recalc_rate = meson_spicc_pow2_recalc_rate,
567
567
+
.determine_rate = meson_spicc_pow2_determine_rate,
568
568
+
.set_rate = meson_spicc_pow2_set_rate,
569
569
+
};
570
570
+
571
571
+
static int meson_spicc_pow2_clk_init(struct meson_spicc_device *spicc)
529
572
{
530
573
struct device *dev = &spicc->pdev->dev;
531
531
-
struct clk_fixed_factor *pow2_fixed_div, *enh_fixed_div;
532
532
-
struct clk_divider *pow2_div, *enh_div;
533
533
-
struct clk_mux *mux;
574
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
614
-
pow2_div = devm_kzalloc(dev, sizeof(*pow2_div), GFP_KERNEL);
615
615
-
if (!pow2_div)
616
616
-
return -ENOMEM;
617
617
-
618
563
snprintf(name, sizeof(name), "%s#pow2_div", dev_name(dev));
619
564
init.name = name;
620
620
-
init.ops = &clk_divider_ops;
621
621
-
init.flags = CLK_SET_RATE_PARENT;
565
565
+
init.ops = &meson_spicc_pow2_clk_ops;
566
566
+
/*
567
567
+
* Set NOCACHE here to make sure we read the actual HW value
568
568
+
* since we reset the HW after each transfer.
569
569
+
*/
570
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
625
-
pow2_div->shift = 16,
626
626
-
pow2_div->width = 3,
627
627
-
pow2_div->flags = CLK_DIVIDER_POWER_OF_TWO,
628
628
-
pow2_div->reg = spicc->base + SPICC_CONREG;
629
629
-
pow2_div->hw.init = &init;
574
574
+
spicc->pow2_div.shift = 16,
575
575
+
spicc->pow2_div.width = 3,
576
576
+
spicc->pow2_div.flags = CLK_DIVIDER_POWER_OF_TWO,
577
577
+
spicc->pow2_div.reg = spicc->base + SPICC_CONREG;
578
578
+
spicc->pow2_div.hw.init = &init;
630
579
631
631
-
clk = devm_clk_register(dev, &pow2_div->hw);
632
632
-
if (WARN_ON(IS_ERR(clk)))
633
633
-
return PTR_ERR(clk);
580
580
+
spicc->clk = devm_clk_register(dev, &spicc->pow2_div.hw);
581
581
+
if (WARN_ON(IS_ERR(spicc->clk)))
582
582
+
return PTR_ERR(spicc->clk);
634
583
635
635
-
if (!spicc->data->has_enhance_clk_div) {
636
636
-
spicc->clk = clk;
637
637
-
return 0;
638
638
-
}
584
584
+
return 0;
585
585
+
}
586
586
+
587
587
+
static int meson_spicc_enh_clk_init(struct meson_spicc_device *spicc)
588
588
+
{
589
589
+
struct device *dev = &spicc->pdev->dev;
590
590
+
struct clk_fixed_factor *enh_fixed_div;
591
591
+
struct clk_divider *enh_div;
592
592
+
struct clk_mux *mux;
593
593
+
struct clk_init_data init;
594
594
+
struct clk *clk;
595
595
+
struct clk_parent_data parent_data[2];
596
596
+
char name[64];
597
597
+
598
598
+
memset(&init, 0, sizeof(init));
599
599
+
memset(&parent_data, 0, sizeof(parent_data));
600
600
+
601
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
705
-
parent_data[0].hw = &pow2_div->hw;
640
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
822
-
ret = meson_spicc_clk_init(spicc);
757
757
+
ret = meson_spicc_pow2_clk_init(spicc);
823
758
if (ret) {
824
824
-
dev_err(&pdev->dev, "clock registration failed\n");
759
759
+
dev_err(&pdev->dev, "pow2 clock registration failed\n");
825
760
goto out_clk;
761
761
+
}
762
762
+
763
763
+
if (spicc->data->has_enhance_clk_div) {
764
764
+
ret = meson_spicc_enh_clk_init(spicc);
765
765
+
if (ret) {
766
766
+
dev_err(&pdev->dev, "clock registration failed\n");
767
767
+
goto out_clk;
768
768
+
}
826
769
}
827
770
828
771
ret = devm_spi_register_master(&pdev->dev, master);
+7
-7
drivers/spi/spi.c
reviewed
···
95
95
}
96
96
static DEVICE_ATTR_RW(driver_override);
97
97
98
98
-
static struct spi_statistics *spi_alloc_pcpu_stats(struct device *dev)
98
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
165
-
static ssize_t spi_statistics_##name##_show(struct spi_statistics *stat, \
165
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
312
-
static void spi_statistics_add_transfer_stats(struct spi_statistics *pcpu_stats,
312
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
1278
-
struct spi_statistics *statm = ctlr->pcpu_statistics;
1279
1279
-
struct spi_statistics *stats = msg->spi->pcpu_statistics;
1278
1278
+
struct spi_statistics __percpu *statm = ctlr->pcpu_statistics;
1279
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
1435
-
struct spi_statistics *statm = ctlr->pcpu_statistics;
1436
1436
-
struct spi_statistics *stats = msg->spi->pcpu_statistics;
1435
1435
+
struct spi_statistics __percpu *statm = ctlr->pcpu_statistics;
1436
1436
+
struct spi_statistics __percpu *stats = msg->spi->pcpu_statistics;
1437
1437
1438
1438
spi_set_cs(msg->spi, true, false);
1439
1439