Lines Matching +full:meson +full:- +full:gx +full:- +full:spicc

2  * Driver for Amlogic Meson SPI communication controller (SPICC)
7 * SPDX-License-Identifier: GPL-2.0+
12 #include <linux/clk-provider.h>
26 * The Meson SPICC controller could support DMA based transfers, but is not
30 * - all transfers are cutted in 16 words burst because the FIFO hangs on
31 * TX underflow, and there is no TX "Half-Empty" interrupt, so we go by
33 * - CS management is dumb, and goes UP between every burst, so is really a
69 #define SPICC_TH_EN BIT(1) /* TX FIFO Half-Full Interrupt */
72 #define SPICC_RH_EN BIT(4) /* RX FIFO Half-Full Interrupt */
89 #define SPICC_TH BIT(1) /* TX FIFO Half-Full Interrupt */
92 #define SPICC_RH BIT(4) /* RX FIFO Half-Full Interrupt */
104 #define SPICC_LBC_RO BIT(13) /* Loop Back Control Read-Only */
105 #define SPICC_LBC_W1 BIT(14) /* Loop Back Control Write-Only */
106 #define SPICC_SWAP_RO BIT(14) /* RX FIFO Data Swap Read-Only */
107 #define SPICC_SWAP_W1 BIT(15) /* RX FIFO Data Swap Write-Only */
108 #define SPICC_DLYCTL_RO_MASK GENMASK(20, 15) /* Delay Control Read-Only */
124 #define SPICC_FIFORST_RO_MASK GENMASK(22, 21) /* FIFO Softreset Read-Only */
125 #define SPICC_FIFORST_W1_MASK GENMASK(23, 22) /* FIFO Softreset Write-Only */
178 static void meson_spicc_oen_enable(struct meson_spicc_device *spicc) in meson_spicc_oen_enable() argument
182 if (!spicc->data->has_oen) { in meson_spicc_oen_enable()
184 spicc->pins_idle_high = pinctrl_lookup_state(spicc->pinctrl, in meson_spicc_oen_enable()
185 "idle-high"); in meson_spicc_oen_enable()
186 if (IS_ERR(spicc->pins_idle_high)) { in meson_spicc_oen_enable()
187 dev_warn(&spicc->pdev->dev, "can't get idle-high pinctrl\n"); in meson_spicc_oen_enable()
188 spicc->pins_idle_high = NULL; in meson_spicc_oen_enable()
190 spicc->pins_idle_low = pinctrl_lookup_state(spicc->pinctrl, in meson_spicc_oen_enable()
191 "idle-low"); in meson_spicc_oen_enable()
192 if (IS_ERR(spicc->pins_idle_low)) { in meson_spicc_oen_enable()
193 dev_warn(&spicc->pdev->dev, "can't get idle-low pinctrl\n"); in meson_spicc_oen_enable()
194 spicc->pins_idle_low = NULL; in meson_spicc_oen_enable()
199 conf = readl_relaxed(spicc->base + SPICC_ENH_CTL0) | in meson_spicc_oen_enable()
202 writel_relaxed(conf, spicc->base + SPICC_ENH_CTL0); in meson_spicc_oen_enable()
205 static inline bool meson_spicc_txfull(struct meson_spicc_device *spicc) in meson_spicc_txfull() argument
208 readl_relaxed(spicc->base + SPICC_STATREG)); in meson_spicc_txfull()
211 static inline bool meson_spicc_rxready(struct meson_spicc_device *spicc) in meson_spicc_rxready() argument
214 readl_relaxed(spicc->base + SPICC_STATREG)); in meson_spicc_rxready()
217 static inline u32 meson_spicc_pull_data(struct meson_spicc_device *spicc) in meson_spicc_pull_data() argument
219 unsigned int bytes = spicc->bytes_per_word; in meson_spicc_pull_data()
224 while (bytes--) { in meson_spicc_pull_data()
225 byte = *spicc->tx_buf++; in meson_spicc_pull_data()
230 spicc->tx_remain--; in meson_spicc_pull_data()
234 static inline void meson_spicc_push_data(struct meson_spicc_device *spicc, in meson_spicc_push_data() argument
237 unsigned int bytes = spicc->bytes_per_word; in meson_spicc_push_data()
241 while (bytes--) { in meson_spicc_push_data()
243 *spicc->rx_buf++ = byte; in meson_spicc_push_data()
247 spicc->rx_remain--; in meson_spicc_push_data()
250 static inline void meson_spicc_rx(struct meson_spicc_device *spicc) in meson_spicc_rx() argument
253 while (spicc->rx_remain && in meson_spicc_rx()
254 meson_spicc_rxready(spicc)) in meson_spicc_rx()
255 meson_spicc_push_data(spicc, in meson_spicc_rx()
256 readl_relaxed(spicc->base + SPICC_RXDATA)); in meson_spicc_rx()
259 static inline void meson_spicc_tx(struct meson_spicc_device *spicc) in meson_spicc_tx() argument
262 while (spicc->tx_remain && in meson_spicc_tx()
263 !meson_spicc_txfull(spicc)) in meson_spicc_tx()
264 writel_relaxed(meson_spicc_pull_data(spicc), in meson_spicc_tx()
265 spicc->base + SPICC_TXDATA); in meson_spicc_tx()
268 static inline void meson_spicc_setup_burst(struct meson_spicc_device *spicc) in meson_spicc_setup_burst() argument
272 spicc->xfer_remain / in meson_spicc_setup_burst()
273 spicc->bytes_per_word, in meson_spicc_setup_burst()
274 spicc->data->fifo_size); in meson_spicc_setup_burst()
276 spicc->tx_remain = burst_len; in meson_spicc_setup_burst()
277 spicc->rx_remain = burst_len; in meson_spicc_setup_burst()
278 spicc->xfer_remain -= burst_len * spicc->bytes_per_word; in meson_spicc_setup_burst()
283 burst_len - 1), in meson_spicc_setup_burst()
284 spicc->base + SPICC_CONREG); in meson_spicc_setup_burst()
287 meson_spicc_tx(spicc); in meson_spicc_setup_burst()
292 struct meson_spicc_device *spicc = (void *) data; in meson_spicc_irq() local
294 writel_bits_relaxed(SPICC_TC, SPICC_TC, spicc->base + SPICC_STATREG); in meson_spicc_irq()
297 meson_spicc_rx(spicc); in meson_spicc_irq()
299 if (!spicc->xfer_remain) { in meson_spicc_irq()
301 writel(0, spicc->base + SPICC_INTREG); in meson_spicc_irq()
303 complete(&spicc->done); in meson_spicc_irq()
309 meson_spicc_setup_burst(spicc); in meson_spicc_irq()
312 writel_bits_relaxed(SPICC_XCH, SPICC_XCH, spicc->base + SPICC_CONREG); in meson_spicc_irq()
317 static void meson_spicc_auto_io_delay(struct meson_spicc_device *spicc) in meson_spicc_auto_io_delay() argument
323 if (spicc->data->has_enhance_clk_div) { in meson_spicc_auto_io_delay()
325 readl_relaxed(spicc->base + SPICC_ENH_CTL0)); in meson_spicc_auto_io_delay()
330 readl_relaxed(spicc->base + SPICC_CONREG)); in meson_spicc_auto_io_delay()
337 hz = clk_get_rate(spicc->clk); in meson_spicc_auto_io_delay()
352 conf = readl_relaxed(spicc->base + SPICC_TESTREG); in meson_spicc_auto_io_delay()
357 writel_relaxed(conf, spicc->base + SPICC_TESTREG); in meson_spicc_auto_io_delay()
360 static void meson_spicc_setup_xfer(struct meson_spicc_device *spicc, in meson_spicc_setup_xfer() argument
366 conf = conf_orig = readl_relaxed(spicc->base + SPICC_CONREG); in meson_spicc_setup_xfer()
371 (spicc->bytes_per_word << 3) - 1); in meson_spicc_setup_xfer()
375 writel_relaxed(conf, spicc->base + SPICC_CONREG); in meson_spicc_setup_xfer()
377 clk_set_rate(spicc->clk, xfer->speed_hz); in meson_spicc_setup_xfer()
379 meson_spicc_auto_io_delay(spicc); in meson_spicc_setup_xfer()
381 writel_relaxed(0, spicc->base + SPICC_DMAREG); in meson_spicc_setup_xfer()
384 static void meson_spicc_reset_fifo(struct meson_spicc_device *spicc) in meson_spicc_reset_fifo() argument
386 if (spicc->data->has_oen) in meson_spicc_reset_fifo()
389 spicc->base + SPICC_ENH_CTL0); in meson_spicc_reset_fifo()
392 spicc->base + SPICC_TESTREG); in meson_spicc_reset_fifo()
394 while (meson_spicc_rxready(spicc)) in meson_spicc_reset_fifo()
395 readl_relaxed(spicc->base + SPICC_RXDATA); in meson_spicc_reset_fifo()
397 if (spicc->data->has_oen) in meson_spicc_reset_fifo()
399 spicc->base + SPICC_ENH_CTL0); in meson_spicc_reset_fifo()
406 struct meson_spicc_device *spicc = spi_master_get_devdata(master); in meson_spicc_transfer_one() local
410 spicc->xfer = xfer; in meson_spicc_transfer_one()
413 spicc->tx_buf = (u8 *)xfer->tx_buf; in meson_spicc_transfer_one()
414 spicc->rx_buf = (u8 *)xfer->rx_buf; in meson_spicc_transfer_one()
415 spicc->xfer_remain = xfer->len; in meson_spicc_transfer_one()
417 /* Pre-calculate word size */ in meson_spicc_transfer_one()
418 spicc->bytes_per_word = in meson_spicc_transfer_one()
419 DIV_ROUND_UP(spicc->xfer->bits_per_word, 8); in meson_spicc_transfer_one()
421 if (xfer->len % spicc->bytes_per_word) in meson_spicc_transfer_one()
422 return -EINVAL; in meson_spicc_transfer_one()
425 meson_spicc_setup_xfer(spicc, xfer); in meson_spicc_transfer_one()
427 meson_spicc_reset_fifo(spicc); in meson_spicc_transfer_one()
430 meson_spicc_setup_burst(spicc); in meson_spicc_transfer_one()
433 reinit_completion(&spicc->done); in meson_spicc_transfer_one()
436 timeout = 8LL * MSEC_PER_SEC * xfer->len; in meson_spicc_transfer_one()
437 do_div(timeout, xfer->speed_hz); in meson_spicc_transfer_one()
440 timeout += ((xfer->len >> 4) * 10) / MSEC_PER_SEC; in meson_spicc_transfer_one()
446 writel_bits_relaxed(SPICC_XCH, SPICC_XCH, spicc->base + SPICC_CONREG); in meson_spicc_transfer_one()
449 writel_relaxed(SPICC_TC_EN, spicc->base + SPICC_INTREG); in meson_spicc_transfer_one()
451 if (!wait_for_completion_timeout(&spicc->done, msecs_to_jiffies(timeout))) in meson_spicc_transfer_one()
452 return -ETIMEDOUT; in meson_spicc_transfer_one()
460 struct meson_spicc_device *spicc = spi_master_get_devdata(master); in meson_spicc_prepare_message() local
461 struct spi_device *spi = message->spi; in meson_spicc_prepare_message()
462 u32 conf = readl_relaxed(spicc->base + SPICC_CONREG) & SPICC_DATARATE_MASK; in meson_spicc_prepare_message()
465 spicc->message = message; in meson_spicc_prepare_message()
474 if (spi->mode & SPI_CPOL) in meson_spicc_prepare_message()
479 if (!spicc->data->has_oen) { in meson_spicc_prepare_message()
480 if (spi->mode & SPI_CPOL) { in meson_spicc_prepare_message()
481 if (spicc->pins_idle_high) in meson_spicc_prepare_message()
482 pinctrl_select_state(spicc->pinctrl, spicc->pins_idle_high); in meson_spicc_prepare_message()
484 if (spicc->pins_idle_low) in meson_spicc_prepare_message()
485 pinctrl_select_state(spicc->pinctrl, spicc->pins_idle_low); in meson_spicc_prepare_message()
489 if (spi->mode & SPI_CPHA) in meson_spicc_prepare_message()
496 if (spi->mode & SPI_CS_HIGH) in meson_spicc_prepare_message()
501 if (spi->mode & SPI_READY) in meson_spicc_prepare_message()
510 conf |= FIELD_PREP(SPICC_BITLENGTH_MASK, 8 - 1); in meson_spicc_prepare_message()
512 writel_relaxed(conf, spicc->base + SPICC_CONREG); in meson_spicc_prepare_message()
515 writel_relaxed(0, spicc->base + SPICC_PERIODREG); in meson_spicc_prepare_message()
517 writel_bits_relaxed(SPICC_LBC_W1, 0, spicc->base + SPICC_TESTREG); in meson_spicc_prepare_message()
524 struct meson_spicc_device *spicc = spi_master_get_devdata(master); in meson_spicc_unprepare_transfer() local
525 u32 conf = readl_relaxed(spicc->base + SPICC_CONREG) & SPICC_DATARATE_MASK; in meson_spicc_unprepare_transfer()
528 writel(0, spicc->base + SPICC_INTREG); in meson_spicc_unprepare_transfer()
530 device_reset_optional(&spicc->pdev->dev); in meson_spicc_unprepare_transfer()
533 writel_relaxed(conf, spicc->base + SPICC_CONREG); in meson_spicc_unprepare_transfer()
535 if (!spicc->data->has_oen) in meson_spicc_unprepare_transfer()
536 pinctrl_select_default_state(&spicc->pdev->dev); in meson_spicc_unprepare_transfer()
543 if (!spi->controller_state) in meson_spicc_setup()
544 spi->controller_state = spi_master_get_devdata(spi->master); in meson_spicc_setup()
551 spi->controller_state = NULL; in meson_spicc_cleanup()
556 * x-----------------x x------------x x------\
557 * |---| pow2 fixed div |---| pow2 div |----| |
558 * | x-----------------x x------------x | |
559 * src ---| | mux |-- out
560 * | x-----------------x x------------x | |
561 * |---| enh fixed div |---| enh div |0---| |
562 * x-----------------x x------------x x------/
564 * Clk path for GX series:
565 * src -> pow2 fixed div -> pow2 div -> out
568 * src -> pow2 fixed div -> pow2 div -> mux -> out
569 * src -> enh fixed div -> enh div -> mux -> out
572 * pclk -> pow2 fixed div -> pow2 div -> mux -> out
573 * pclk -> enh fixed div -> enh div -> mux -> out
586 struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); in meson_spicc_pow2_recalc_rate() local
588 if (!spicc->master->cur_msg) in meson_spicc_pow2_recalc_rate()
598 struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); in meson_spicc_pow2_determine_rate() local
600 if (!spicc->master->cur_msg) in meson_spicc_pow2_determine_rate()
601 return -EINVAL; in meson_spicc_pow2_determine_rate()
610 struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); in meson_spicc_pow2_set_rate() local
612 if (!spicc->master->cur_msg) in meson_spicc_pow2_set_rate()
613 return -EINVAL; in meson_spicc_pow2_set_rate()
624 static int meson_spicc_pow2_clk_init(struct meson_spicc_device *spicc) in meson_spicc_pow2_clk_init() argument
626 struct device *dev = &spicc->pdev->dev; in meson_spicc_pow2_clk_init()
642 return -ENOMEM; in meson_spicc_pow2_clk_init()
648 if (spicc->data->has_pclk) in meson_spicc_pow2_clk_init()
649 parent_data[0].hw = __clk_get_hw(spicc->pclk); in meson_spicc_pow2_clk_init()
651 parent_data[0].hw = __clk_get_hw(spicc->core); in meson_spicc_pow2_clk_init()
654 pow2_fixed_div->mult = 1, in meson_spicc_pow2_clk_init()
655 pow2_fixed_div->div = 4, in meson_spicc_pow2_clk_init()
656 pow2_fixed_div->hw.init = &init; in meson_spicc_pow2_clk_init()
658 clk = devm_clk_register(dev, &pow2_fixed_div->hw); in meson_spicc_pow2_clk_init()
670 parent_data[0].hw = &pow2_fixed_div->hw; in meson_spicc_pow2_clk_init()
673 spicc->pow2_div.shift = 16, in meson_spicc_pow2_clk_init()
674 spicc->pow2_div.width = 3, in meson_spicc_pow2_clk_init()
675 spicc->pow2_div.flags = CLK_DIVIDER_POWER_OF_TWO, in meson_spicc_pow2_clk_init()
676 spicc->pow2_div.reg = spicc->base + SPICC_CONREG; in meson_spicc_pow2_clk_init()
677 spicc->pow2_div.hw.init = &init; in meson_spicc_pow2_clk_init()
679 spicc->clk = devm_clk_register(dev, &spicc->pow2_div.hw); in meson_spicc_pow2_clk_init()
680 if (WARN_ON(IS_ERR(spicc->clk))) in meson_spicc_pow2_clk_init()
681 return PTR_ERR(spicc->clk); in meson_spicc_pow2_clk_init()
686 static int meson_spicc_enh_clk_init(struct meson_spicc_device *spicc) in meson_spicc_enh_clk_init() argument
688 struct device *dev = &spicc->pdev->dev; in meson_spicc_enh_clk_init()
706 return -ENOMEM; in meson_spicc_enh_clk_init()
712 if (spicc->data->has_pclk) in meson_spicc_enh_clk_init()
713 parent_data[0].hw = __clk_get_hw(spicc->pclk); in meson_spicc_enh_clk_init()
715 parent_data[0].hw = __clk_get_hw(spicc->core); in meson_spicc_enh_clk_init()
718 enh_fixed_div->mult = 1, in meson_spicc_enh_clk_init()
719 enh_fixed_div->div = 2, in meson_spicc_enh_clk_init()
720 enh_fixed_div->hw.init = &init; in meson_spicc_enh_clk_init()
722 clk = devm_clk_register(dev, &enh_fixed_div->hw); in meson_spicc_enh_clk_init()
728 return -ENOMEM; in meson_spicc_enh_clk_init()
734 parent_data[0].hw = &enh_fixed_div->hw; in meson_spicc_enh_clk_init()
737 enh_div->shift = 16, in meson_spicc_enh_clk_init()
738 enh_div->width = 8, in meson_spicc_enh_clk_init()
739 enh_div->reg = spicc->base + SPICC_ENH_CTL0; in meson_spicc_enh_clk_init()
740 enh_div->hw.init = &init; in meson_spicc_enh_clk_init()
742 clk = devm_clk_register(dev, &enh_div->hw); in meson_spicc_enh_clk_init()
748 return -ENOMEM; in meson_spicc_enh_clk_init()
753 parent_data[0].hw = &spicc->pow2_div.hw; in meson_spicc_enh_clk_init()
754 parent_data[1].hw = &enh_div->hw; in meson_spicc_enh_clk_init()
758 mux->mask = 0x1, in meson_spicc_enh_clk_init()
759 mux->shift = 24, in meson_spicc_enh_clk_init()
760 mux->reg = spicc->base + SPICC_ENH_CTL0; in meson_spicc_enh_clk_init()
761 mux->hw.init = &init; in meson_spicc_enh_clk_init()
763 spicc->clk = devm_clk_register(dev, &mux->hw); in meson_spicc_enh_clk_init()
764 if (WARN_ON(IS_ERR(spicc->clk))) in meson_spicc_enh_clk_init()
765 return PTR_ERR(spicc->clk); in meson_spicc_enh_clk_init()
773 struct meson_spicc_device *spicc; in meson_spicc_probe() local
776 master = spi_alloc_master(&pdev->dev, sizeof(*spicc)); in meson_spicc_probe()
778 dev_err(&pdev->dev, "master allocation failed\n"); in meson_spicc_probe()
779 return -ENOMEM; in meson_spicc_probe()
781 spicc = spi_master_get_devdata(master); in meson_spicc_probe()
782 spicc->master = master; in meson_spicc_probe()
784 spicc->data = of_device_get_match_data(&pdev->dev); in meson_spicc_probe()
785 if (!spicc->data) { in meson_spicc_probe()
786 dev_err(&pdev->dev, "failed to get match data\n"); in meson_spicc_probe()
787 ret = -EINVAL; in meson_spicc_probe()
791 spicc->pdev = pdev; in meson_spicc_probe()
792 platform_set_drvdata(pdev, spicc); in meson_spicc_probe()
794 init_completion(&spicc->done); in meson_spicc_probe()
796 spicc->base = devm_platform_ioremap_resource(pdev, 0); in meson_spicc_probe()
797 if (IS_ERR(spicc->base)) { in meson_spicc_probe()
798 dev_err(&pdev->dev, "io resource mapping failed\n"); in meson_spicc_probe()
799 ret = PTR_ERR(spicc->base); in meson_spicc_probe()
805 spicc->base + SPICC_CONREG); in meson_spicc_probe()
808 writel_relaxed(0, spicc->base + SPICC_INTREG); in meson_spicc_probe()
816 ret = devm_request_irq(&pdev->dev, irq, meson_spicc_irq, in meson_spicc_probe()
817 0, NULL, spicc); in meson_spicc_probe()
819 dev_err(&pdev->dev, "irq request failed\n"); in meson_spicc_probe()
823 spicc->core = devm_clk_get(&pdev->dev, "core"); in meson_spicc_probe()
824 if (IS_ERR(spicc->core)) { in meson_spicc_probe()
825 dev_err(&pdev->dev, "core clock request failed\n"); in meson_spicc_probe()
826 ret = PTR_ERR(spicc->core); in meson_spicc_probe()
830 if (spicc->data->has_pclk) { in meson_spicc_probe()
831 spicc->pclk = devm_clk_get(&pdev->dev, "pclk"); in meson_spicc_probe()
832 if (IS_ERR(spicc->pclk)) { in meson_spicc_probe()
833 dev_err(&pdev->dev, "pclk clock request failed\n"); in meson_spicc_probe()
834 ret = PTR_ERR(spicc->pclk); in meson_spicc_probe()
839 ret = clk_prepare_enable(spicc->core); in meson_spicc_probe()
841 dev_err(&pdev->dev, "core clock enable failed\n"); in meson_spicc_probe()
845 ret = clk_prepare_enable(spicc->pclk); in meson_spicc_probe()
847 dev_err(&pdev->dev, "pclk clock enable failed\n"); in meson_spicc_probe()
851 spicc->pinctrl = devm_pinctrl_get(&pdev->dev); in meson_spicc_probe()
852 if (IS_ERR(spicc->pinctrl)) { in meson_spicc_probe()
853 ret = PTR_ERR(spicc->pinctrl); in meson_spicc_probe()
857 device_reset_optional(&pdev->dev); in meson_spicc_probe()
859 master->num_chipselect = 4; in meson_spicc_probe()
860 master->dev.of_node = pdev->dev.of_node; in meson_spicc_probe()
861 master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH; in meson_spicc_probe()
862 master->bits_per_word_mask = SPI_BPW_MASK(32) | in meson_spicc_probe()
866 master->flags = (SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX); in meson_spicc_probe()
867 master->min_speed_hz = spicc->data->min_speed_hz; in meson_spicc_probe()
868 master->max_speed_hz = spicc->data->max_speed_hz; in meson_spicc_probe()
869 master->setup = meson_spicc_setup; in meson_spicc_probe()
870 master->cleanup = meson_spicc_cleanup; in meson_spicc_probe()
871 master->prepare_message = meson_spicc_prepare_message; in meson_spicc_probe()
872 master->unprepare_transfer_hardware = meson_spicc_unprepare_transfer; in meson_spicc_probe()
873 master->transfer_one = meson_spicc_transfer_one; in meson_spicc_probe()
874 master->use_gpio_descriptors = true; in meson_spicc_probe()
876 meson_spicc_oen_enable(spicc); in meson_spicc_probe()
878 ret = meson_spicc_pow2_clk_init(spicc); in meson_spicc_probe()
880 dev_err(&pdev->dev, "pow2 clock registration failed\n"); in meson_spicc_probe()
884 if (spicc->data->has_enhance_clk_div) { in meson_spicc_probe()
885 ret = meson_spicc_enh_clk_init(spicc); in meson_spicc_probe()
887 dev_err(&pdev->dev, "clock registration failed\n"); in meson_spicc_probe()
892 ret = devm_spi_register_master(&pdev->dev, master); in meson_spicc_probe()
894 dev_err(&pdev->dev, "spi master registration failed\n"); in meson_spicc_probe()
901 clk_disable_unprepare(spicc->pclk); in meson_spicc_probe()
904 clk_disable_unprepare(spicc->core); in meson_spicc_probe()
914 struct meson_spicc_device *spicc = platform_get_drvdata(pdev); in meson_spicc_remove() local
917 writel(0, spicc->base + SPICC_CONREG); in meson_spicc_remove()
919 clk_disable_unprepare(spicc->core); in meson_spicc_remove()
920 clk_disable_unprepare(spicc->pclk); in meson_spicc_remove()
922 spi_master_put(spicc->master); in meson_spicc_remove()
950 .compatible = "amlogic,meson-gx-spicc",
954 .compatible = "amlogic,meson-axg-spicc",
958 .compatible = "amlogic,meson-g12a-spicc",
969 .name = "meson-spicc",
976 MODULE_DESCRIPTION("Meson SPI Communication Controller driver");