Lines Matching +full:qe +full:- +full:tsa
1 // SPDX-License-Identifier: GPL-2.0
3 * TSA driver
10 #include "tsa.h"
11 #include <dt-bindings/soc/cpm1-fsl,tsa.h>
12 #include <dt-bindings/soc/qe-fsl,tsa.h>
21 #include <soc/fsl/qe/ucc.h>
23 /* TSA SI RAM routing tables entry (CPM1) */
36 /* TSA SI RAM routing tables entry (QE) */
51 * - CPM1: 32bit register split in 2*16bit (16bit TDM)
52 * - QE: 4x16bit registers, one per TDM
78 #define TSA_QE_SIMODE_TDM_SL BIT(5) /* bit 5: SL in QE */
95 /* QE SI global mode register high (8 bits) */
149 #define TSA_TDMC 2 /* QE implementation only */
150 #define TSA_TDMD 3 /* QE implementation only */
157 struct tsa { struct
170 /* Same number of serials for CPM1 and QE:
172 * QE: NU and 5 UCCs
180 static inline struct tsa *tsa_serial_get_tsa(struct tsa_serial *tsa_serial) in tsa_serial_get_tsa() argument
183 return container_of(tsa_serial, struct tsa, serials[tsa_serial->id]); in tsa_serial_get_tsa()
226 static bool tsa_is_qe(const struct tsa *tsa) in tsa_is_qe() argument
229 return tsa->version == TSA_QE; in tsa_is_qe()
236 struct tsa *tsa = tsa_serial_get_tsa(tsa_serial); in tsa_qe_serial_get_num() local
238 switch (tsa_serial->id) { in tsa_qe_serial_get_num()
248 dev_err(tsa->dev, "Unsupported serial id %u\n", tsa_serial->id); in tsa_qe_serial_get_num()
249 return -EINVAL; in tsa_qe_serial_get_num()
254 struct tsa *tsa = tsa_serial_get_tsa(tsa_serial); in tsa_serial_get_num() local
257 * There is no need to get the serial num out of the TSA driver in the in tsa_serial_get_num()
263 return tsa_is_qe(tsa) ? tsa_qe_serial_get_num(tsa_serial) : -EOPNOTSUPP; in tsa_serial_get_num()
269 struct tsa *tsa = tsa_serial_get_tsa(tsa_serial); in tsa_cpm1_serial_connect() local
274 switch (tsa_serial->id) { in tsa_cpm1_serial_connect()
288 dev_err(tsa->dev, "Unsupported serial id %u\n", tsa_serial->id); in tsa_cpm1_serial_connect()
289 return -EINVAL; in tsa_cpm1_serial_connect()
292 spin_lock_irqsave(&tsa->lock, flags); in tsa_cpm1_serial_connect()
293 tsa_clrsetbits32(tsa->si_regs + TSA_CPM1_SICR, clear, in tsa_cpm1_serial_connect()
295 spin_unlock_irqrestore(&tsa->lock, flags); in tsa_cpm1_serial_connect()
302 struct tsa *tsa = tsa_serial_get_tsa(tsa_serial); in tsa_qe_serial_connect() local
311 spin_lock_irqsave(&tsa->lock, flags); in tsa_qe_serial_connect()
313 spin_unlock_irqrestore(&tsa->lock, flags); in tsa_qe_serial_connect()
315 dev_err(tsa->dev, "Connect serial id %u to TSA failed (%d)\n", in tsa_qe_serial_connect()
316 tsa_serial->id, ret); in tsa_qe_serial_connect()
324 struct tsa *tsa = tsa_serial_get_tsa(tsa_serial); in tsa_serial_connect() local
326 return tsa_is_qe(tsa) ? in tsa_serial_connect()
334 struct tsa *tsa = tsa_serial_get_tsa(tsa_serial); in tsa_serial_disconnect() local
336 return tsa_is_qe(tsa) ? in tsa_serial_disconnect()
344 memcpy(info, &tsa_serial->info, sizeof(*info)); in tsa_serial_get_info()
349 static void tsa_cpm1_init_entries_area(struct tsa *tsa, struct tsa_entries_area *area, in tsa_cpm1_init_entries_area() argument
355 quarter = tsa->si_ram_sz / 4; in tsa_cpm1_init_entries_area()
356 half = tsa->si_ram_sz / 2; in tsa_cpm1_init_entries_area()
362 area->entries_start = tsa->si_ram; in tsa_cpm1_init_entries_area()
363 area->entries_next = area->entries_start + half; in tsa_cpm1_init_entries_area()
364 area->last_entry = NULL; in tsa_cpm1_init_entries_area()
367 area->entries_start = tsa->si_ram + half; in tsa_cpm1_init_entries_area()
368 area->entries_next = area->entries_start + half; in tsa_cpm1_init_entries_area()
369 area->last_entry = NULL; in tsa_cpm1_init_entries_area()
376 area->entries_start = tsa->si_ram; in tsa_cpm1_init_entries_area()
377 area->entries_next = area->entries_start + quarter; in tsa_cpm1_init_entries_area()
378 area->last_entry = NULL; in tsa_cpm1_init_entries_area()
381 area->entries_start = tsa->si_ram + (2 * quarter); in tsa_cpm1_init_entries_area()
382 area->entries_next = area->entries_start + quarter; in tsa_cpm1_init_entries_area()
383 area->last_entry = NULL; in tsa_cpm1_init_entries_area()
388 area->entries_start = tsa->si_ram + quarter; in tsa_cpm1_init_entries_area()
389 area->entries_next = area->entries_start + quarter; in tsa_cpm1_init_entries_area()
390 area->last_entry = NULL; in tsa_cpm1_init_entries_area()
393 area->entries_start = tsa->si_ram + (3 * quarter); in tsa_cpm1_init_entries_area()
394 area->entries_next = area->entries_start + quarter; in tsa_cpm1_init_entries_area()
395 area->last_entry = NULL; in tsa_cpm1_init_entries_area()
401 static void tsa_qe_init_entries_area(struct tsa *tsa, struct tsa_entries_area *area, in tsa_qe_init_entries_area() argument
407 eighth = tsa->si_ram_sz / 8; in tsa_qe_init_entries_area()
408 half = tsa->si_ram_sz / 2; in tsa_qe_init_entries_area()
416 area->entries_start = tsa->si_ram + half + (eighth * tdm_id); in tsa_qe_init_entries_area()
417 area->entries_next = area->entries_start + eighth; in tsa_qe_init_entries_area()
418 area->last_entry = NULL; in tsa_qe_init_entries_area()
421 area->entries_start = tsa->si_ram + (eighth * tdm_id); in tsa_qe_init_entries_area()
422 area->entries_next = area->entries_start + eighth; in tsa_qe_init_entries_area()
423 area->last_entry = NULL; in tsa_qe_init_entries_area()
427 static void tsa_init_entries_area(struct tsa *tsa, struct tsa_entries_area *area, in tsa_init_entries_area() argument
430 if (tsa_is_qe(tsa)) in tsa_init_entries_area()
431 tsa_qe_init_entries_area(tsa, area, tdms, tdm_id, is_rx); in tsa_init_entries_area()
433 tsa_cpm1_init_entries_area(tsa, area, tdms, tdm_id, is_rx); in tsa_init_entries_area()
436 static const char *tsa_cpm1_serial_id2name(struct tsa *tsa, u32 serial_id) in tsa_cpm1_serial_id2name() argument
451 static const char *tsa_qe_serial_id2name(struct tsa *tsa, u32 serial_id) in tsa_qe_serial_id2name() argument
466 static const char *tsa_serial_id2name(struct tsa *tsa, u32 serial_id) in tsa_serial_id2name() argument
468 return tsa_is_qe(tsa) ? in tsa_serial_id2name()
469 tsa_qe_serial_id2name(tsa, serial_id) : in tsa_serial_id2name()
470 tsa_cpm1_serial_id2name(tsa, serial_id); in tsa_serial_id2name()
473 static u32 tsa_cpm1_serial_id2csel(struct tsa *tsa, u32 serial_id) in tsa_cpm1_serial_id2csel() argument
487 static int tsa_cpm1_add_entry(struct tsa *tsa, struct tsa_entries_area *area, in tsa_cpm1_add_entry() argument
496 addr = area->last_entry ? area->last_entry + 4 : area->entries_start; in tsa_cpm1_add_entry()
499 if ((addr + (nb * 4)) > area->entries_next) { in tsa_cpm1_add_entry()
500 dev_err(tsa->dev, "si ram area full\n"); in tsa_cpm1_add_entry()
501 return -ENOSPC; in tsa_cpm1_add_entry()
504 if (area->last_entry) { in tsa_cpm1_add_entry()
506 tsa_clrbits32(area->last_entry, TSA_CPM1_SIRAM_ENTRY_LAST); in tsa_cpm1_add_entry()
511 val = TSA_CPM1_SIRAM_ENTRY_BYTE | tsa_cpm1_serial_id2csel(tsa, serial_id); in tsa_cpm1_add_entry()
518 area->last_entry = addr; in tsa_cpm1_add_entry()
520 val |= TSA_CPM1_SIRAM_ENTRY_CNT(cnt - 1); in tsa_cpm1_add_entry()
524 left -= cnt; in tsa_cpm1_add_entry()
530 static u32 tsa_qe_serial_id2csel(struct tsa *tsa, u32 serial_id) in tsa_qe_serial_id2csel() argument
544 static int tsa_qe_add_entry(struct tsa *tsa, struct tsa_entries_area *area, in tsa_qe_add_entry() argument
553 addr = area->last_entry ? area->last_entry + 2 : area->entries_start; in tsa_qe_add_entry()
556 if ((addr + (nb * 2)) > area->entries_next) { in tsa_qe_add_entry()
557 dev_err(tsa->dev, "si ram area full\n"); in tsa_qe_add_entry()
558 return -ENOSPC; in tsa_qe_add_entry()
561 if (area->last_entry) { in tsa_qe_add_entry()
563 tsa_clrbits16(area->last_entry, TSA_QE_SIRAM_ENTRY_LAST); in tsa_qe_add_entry()
568 val = TSA_QE_SIRAM_ENTRY_BYTE | tsa_qe_serial_id2csel(tsa, serial_id); in tsa_qe_add_entry()
575 area->last_entry = addr; in tsa_qe_add_entry()
577 val |= TSA_QE_SIRAM_ENTRY_CNT(cnt - 1); in tsa_qe_add_entry()
581 left -= cnt; in tsa_qe_add_entry()
587 static int tsa_add_entry(struct tsa *tsa, struct tsa_entries_area *area, in tsa_add_entry() argument
590 return tsa_is_qe(tsa) ? in tsa_add_entry()
591 tsa_qe_add_entry(tsa, area, count, serial_id) : in tsa_add_entry()
592 tsa_cpm1_add_entry(tsa, area, count, serial_id); in tsa_add_entry()
595 static int tsa_of_parse_tdm_route(struct tsa *tsa, struct device_node *tdm_np, in tsa_of_parse_tdm_route() argument
609 route_name = is_rx ? "fsl,rx-ts-routes" : "fsl,tx-ts-routes"; in tsa_of_parse_tdm_route()
613 dev_err(tsa->dev, "%pOF: failed to read %s\n", tdm_np, route_name); in tsa_of_parse_tdm_route()
617 dev_err(tsa->dev, "%pOF: wrong %s format\n", tdm_np, route_name); in tsa_of_parse_tdm_route()
618 return -EINVAL; in tsa_of_parse_tdm_route()
621 tsa_init_entries_area(tsa, &area, tdms, tdm_id, is_rx); in tsa_of_parse_tdm_route()
627 if (serial_id >= ARRAY_SIZE(tsa->serials)) { in tsa_of_parse_tdm_route()
628 dev_err(tsa->dev, "%pOF: invalid serial id (%u)\n", in tsa_of_parse_tdm_route()
630 return -EINVAL; in tsa_of_parse_tdm_route()
633 serial_name = tsa_serial_id2name(tsa, serial_id); in tsa_of_parse_tdm_route()
635 dev_err(tsa->dev, "%pOF: unsupported serial id (%u)\n", in tsa_of_parse_tdm_route()
637 return -EINVAL; in tsa_of_parse_tdm_route()
640 dev_dbg(tsa->dev, "tdm_id=%u, %s ts %u..%u -> %s\n", in tsa_of_parse_tdm_route()
641 tdm_id, route_name, ts, ts + count - 1, serial_name); in tsa_of_parse_tdm_route()
644 ret = tsa_add_entry(tsa, &area, count, serial_id); in tsa_of_parse_tdm_route()
648 serial_info = &tsa->serials[serial_id].info; in tsa_of_parse_tdm_route()
649 tdm = &tsa->tdm[tdm_id]; in tsa_of_parse_tdm_route()
651 serial_info->rx_fs_rate = clk_get_rate(tdm->l1rsync_clk); in tsa_of_parse_tdm_route()
652 serial_info->rx_bit_rate = clk_get_rate(tdm->l1rclk_clk); in tsa_of_parse_tdm_route()
653 serial_info->nb_rx_ts += count; in tsa_of_parse_tdm_route()
655 serial_info->tx_fs_rate = tdm->l1tsync_clk ? in tsa_of_parse_tdm_route()
656 clk_get_rate(tdm->l1tsync_clk) : in tsa_of_parse_tdm_route()
657 clk_get_rate(tdm->l1rsync_clk); in tsa_of_parse_tdm_route()
658 serial_info->tx_bit_rate = tdm->l1tclk_clk ? in tsa_of_parse_tdm_route()
659 clk_get_rate(tdm->l1tclk_clk) : in tsa_of_parse_tdm_route()
660 clk_get_rate(tdm->l1rclk_clk); in tsa_of_parse_tdm_route()
661 serial_info->nb_tx_ts += count; in tsa_of_parse_tdm_route()
667 static inline int tsa_of_parse_tdm_rx_route(struct tsa *tsa, in tsa_of_parse_tdm_rx_route() argument
671 return tsa_of_parse_tdm_route(tsa, tdm_np, tdms, tdm_id, true); in tsa_of_parse_tdm_rx_route()
674 static inline int tsa_of_parse_tdm_tx_route(struct tsa *tsa, in tsa_of_parse_tdm_tx_route() argument
678 return tsa_of_parse_tdm_route(tsa, tdm_np, tdms, tdm_id, false); in tsa_of_parse_tdm_tx_route()
681 static int tsa_of_parse_tdms(struct tsa *tsa, struct device_node *np) in tsa_of_parse_tdms() argument
690 tsa->tdms = 0; in tsa_of_parse_tdms()
691 for (i = 0; i < ARRAY_SIZE(tsa->tdm); i++) in tsa_of_parse_tdms()
692 tsa->tdm[i].is_enable = false; in tsa_of_parse_tdms()
697 dev_err(tsa->dev, "%pOF: failed to read reg\n", tdm_np); in tsa_of_parse_tdms()
703 tsa->tdms |= BIT(TSA_TDMA); in tsa_of_parse_tdms()
706 tsa->tdms |= BIT(TSA_TDMB); in tsa_of_parse_tdms()
709 if (!tsa_is_qe(tsa)) in tsa_of_parse_tdms()
711 tsa->tdms |= BIT(TSA_TDMC); in tsa_of_parse_tdms()
714 if (!tsa_is_qe(tsa)) in tsa_of_parse_tdms()
716 tsa->tdms |= BIT(TSA_TDMD); in tsa_of_parse_tdms()
720 dev_err(tsa->dev, "%pOF: Invalid tdm_id (%u)\n", tdm_np, in tsa_of_parse_tdms()
723 return -EINVAL; in tsa_of_parse_tdms()
730 dev_err(tsa->dev, "%pOF: failed to read reg\n", tdm_np); in tsa_of_parse_tdms()
735 tdm = &tsa->tdm[tdm_id]; in tsa_of_parse_tdms()
736 tdm->simode_tdm = TSA_SIMODE_TDM_SDM_NORM; in tsa_of_parse_tdms()
739 ret = of_property_read_u32(tdm_np, "fsl,rx-frame-sync-delay-bits", in tsa_of_parse_tdms()
741 if (ret && ret != -EINVAL) { in tsa_of_parse_tdms()
742 dev_err(tsa->dev, in tsa_of_parse_tdms()
743 "%pOF: failed to read fsl,rx-frame-sync-delay-bits\n", in tsa_of_parse_tdms()
749 dev_err(tsa->dev, in tsa_of_parse_tdms()
750 "%pOF: Invalid fsl,rx-frame-sync-delay-bits (%u)\n", in tsa_of_parse_tdms()
753 return -EINVAL; in tsa_of_parse_tdms()
755 tdm->simode_tdm |= TSA_SIMODE_TDM_RFSD(val); in tsa_of_parse_tdms()
758 ret = of_property_read_u32(tdm_np, "fsl,tx-frame-sync-delay-bits", in tsa_of_parse_tdms()
760 if (ret && ret != -EINVAL) { in tsa_of_parse_tdms()
761 dev_err(tsa->dev, in tsa_of_parse_tdms()
762 "%pOF: failed to read fsl,tx-frame-sync-delay-bits\n", in tsa_of_parse_tdms()
768 dev_err(tsa->dev, in tsa_of_parse_tdms()
769 "%pOF: Invalid fsl,tx-frame-sync-delay-bits (%u)\n", in tsa_of_parse_tdms()
772 return -EINVAL; in tsa_of_parse_tdms()
774 tdm->simode_tdm |= TSA_SIMODE_TDM_TFSD(val); in tsa_of_parse_tdms()
776 if (of_property_read_bool(tdm_np, "fsl,common-rxtx-pins")) in tsa_of_parse_tdms()
777 tdm->simode_tdm |= TSA_SIMODE_TDM_CRT; in tsa_of_parse_tdms()
779 if (of_property_read_bool(tdm_np, "fsl,clock-falling-edge")) in tsa_of_parse_tdms()
780 tdm->simode_tdm |= TSA_SIMODE_TDM_CE; in tsa_of_parse_tdms()
782 if (of_property_read_bool(tdm_np, "fsl,fsync-rising-edge")) in tsa_of_parse_tdms()
783 tdm->simode_tdm |= TSA_SIMODE_TDM_FE; in tsa_of_parse_tdms()
785 if (tsa_is_qe(tsa) && in tsa_of_parse_tdms()
786 of_property_read_bool(tdm_np, "fsl,fsync-active-low")) in tsa_of_parse_tdms()
787 tdm->simode_tdm |= TSA_QE_SIMODE_TDM_SL; in tsa_of_parse_tdms()
789 if (of_property_read_bool(tdm_np, "fsl,double-speed-clock")) in tsa_of_parse_tdms()
790 tdm->simode_tdm |= TSA_SIMODE_TDM_DSC; in tsa_of_parse_tdms()
792 clk = of_clk_get_by_name(tdm_np, tsa_is_qe(tsa) ? "rsync" : "l1rsync"); in tsa_of_parse_tdms()
804 tdm->l1rsync_clk = clk; in tsa_of_parse_tdms()
806 clk = of_clk_get_by_name(tdm_np, tsa_is_qe(tsa) ? "rclk" : "l1rclk"); in tsa_of_parse_tdms()
818 tdm->l1rclk_clk = clk; in tsa_of_parse_tdms()
820 if (!(tdm->simode_tdm & TSA_SIMODE_TDM_CRT)) { in tsa_of_parse_tdms()
821 clk = of_clk_get_by_name(tdm_np, tsa_is_qe(tsa) ? "tsync" : "l1tsync"); in tsa_of_parse_tdms()
833 tdm->l1tsync_clk = clk; in tsa_of_parse_tdms()
835 clk = of_clk_get_by_name(tdm_np, tsa_is_qe(tsa) ? "tclk" : "l1tclk"); in tsa_of_parse_tdms()
847 tdm->l1tclk_clk = clk; in tsa_of_parse_tdms()
850 if (tsa_is_qe(tsa)) { in tsa_of_parse_tdms()
852 * The starting address for TSA table must be set. in tsa_of_parse_tdms()
855 * We assign entries equally -> 128 Rx/Tx entries per in tsa_of_parse_tdms()
858 tdm->simode_tdm |= TSA_QE_SIMODE_TDM_SAD(4 * tdm_id); in tsa_of_parse_tdms()
861 ret = tsa_of_parse_tdm_rx_route(tsa, tdm_np, tsa->tdms, tdm_id); in tsa_of_parse_tdms()
867 ret = tsa_of_parse_tdm_tx_route(tsa, tdm_np, tsa->tdms, tdm_id); in tsa_of_parse_tdms()
873 tdm->is_enable = true; in tsa_of_parse_tdms()
878 for (i = 0; i < ARRAY_SIZE(tsa->tdm); i++) { in tsa_of_parse_tdms()
879 if (tsa->tdm[i].l1rsync_clk) { in tsa_of_parse_tdms()
880 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); in tsa_of_parse_tdms()
881 clk_put(tsa->tdm[i].l1rsync_clk); in tsa_of_parse_tdms()
883 if (tsa->tdm[i].l1rclk_clk) { in tsa_of_parse_tdms()
884 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); in tsa_of_parse_tdms()
885 clk_put(tsa->tdm[i].l1rclk_clk); in tsa_of_parse_tdms()
887 if (tsa->tdm[i].l1tsync_clk) { in tsa_of_parse_tdms()
888 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); in tsa_of_parse_tdms()
889 clk_put(tsa->tdm[i].l1rsync_clk); in tsa_of_parse_tdms()
891 if (tsa->tdm[i].l1tclk_clk) { in tsa_of_parse_tdms()
892 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); in tsa_of_parse_tdms()
893 clk_put(tsa->tdm[i].l1rclk_clk); in tsa_of_parse_tdms()
899 static void tsa_init_si_ram(struct tsa *tsa) in tsa_init_si_ram() argument
904 if (tsa_is_qe(tsa)) { in tsa_init_si_ram()
905 for (i = 0; i < tsa->si_ram_sz; i += 2) in tsa_init_si_ram()
906 tsa_write16(tsa->si_ram + i, TSA_QE_SIRAM_ENTRY_LAST); in tsa_init_si_ram()
908 for (i = 0; i < tsa->si_ram_sz; i += 4) in tsa_init_si_ram()
909 tsa_write32(tsa->si_ram + i, TSA_CPM1_SIRAM_ENTRY_LAST); in tsa_init_si_ram()
913 static int tsa_cpm1_setup(struct tsa *tsa) in tsa_cpm1_setup() argument
919 if (tsa->tdm[0].is_enable) in tsa_cpm1_setup()
920 val |= TSA_CPM1_SIMODE_TDMA(tsa->tdm[0].simode_tdm); in tsa_cpm1_setup()
921 if (tsa->tdm[1].is_enable) in tsa_cpm1_setup()
922 val |= TSA_CPM1_SIMODE_TDMB(tsa->tdm[1].simode_tdm); in tsa_cpm1_setup()
924 tsa_clrsetbits32(tsa->si_regs + TSA_CPM1_SIMODE, in tsa_cpm1_setup()
930 val = (tsa->tdms == BIT(TSA_TDMA)) ? in tsa_cpm1_setup()
932 if (tsa->tdms & BIT(TSA_TDMA)) in tsa_cpm1_setup()
934 if (tsa->tdms & BIT(TSA_TDMB)) in tsa_cpm1_setup()
936 tsa_write8(tsa->si_regs + TSA_CPM1_SIGMR, val); in tsa_cpm1_setup()
941 static int tsa_qe_setup(struct tsa *tsa) in tsa_qe_setup() argument
947 for (i = 0; i < ARRAY_SIZE(tsa->tdm); i++) { in tsa_qe_setup()
948 if (!tsa->tdm[i].is_enable) in tsa_qe_setup()
969 return -EINVAL; in tsa_qe_setup()
973 tsa_write16(tsa->si_regs + sixmr, tsa->tdm[i].simode_tdm); in tsa_qe_setup()
977 tsa_write8(tsa->si_regs + TSA_QE_SIGLMRH, siglmrh); in tsa_qe_setup()
982 static int tsa_setup(struct tsa *tsa) in tsa_setup() argument
984 return tsa_is_qe(tsa) ? tsa_qe_setup(tsa) : tsa_cpm1_setup(tsa); in tsa_setup()
989 struct device_node *np = pdev->dev.of_node; in tsa_probe()
991 struct tsa *tsa; in tsa_probe() local
995 tsa = devm_kzalloc(&pdev->dev, sizeof(*tsa), GFP_KERNEL); in tsa_probe()
996 if (!tsa) in tsa_probe()
997 return -ENOMEM; in tsa_probe()
999 tsa->dev = &pdev->dev; in tsa_probe()
1000 tsa->version = (enum tsa_version)(uintptr_t)of_device_get_match_data(&pdev->dev); in tsa_probe()
1001 switch (tsa->version) { in tsa_probe()
1003 dev_info(tsa->dev, "CPM1 version\n"); in tsa_probe()
1006 dev_info(tsa->dev, "QE version\n"); in tsa_probe()
1009 dev_err(tsa->dev, "Unknown version (%d)\n", tsa->version); in tsa_probe()
1010 return -EINVAL; in tsa_probe()
1013 for (i = 0; i < ARRAY_SIZE(tsa->serials); i++) in tsa_probe()
1014 tsa->serials[i].id = i; in tsa_probe()
1016 spin_lock_init(&tsa->lock); in tsa_probe()
1018 tsa->si_regs = devm_platform_ioremap_resource_byname(pdev, "si_regs"); in tsa_probe()
1019 if (IS_ERR(tsa->si_regs)) in tsa_probe()
1020 return PTR_ERR(tsa->si_regs); in tsa_probe()
1024 dev_err(tsa->dev, "si_ram resource missing\n"); in tsa_probe()
1025 return -EINVAL; in tsa_probe()
1027 tsa->si_ram_sz = resource_size(res); in tsa_probe()
1028 tsa->si_ram = devm_ioremap_resource(&pdev->dev, res); in tsa_probe()
1029 if (IS_ERR(tsa->si_ram)) in tsa_probe()
1030 return PTR_ERR(tsa->si_ram); in tsa_probe()
1032 tsa_init_si_ram(tsa); in tsa_probe()
1034 ret = tsa_of_parse_tdms(tsa, np); in tsa_probe()
1038 ret = tsa_setup(tsa); in tsa_probe()
1042 platform_set_drvdata(pdev, tsa); in tsa_probe()
1049 struct tsa *tsa = platform_get_drvdata(pdev); in tsa_remove() local
1052 for (i = 0; i < ARRAY_SIZE(tsa->tdm); i++) { in tsa_remove()
1053 if (tsa->tdm[i].l1rsync_clk) { in tsa_remove()
1054 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); in tsa_remove()
1055 clk_put(tsa->tdm[i].l1rsync_clk); in tsa_remove()
1057 if (tsa->tdm[i].l1rclk_clk) { in tsa_remove()
1058 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); in tsa_remove()
1059 clk_put(tsa->tdm[i].l1rclk_clk); in tsa_remove()
1061 if (tsa->tdm[i].l1tsync_clk) { in tsa_remove()
1062 clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); in tsa_remove()
1063 clk_put(tsa->tdm[i].l1rsync_clk); in tsa_remove()
1065 if (tsa->tdm[i].l1tclk_clk) { in tsa_remove()
1066 clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); in tsa_remove()
1067 clk_put(tsa->tdm[i].l1rclk_clk); in tsa_remove()
1074 { .compatible = "fsl,cpm1-tsa", .data = (void *)TSA_CPM1 },
1077 { .compatible = "fsl,qe-tsa", .data = (void *)TSA_QE },
1085 .name = "fsl-tsa",
1099 struct tsa *tsa; in tsa_serial_get_byphandle() local
1108 return ERR_PTR(-EINVAL); in tsa_serial_get_byphandle()
1114 return ERR_PTR(-ENODEV); in tsa_serial_get_byphandle()
1116 tsa = platform_get_drvdata(pdev); in tsa_serial_get_byphandle()
1117 if (!tsa) { in tsa_serial_get_byphandle()
1119 return ERR_PTR(-EPROBE_DEFER); in tsa_serial_get_byphandle()
1124 return ERR_PTR(-EINVAL); in tsa_serial_get_byphandle()
1127 if (out_args.args[0] >= ARRAY_SIZE(tsa->serials)) { in tsa_serial_get_byphandle()
1129 return ERR_PTR(-EINVAL); in tsa_serial_get_byphandle()
1132 tsa_serial = &tsa->serials[out_args.args[0]]; in tsa_serial_get_byphandle()
1139 if (WARN_ON(tsa_serial->id != out_args.args[0])) { in tsa_serial_get_byphandle()
1141 return ERR_PTR(-EINVAL); in tsa_serial_get_byphandle()
1150 struct tsa *tsa = tsa_serial_get_tsa(tsa_serial); in tsa_serial_put() local
1152 put_device(tsa->dev); in tsa_serial_put()
1172 return ERR_PTR(-ENOMEM); in devm_tsa_serial_get_byphandle()
1187 MODULE_DESCRIPTION("CPM/QE TSA driver");