diff options
Diffstat (limited to 'drivers')
25 files changed, 1518 insertions, 313 deletions
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 2394e9753ef5..725c46162bbd 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c | |||
@@ -588,12 +588,6 @@ static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = { | |||
588 | .show_cpu_target = mvebu_sdram_debug_show_orion, | 588 | .show_cpu_target = mvebu_sdram_debug_show_orion, |
589 | }; | 589 | }; |
590 | 590 | ||
591 | /* | ||
592 | * The driver doesn't yet have a DT binding because the details of | ||
593 | * this DT binding still need to be sorted out. However, as a | ||
594 | * preparation, we already use of_device_id to match a SoC description | ||
595 | * string against the SoC specific details of this driver. | ||
596 | */ | ||
597 | static const struct of_device_id of_mvebu_mbus_ids[] = { | 591 | static const struct of_device_id of_mvebu_mbus_ids[] = { |
598 | { .compatible = "marvell,armada370-mbus", | 592 | { .compatible = "marvell,armada370-mbus", |
599 | .data = &armada_370_xp_mbus_data, }, | 593 | .data = &armada_370_xp_mbus_data, }, |
@@ -734,11 +728,11 @@ int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base, | |||
734 | { | 728 | { |
735 | const struct of_device_id *of_id; | 729 | const struct of_device_id *of_id; |
736 | 730 | ||
737 | for (of_id = of_mvebu_mbus_ids; of_id->compatible; of_id++) | 731 | for (of_id = of_mvebu_mbus_ids; of_id->compatible[0]; of_id++) |
738 | if (!strcmp(of_id->compatible, soc)) | 732 | if (!strcmp(of_id->compatible, soc)) |
739 | break; | 733 | break; |
740 | 734 | ||
741 | if (!of_id->compatible) { | 735 | if (!of_id->compatible[0]) { |
742 | pr_err("could not find a matching SoC family\n"); | 736 | pr_err("could not find a matching SoC family\n"); |
743 | return -ENODEV; | 737 | return -ENODEV; |
744 | } | 738 | } |
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index f5e4c21b301f..8cbfcf88fae3 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c | |||
@@ -119,6 +119,7 @@ static const struct clk_ops icst_ops = { | |||
119 | 119 | ||
120 | struct clk *icst_clk_register(struct device *dev, | 120 | struct clk *icst_clk_register(struct device *dev, |
121 | const struct clk_icst_desc *desc, | 121 | const struct clk_icst_desc *desc, |
122 | const char *name, | ||
122 | void __iomem *base) | 123 | void __iomem *base) |
123 | { | 124 | { |
124 | struct clk *clk; | 125 | struct clk *clk; |
@@ -130,7 +131,7 @@ struct clk *icst_clk_register(struct device *dev, | |||
130 | pr_err("could not allocate ICST clock!\n"); | 131 | pr_err("could not allocate ICST clock!\n"); |
131 | return ERR_PTR(-ENOMEM); | 132 | return ERR_PTR(-ENOMEM); |
132 | } | 133 | } |
133 | init.name = "icst"; | 134 | init.name = name; |
134 | init.ops = &icst_ops; | 135 | init.ops = &icst_ops; |
135 | init.flags = CLK_IS_ROOT; | 136 | init.flags = CLK_IS_ROOT; |
136 | init.parent_names = NULL; | 137 | init.parent_names = NULL; |
diff --git a/drivers/clk/versatile/clk-icst.h b/drivers/clk/versatile/clk-icst.h index dad51b6ffd00..be99dd0da785 100644 --- a/drivers/clk/versatile/clk-icst.h +++ b/drivers/clk/versatile/clk-icst.h | |||
@@ -15,4 +15,5 @@ struct clk_icst_desc { | |||
15 | 15 | ||
16 | struct clk *icst_clk_register(struct device *dev, | 16 | struct clk *icst_clk_register(struct device *dev, |
17 | const struct clk_icst_desc *desc, | 17 | const struct clk_icst_desc *desc, |
18 | const char *name, | ||
18 | void __iomem *base); | 19 | void __iomem *base); |
diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c index 369139af2a3b..844f8d711a12 100644 --- a/drivers/clk/versatile/clk-impd1.c +++ b/drivers/clk/versatile/clk-impd1.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Clock driver for the ARM Integrator/IM-PD1 board | 2 | * Clock driver for the ARM Integrator/IM-PD1 board |
3 | * Copyright (C) 2012 Linus Walleij | 3 | * Copyright (C) 2012-2013 Linus Walleij |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
@@ -18,20 +18,28 @@ | |||
18 | #include "clk-icst.h" | 18 | #include "clk-icst.h" |
19 | 19 | ||
20 | struct impd1_clk { | 20 | struct impd1_clk { |
21 | struct clk *vcoclk; | 21 | char *vco1name; |
22 | struct clk *vco1clk; | ||
23 | char *vco2name; | ||
24 | struct clk *vco2clk; | ||
25 | struct clk *mmciclk; | ||
26 | char *uartname; | ||
22 | struct clk *uartclk; | 27 | struct clk *uartclk; |
23 | struct clk_lookup *clks[3]; | 28 | char *spiname; |
29 | struct clk *spiclk; | ||
30 | char *scname; | ||
31 | struct clk *scclk; | ||
32 | struct clk_lookup *clks[6]; | ||
24 | }; | 33 | }; |
25 | 34 | ||
35 | /* One entry for each connected IM-PD1 LM */ | ||
26 | static struct impd1_clk impd1_clks[4]; | 36 | static struct impd1_clk impd1_clks[4]; |
27 | 37 | ||
28 | /* | 38 | /* |
29 | * There are two VCO's on the IM-PD1 but only one is used by the | 39 | * There are two VCO's on the IM-PD1 |
30 | * kernel, that is why we are only implementing the control of | ||
31 | * IMPD1_OSC1 here. | ||
32 | */ | 40 | */ |
33 | 41 | ||
34 | static const struct icst_params impd1_vco_params = { | 42 | static const struct icst_params impd1_vco1_params = { |
35 | .ref = 24000000, /* 24 MHz */ | 43 | .ref = 24000000, /* 24 MHz */ |
36 | .vco_max = ICST525_VCO_MAX_3V, | 44 | .vco_max = ICST525_VCO_MAX_3V, |
37 | .vco_min = ICST525_VCO_MIN, | 45 | .vco_min = ICST525_VCO_MIN, |
@@ -44,11 +52,29 @@ static const struct icst_params impd1_vco_params = { | |||
44 | }; | 52 | }; |
45 | 53 | ||
46 | static const struct clk_icst_desc impd1_icst1_desc = { | 54 | static const struct clk_icst_desc impd1_icst1_desc = { |
47 | .params = &impd1_vco_params, | 55 | .params = &impd1_vco1_params, |
48 | .vco_offset = IMPD1_OSC1, | 56 | .vco_offset = IMPD1_OSC1, |
49 | .lock_offset = IMPD1_LOCK, | 57 | .lock_offset = IMPD1_LOCK, |
50 | }; | 58 | }; |
51 | 59 | ||
60 | static const struct icst_params impd1_vco2_params = { | ||
61 | .ref = 24000000, /* 24 MHz */ | ||
62 | .vco_max = ICST525_VCO_MAX_3V, | ||
63 | .vco_min = ICST525_VCO_MIN, | ||
64 | .vd_min = 12, | ||
65 | .vd_max = 519, | ||
66 | .rd_min = 3, | ||
67 | .rd_max = 120, | ||
68 | .s2div = icst525_s2div, | ||
69 | .idx2s = icst525_idx2s, | ||
70 | }; | ||
71 | |||
72 | static const struct clk_icst_desc impd1_icst2_desc = { | ||
73 | .params = &impd1_vco2_params, | ||
74 | .vco_offset = IMPD1_OSC2, | ||
75 | .lock_offset = IMPD1_LOCK, | ||
76 | }; | ||
77 | |||
52 | /** | 78 | /** |
53 | * integrator_impd1_clk_init() - set up the integrator clock tree | 79 | * integrator_impd1_clk_init() - set up the integrator clock tree |
54 | * @base: base address of the logic module (LM) | 80 | * @base: base address of the logic module (LM) |
@@ -66,16 +92,39 @@ void integrator_impd1_clk_init(void __iomem *base, unsigned int id) | |||
66 | } | 92 | } |
67 | imc = &impd1_clks[id]; | 93 | imc = &impd1_clks[id]; |
68 | 94 | ||
69 | clk = icst_clk_register(NULL, &impd1_icst1_desc, base); | 95 | imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id); |
70 | imc->vcoclk = clk; | 96 | clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, base); |
97 | imc->vco1clk = clk; | ||
71 | imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); | 98 | imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); |
72 | 99 | ||
73 | /* UART reference clock */ | 100 | /* VCO2 is also called "CLK2" */ |
74 | clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT, | 101 | imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id); |
75 | 14745600); | 102 | clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, base); |
103 | imc->vco2clk = clk; | ||
104 | |||
105 | /* MMCI uses CLK2 right off */ | ||
106 | imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:00700", id); | ||
107 | |||
108 | /* UART reference clock divides CLK2 by a fixed factor 4 */ | ||
109 | imc->uartname = kasprintf(GFP_KERNEL, "lm%x-uartclk", id); | ||
110 | clk = clk_register_fixed_factor(NULL, imc->uartname, imc->vco2name, | ||
111 | CLK_IGNORE_UNUSED, 1, 4); | ||
76 | imc->uartclk = clk; | 112 | imc->uartclk = clk; |
77 | imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:00100", id); | 113 | imc->clks[2] = clkdev_alloc(clk, NULL, "lm%x:00100", id); |
78 | imc->clks[2] = clkdev_alloc(clk, NULL, "lm%x:00200", id); | 114 | imc->clks[3] = clkdev_alloc(clk, NULL, "lm%x:00200", id); |
115 | |||
116 | /* SPI PL022 clock divides CLK2 by a fixed factor 64 */ | ||
117 | imc->spiname = kasprintf(GFP_KERNEL, "lm%x-spiclk", id); | ||
118 | clk = clk_register_fixed_factor(NULL, imc->spiname, imc->vco2name, | ||
119 | CLK_IGNORE_UNUSED, 1, 64); | ||
120 | imc->clks[4] = clkdev_alloc(clk, NULL, "lm%x:00300", id); | ||
121 | |||
122 | /* Smart Card clock divides CLK2 by a fixed factor 4 */ | ||
123 | imc->scname = kasprintf(GFP_KERNEL, "lm%x-scclk", id); | ||
124 | clk = clk_register_fixed_factor(NULL, imc->scname, imc->vco2name, | ||
125 | CLK_IGNORE_UNUSED, 1, 4); | ||
126 | imc->scclk = clk; | ||
127 | imc->clks[5] = clkdev_alloc(clk, NULL, "lm%x:00600", id); | ||
79 | 128 | ||
80 | for (i = 0; i < ARRAY_SIZE(imc->clks); i++) | 129 | for (i = 0; i < ARRAY_SIZE(imc->clks); i++) |
81 | clkdev_add(imc->clks[i]); | 130 | clkdev_add(imc->clks[i]); |
@@ -92,6 +141,13 @@ void integrator_impd1_clk_exit(unsigned int id) | |||
92 | 141 | ||
93 | for (i = 0; i < ARRAY_SIZE(imc->clks); i++) | 142 | for (i = 0; i < ARRAY_SIZE(imc->clks); i++) |
94 | clkdev_drop(imc->clks[i]); | 143 | clkdev_drop(imc->clks[i]); |
144 | clk_unregister(imc->spiclk); | ||
95 | clk_unregister(imc->uartclk); | 145 | clk_unregister(imc->uartclk); |
96 | clk_unregister(imc->vcoclk); | 146 | clk_unregister(imc->vco2clk); |
147 | clk_unregister(imc->vco1clk); | ||
148 | kfree(imc->scname); | ||
149 | kfree(imc->spiname); | ||
150 | kfree(imc->uartname); | ||
151 | kfree(imc->vco2name); | ||
152 | kfree(imc->vco1name); | ||
97 | } | 153 | } |
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c index 08593b4ee2c9..bda8967e09c2 100644 --- a/drivers/clk/versatile/clk-integrator.c +++ b/drivers/clk/versatile/clk-integrator.c | |||
@@ -78,7 +78,7 @@ void __init integrator_clk_init(bool is_cp) | |||
78 | clk_register_clkdev(clk, NULL, "sp804"); | 78 | clk_register_clkdev(clk, NULL, "sp804"); |
79 | 79 | ||
80 | /* ICST VCO clock used on the Integrator/CP CLCD */ | 80 | /* ICST VCO clock used on the Integrator/CP CLCD */ |
81 | clk = icst_clk_register(NULL, &cp_icst_desc, | 81 | clk = icst_clk_register(NULL, &cp_icst_desc, "icst", |
82 | __io_address(INTEGRATOR_HDR_BASE)); | 82 | __io_address(INTEGRATOR_HDR_BASE)); |
83 | clk_register_clkdev(clk, NULL, "clcd"); | 83 | clk_register_clkdev(clk, NULL, "clcd"); |
84 | } | 84 | } |
diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c index cda07e70a408..747e7b31117c 100644 --- a/drivers/clk/versatile/clk-realview.c +++ b/drivers/clk/versatile/clk-realview.c | |||
@@ -84,9 +84,11 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) | |||
84 | 84 | ||
85 | /* ICST VCO clock */ | 85 | /* ICST VCO clock */ |
86 | if (is_pb1176) | 86 | if (is_pb1176) |
87 | clk = icst_clk_register(NULL, &realview_osc0_desc, sysbase); | 87 | clk = icst_clk_register(NULL, &realview_osc0_desc, |
88 | "osc0", sysbase); | ||
88 | else | 89 | else |
89 | clk = icst_clk_register(NULL, &realview_osc4_desc, sysbase); | 90 | clk = icst_clk_register(NULL, &realview_osc4_desc, |
91 | "osc4", sysbase); | ||
90 | 92 | ||
91 | clk_register_clkdev(clk, NULL, "dev:clcd"); | 93 | clk_register_clkdev(clk, NULL, "dev:clcd"); |
92 | clk_register_clkdev(clk, NULL, "issp:clcd"); | 94 | clk_register_clkdev(clk, NULL, "issp:clcd"); |
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c index c1efd910d97b..d7c9e317423c 100644 --- a/drivers/crypto/atmel-aes.c +++ b/drivers/crypto/atmel-aes.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
31 | #include <linux/scatterlist.h> | 31 | #include <linux/scatterlist.h> |
32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
33 | #include <linux/of_device.h> | ||
33 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
34 | #include <linux/crypto.h> | 35 | #include <linux/crypto.h> |
35 | #include <linux/cryptohash.h> | 36 | #include <linux/cryptohash.h> |
@@ -39,6 +40,7 @@ | |||
39 | #include <crypto/hash.h> | 40 | #include <crypto/hash.h> |
40 | #include <crypto/internal/hash.h> | 41 | #include <crypto/internal/hash.h> |
41 | #include <linux/platform_data/crypto-atmel.h> | 42 | #include <linux/platform_data/crypto-atmel.h> |
43 | #include <dt-bindings/dma/at91.h> | ||
42 | #include "atmel-aes-regs.h" | 44 | #include "atmel-aes-regs.h" |
43 | 45 | ||
44 | #define CFB8_BLOCK_SIZE 1 | 46 | #define CFB8_BLOCK_SIZE 1 |
@@ -747,59 +749,50 @@ static int atmel_aes_dma_init(struct atmel_aes_dev *dd, | |||
747 | struct crypto_platform_data *pdata) | 749 | struct crypto_platform_data *pdata) |
748 | { | 750 | { |
749 | int err = -ENOMEM; | 751 | int err = -ENOMEM; |
750 | dma_cap_mask_t mask_in, mask_out; | 752 | dma_cap_mask_t mask; |
753 | |||
754 | dma_cap_zero(mask); | ||
755 | dma_cap_set(DMA_SLAVE, mask); | ||
756 | |||
757 | /* Try to grab 2 DMA channels */ | ||
758 | dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask, | ||
759 | atmel_aes_filter, &pdata->dma_slave->rxdata, dd->dev, "tx"); | ||
760 | if (!dd->dma_lch_in.chan) | ||
761 | goto err_dma_in; | ||
762 | |||
763 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
764 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
765 | AES_IDATAR(0); | ||
766 | dd->dma_lch_in.dma_conf.src_maxburst = dd->caps.max_burst_size; | ||
767 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
768 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
769 | dd->dma_lch_in.dma_conf.dst_maxburst = dd->caps.max_burst_size; | ||
770 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
771 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
772 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
773 | |||
774 | dd->dma_lch_out.chan = dma_request_slave_channel_compat(mask, | ||
775 | atmel_aes_filter, &pdata->dma_slave->txdata, dd->dev, "rx"); | ||
776 | if (!dd->dma_lch_out.chan) | ||
777 | goto err_dma_out; | ||
778 | |||
779 | dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; | ||
780 | dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + | ||
781 | AES_ODATAR(0); | ||
782 | dd->dma_lch_out.dma_conf.src_maxburst = dd->caps.max_burst_size; | ||
783 | dd->dma_lch_out.dma_conf.src_addr_width = | ||
784 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
785 | dd->dma_lch_out.dma_conf.dst_maxburst = dd->caps.max_burst_size; | ||
786 | dd->dma_lch_out.dma_conf.dst_addr_width = | ||
787 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
788 | dd->dma_lch_out.dma_conf.device_fc = false; | ||
751 | 789 | ||
752 | if (pdata && pdata->dma_slave->txdata.dma_dev && | 790 | return 0; |
753 | pdata->dma_slave->rxdata.dma_dev) { | ||
754 | |||
755 | /* Try to grab 2 DMA channels */ | ||
756 | dma_cap_zero(mask_in); | ||
757 | dma_cap_set(DMA_SLAVE, mask_in); | ||
758 | |||
759 | dd->dma_lch_in.chan = dma_request_channel(mask_in, | ||
760 | atmel_aes_filter, &pdata->dma_slave->rxdata); | ||
761 | |||
762 | if (!dd->dma_lch_in.chan) | ||
763 | goto err_dma_in; | ||
764 | |||
765 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
766 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
767 | AES_IDATAR(0); | ||
768 | dd->dma_lch_in.dma_conf.src_maxburst = dd->caps.max_burst_size; | ||
769 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
770 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
771 | dd->dma_lch_in.dma_conf.dst_maxburst = dd->caps.max_burst_size; | ||
772 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
773 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
774 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
775 | |||
776 | dma_cap_zero(mask_out); | ||
777 | dma_cap_set(DMA_SLAVE, mask_out); | ||
778 | dd->dma_lch_out.chan = dma_request_channel(mask_out, | ||
779 | atmel_aes_filter, &pdata->dma_slave->txdata); | ||
780 | |||
781 | if (!dd->dma_lch_out.chan) | ||
782 | goto err_dma_out; | ||
783 | |||
784 | dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; | ||
785 | dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + | ||
786 | AES_ODATAR(0); | ||
787 | dd->dma_lch_out.dma_conf.src_maxburst = dd->caps.max_burst_size; | ||
788 | dd->dma_lch_out.dma_conf.src_addr_width = | ||
789 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
790 | dd->dma_lch_out.dma_conf.dst_maxburst = dd->caps.max_burst_size; | ||
791 | dd->dma_lch_out.dma_conf.dst_addr_width = | ||
792 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
793 | dd->dma_lch_out.dma_conf.device_fc = false; | ||
794 | |||
795 | return 0; | ||
796 | } else { | ||
797 | return -ENODEV; | ||
798 | } | ||
799 | 791 | ||
800 | err_dma_out: | 792 | err_dma_out: |
801 | dma_release_channel(dd->dma_lch_in.chan); | 793 | dma_release_channel(dd->dma_lch_in.chan); |
802 | err_dma_in: | 794 | err_dma_in: |
795 | dev_warn(dd->dev, "no DMA channel available\n"); | ||
803 | return err; | 796 | return err; |
804 | } | 797 | } |
805 | 798 | ||
@@ -1261,6 +1254,47 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd) | |||
1261 | } | 1254 | } |
1262 | } | 1255 | } |
1263 | 1256 | ||
1257 | #if defined(CONFIG_OF) | ||
1258 | static const struct of_device_id atmel_aes_dt_ids[] = { | ||
1259 | { .compatible = "atmel,at91sam9g46-aes" }, | ||
1260 | { /* sentinel */ } | ||
1261 | }; | ||
1262 | MODULE_DEVICE_TABLE(of, atmel_aes_dt_ids); | ||
1263 | |||
1264 | static struct crypto_platform_data *atmel_aes_of_init(struct platform_device *pdev) | ||
1265 | { | ||
1266 | struct device_node *np = pdev->dev.of_node; | ||
1267 | struct crypto_platform_data *pdata; | ||
1268 | |||
1269 | if (!np) { | ||
1270 | dev_err(&pdev->dev, "device node not found\n"); | ||
1271 | return ERR_PTR(-EINVAL); | ||
1272 | } | ||
1273 | |||
1274 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
1275 | if (!pdata) { | ||
1276 | dev_err(&pdev->dev, "could not allocate memory for pdata\n"); | ||
1277 | return ERR_PTR(-ENOMEM); | ||
1278 | } | ||
1279 | |||
1280 | pdata->dma_slave = devm_kzalloc(&pdev->dev, | ||
1281 | sizeof(*(pdata->dma_slave)), | ||
1282 | GFP_KERNEL); | ||
1283 | if (!pdata->dma_slave) { | ||
1284 | dev_err(&pdev->dev, "could not allocate memory for dma_slave\n"); | ||
1285 | devm_kfree(&pdev->dev, pdata); | ||
1286 | return ERR_PTR(-ENOMEM); | ||
1287 | } | ||
1288 | |||
1289 | return pdata; | ||
1290 | } | ||
1291 | #else | ||
1292 | static inline struct crypto_platform_data *atmel_aes_of_init(struct platform_device *pdev) | ||
1293 | { | ||
1294 | return ERR_PTR(-EINVAL); | ||
1295 | } | ||
1296 | #endif | ||
1297 | |||
1264 | static int atmel_aes_probe(struct platform_device *pdev) | 1298 | static int atmel_aes_probe(struct platform_device *pdev) |
1265 | { | 1299 | { |
1266 | struct atmel_aes_dev *aes_dd; | 1300 | struct atmel_aes_dev *aes_dd; |
@@ -1272,6 +1306,14 @@ static int atmel_aes_probe(struct platform_device *pdev) | |||
1272 | 1306 | ||
1273 | pdata = pdev->dev.platform_data; | 1307 | pdata = pdev->dev.platform_data; |
1274 | if (!pdata) { | 1308 | if (!pdata) { |
1309 | pdata = atmel_aes_of_init(pdev); | ||
1310 | if (IS_ERR(pdata)) { | ||
1311 | err = PTR_ERR(pdata); | ||
1312 | goto aes_dd_err; | ||
1313 | } | ||
1314 | } | ||
1315 | |||
1316 | if (!pdata->dma_slave) { | ||
1275 | err = -ENXIO; | 1317 | err = -ENXIO; |
1276 | goto aes_dd_err; | 1318 | goto aes_dd_err; |
1277 | } | 1319 | } |
@@ -1358,7 +1400,9 @@ static int atmel_aes_probe(struct platform_device *pdev) | |||
1358 | if (err) | 1400 | if (err) |
1359 | goto err_algs; | 1401 | goto err_algs; |
1360 | 1402 | ||
1361 | dev_info(dev, "Atmel AES\n"); | 1403 | dev_info(dev, "Atmel AES - Using %s, %s for DMA transfers\n", |
1404 | dma_chan_name(aes_dd->dma_lch_in.chan), | ||
1405 | dma_chan_name(aes_dd->dma_lch_out.chan)); | ||
1362 | 1406 | ||
1363 | return 0; | 1407 | return 0; |
1364 | 1408 | ||
@@ -1424,6 +1468,7 @@ static struct platform_driver atmel_aes_driver = { | |||
1424 | .driver = { | 1468 | .driver = { |
1425 | .name = "atmel_aes", | 1469 | .name = "atmel_aes", |
1426 | .owner = THIS_MODULE, | 1470 | .owner = THIS_MODULE, |
1471 | .of_match_table = of_match_ptr(atmel_aes_dt_ids), | ||
1427 | }, | 1472 | }, |
1428 | }; | 1473 | }; |
1429 | 1474 | ||
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index eaed8bf183bc..0618be06b9fb 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
31 | #include <linux/scatterlist.h> | 31 | #include <linux/scatterlist.h> |
32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
33 | #include <linux/of_device.h> | ||
33 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
34 | #include <linux/crypto.h> | 35 | #include <linux/crypto.h> |
35 | #include <linux/cryptohash.h> | 36 | #include <linux/cryptohash.h> |
@@ -1263,32 +1264,29 @@ static int atmel_sha_dma_init(struct atmel_sha_dev *dd, | |||
1263 | int err = -ENOMEM; | 1264 | int err = -ENOMEM; |
1264 | dma_cap_mask_t mask_in; | 1265 | dma_cap_mask_t mask_in; |
1265 | 1266 | ||
1266 | if (pdata && pdata->dma_slave->rxdata.dma_dev) { | 1267 | /* Try to grab DMA channel */ |
1267 | /* Try to grab DMA channel */ | 1268 | dma_cap_zero(mask_in); |
1268 | dma_cap_zero(mask_in); | 1269 | dma_cap_set(DMA_SLAVE, mask_in); |
1269 | dma_cap_set(DMA_SLAVE, mask_in); | ||
1270 | 1270 | ||
1271 | dd->dma_lch_in.chan = dma_request_channel(mask_in, | 1271 | dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask_in, |
1272 | atmel_sha_filter, &pdata->dma_slave->rxdata); | 1272 | atmel_sha_filter, &pdata->dma_slave->rxdata, dd->dev, "tx"); |
1273 | 1273 | if (!dd->dma_lch_in.chan) { | |
1274 | if (!dd->dma_lch_in.chan) | 1274 | dev_warn(dd->dev, "no DMA channel available\n"); |
1275 | return err; | 1275 | return err; |
1276 | |||
1277 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
1278 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
1279 | SHA_REG_DIN(0); | ||
1280 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
1281 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
1282 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
1283 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
1284 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
1285 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
1286 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
1287 | |||
1288 | return 0; | ||
1289 | } | 1276 | } |
1290 | 1277 | ||
1291 | return -ENODEV; | 1278 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; |
1279 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
1280 | SHA_REG_DIN(0); | ||
1281 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
1282 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
1283 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
1284 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
1285 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
1286 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
1287 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
1288 | |||
1289 | return 0; | ||
1292 | } | 1290 | } |
1293 | 1291 | ||
1294 | static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd) | 1292 | static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd) |
@@ -1326,6 +1324,48 @@ static void atmel_sha_get_cap(struct atmel_sha_dev *dd) | |||
1326 | } | 1324 | } |
1327 | } | 1325 | } |
1328 | 1326 | ||
1327 | #if defined(CONFIG_OF) | ||
1328 | static const struct of_device_id atmel_sha_dt_ids[] = { | ||
1329 | { .compatible = "atmel,at91sam9g46-sha" }, | ||
1330 | { /* sentinel */ } | ||
1331 | }; | ||
1332 | |||
1333 | MODULE_DEVICE_TABLE(of, atmel_sha_dt_ids); | ||
1334 | |||
1335 | static struct crypto_platform_data *atmel_sha_of_init(struct platform_device *pdev) | ||
1336 | { | ||
1337 | struct device_node *np = pdev->dev.of_node; | ||
1338 | struct crypto_platform_data *pdata; | ||
1339 | |||
1340 | if (!np) { | ||
1341 | dev_err(&pdev->dev, "device node not found\n"); | ||
1342 | return ERR_PTR(-EINVAL); | ||
1343 | } | ||
1344 | |||
1345 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
1346 | if (!pdata) { | ||
1347 | dev_err(&pdev->dev, "could not allocate memory for pdata\n"); | ||
1348 | return ERR_PTR(-ENOMEM); | ||
1349 | } | ||
1350 | |||
1351 | pdata->dma_slave = devm_kzalloc(&pdev->dev, | ||
1352 | sizeof(*(pdata->dma_slave)), | ||
1353 | GFP_KERNEL); | ||
1354 | if (!pdata->dma_slave) { | ||
1355 | dev_err(&pdev->dev, "could not allocate memory for dma_slave\n"); | ||
1356 | devm_kfree(&pdev->dev, pdata); | ||
1357 | return ERR_PTR(-ENOMEM); | ||
1358 | } | ||
1359 | |||
1360 | return pdata; | ||
1361 | } | ||
1362 | #else /* CONFIG_OF */ | ||
1363 | static inline struct crypto_platform_data *atmel_sha_of_init(struct platform_device *dev) | ||
1364 | { | ||
1365 | return ERR_PTR(-EINVAL); | ||
1366 | } | ||
1367 | #endif | ||
1368 | |||
1329 | static int atmel_sha_probe(struct platform_device *pdev) | 1369 | static int atmel_sha_probe(struct platform_device *pdev) |
1330 | { | 1370 | { |
1331 | struct atmel_sha_dev *sha_dd; | 1371 | struct atmel_sha_dev *sha_dd; |
@@ -1402,13 +1442,23 @@ static int atmel_sha_probe(struct platform_device *pdev) | |||
1402 | if (sha_dd->caps.has_dma) { | 1442 | if (sha_dd->caps.has_dma) { |
1403 | pdata = pdev->dev.platform_data; | 1443 | pdata = pdev->dev.platform_data; |
1404 | if (!pdata) { | 1444 | if (!pdata) { |
1405 | dev_err(&pdev->dev, "platform data not available\n"); | 1445 | pdata = atmel_sha_of_init(pdev); |
1446 | if (IS_ERR(pdata)) { | ||
1447 | dev_err(&pdev->dev, "platform data not available\n"); | ||
1448 | err = PTR_ERR(pdata); | ||
1449 | goto err_pdata; | ||
1450 | } | ||
1451 | } | ||
1452 | if (!pdata->dma_slave) { | ||
1406 | err = -ENXIO; | 1453 | err = -ENXIO; |
1407 | goto err_pdata; | 1454 | goto err_pdata; |
1408 | } | 1455 | } |
1409 | err = atmel_sha_dma_init(sha_dd, pdata); | 1456 | err = atmel_sha_dma_init(sha_dd, pdata); |
1410 | if (err) | 1457 | if (err) |
1411 | goto err_sha_dma; | 1458 | goto err_sha_dma; |
1459 | |||
1460 | dev_info(dev, "using %s for DMA transfers\n", | ||
1461 | dma_chan_name(sha_dd->dma_lch_in.chan)); | ||
1412 | } | 1462 | } |
1413 | 1463 | ||
1414 | spin_lock(&atmel_sha.lock); | 1464 | spin_lock(&atmel_sha.lock); |
@@ -1419,7 +1469,9 @@ static int atmel_sha_probe(struct platform_device *pdev) | |||
1419 | if (err) | 1469 | if (err) |
1420 | goto err_algs; | 1470 | goto err_algs; |
1421 | 1471 | ||
1422 | dev_info(dev, "Atmel SHA1/SHA256\n"); | 1472 | dev_info(dev, "Atmel SHA1/SHA256%s%s\n", |
1473 | sha_dd->caps.has_sha224 ? "/SHA224" : "", | ||
1474 | sha_dd->caps.has_sha_384_512 ? "/SHA384/SHA512" : ""); | ||
1423 | 1475 | ||
1424 | return 0; | 1476 | return 0; |
1425 | 1477 | ||
@@ -1483,6 +1535,7 @@ static struct platform_driver atmel_sha_driver = { | |||
1483 | .driver = { | 1535 | .driver = { |
1484 | .name = "atmel_sha", | 1536 | .name = "atmel_sha", |
1485 | .owner = THIS_MODULE, | 1537 | .owner = THIS_MODULE, |
1538 | .of_match_table = of_match_ptr(atmel_sha_dt_ids), | ||
1486 | }, | 1539 | }, |
1487 | }; | 1540 | }; |
1488 | 1541 | ||
diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c index 4a99564a08e6..6cde5b530c69 100644 --- a/drivers/crypto/atmel-tdes.c +++ b/drivers/crypto/atmel-tdes.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
31 | #include <linux/scatterlist.h> | 31 | #include <linux/scatterlist.h> |
32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
33 | #include <linux/of_device.h> | ||
33 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
34 | #include <linux/crypto.h> | 35 | #include <linux/crypto.h> |
35 | #include <linux/cryptohash.h> | 36 | #include <linux/cryptohash.h> |
@@ -716,59 +717,50 @@ static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd, | |||
716 | struct crypto_platform_data *pdata) | 717 | struct crypto_platform_data *pdata) |
717 | { | 718 | { |
718 | int err = -ENOMEM; | 719 | int err = -ENOMEM; |
719 | dma_cap_mask_t mask_in, mask_out; | 720 | dma_cap_mask_t mask; |
721 | |||
722 | dma_cap_zero(mask); | ||
723 | dma_cap_set(DMA_SLAVE, mask); | ||
724 | |||
725 | /* Try to grab 2 DMA channels */ | ||
726 | dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask, | ||
727 | atmel_tdes_filter, &pdata->dma_slave->rxdata, dd->dev, "tx"); | ||
728 | if (!dd->dma_lch_in.chan) | ||
729 | goto err_dma_in; | ||
730 | |||
731 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
732 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
733 | TDES_IDATA1R; | ||
734 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
735 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
736 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
737 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
738 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
739 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
740 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
741 | |||
742 | dd->dma_lch_out.chan = dma_request_slave_channel_compat(mask, | ||
743 | atmel_tdes_filter, &pdata->dma_slave->txdata, dd->dev, "rx"); | ||
744 | if (!dd->dma_lch_out.chan) | ||
745 | goto err_dma_out; | ||
746 | |||
747 | dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; | ||
748 | dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + | ||
749 | TDES_ODATA1R; | ||
750 | dd->dma_lch_out.dma_conf.src_maxburst = 1; | ||
751 | dd->dma_lch_out.dma_conf.src_addr_width = | ||
752 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
753 | dd->dma_lch_out.dma_conf.dst_maxburst = 1; | ||
754 | dd->dma_lch_out.dma_conf.dst_addr_width = | ||
755 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
756 | dd->dma_lch_out.dma_conf.device_fc = false; | ||
720 | 757 | ||
721 | if (pdata && pdata->dma_slave->txdata.dma_dev && | 758 | return 0; |
722 | pdata->dma_slave->rxdata.dma_dev) { | ||
723 | |||
724 | /* Try to grab 2 DMA channels */ | ||
725 | dma_cap_zero(mask_in); | ||
726 | dma_cap_set(DMA_SLAVE, mask_in); | ||
727 | |||
728 | dd->dma_lch_in.chan = dma_request_channel(mask_in, | ||
729 | atmel_tdes_filter, &pdata->dma_slave->rxdata); | ||
730 | |||
731 | if (!dd->dma_lch_in.chan) | ||
732 | goto err_dma_in; | ||
733 | |||
734 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
735 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
736 | TDES_IDATA1R; | ||
737 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
738 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
739 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
740 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
741 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
742 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
743 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
744 | |||
745 | dma_cap_zero(mask_out); | ||
746 | dma_cap_set(DMA_SLAVE, mask_out); | ||
747 | dd->dma_lch_out.chan = dma_request_channel(mask_out, | ||
748 | atmel_tdes_filter, &pdata->dma_slave->txdata); | ||
749 | |||
750 | if (!dd->dma_lch_out.chan) | ||
751 | goto err_dma_out; | ||
752 | |||
753 | dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; | ||
754 | dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + | ||
755 | TDES_ODATA1R; | ||
756 | dd->dma_lch_out.dma_conf.src_maxburst = 1; | ||
757 | dd->dma_lch_out.dma_conf.src_addr_width = | ||
758 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
759 | dd->dma_lch_out.dma_conf.dst_maxburst = 1; | ||
760 | dd->dma_lch_out.dma_conf.dst_addr_width = | ||
761 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
762 | dd->dma_lch_out.dma_conf.device_fc = false; | ||
763 | |||
764 | return 0; | ||
765 | } else { | ||
766 | return -ENODEV; | ||
767 | } | ||
768 | 759 | ||
769 | err_dma_out: | 760 | err_dma_out: |
770 | dma_release_channel(dd->dma_lch_in.chan); | 761 | dma_release_channel(dd->dma_lch_in.chan); |
771 | err_dma_in: | 762 | err_dma_in: |
763 | dev_warn(dd->dev, "no DMA channel available\n"); | ||
772 | return err; | 764 | return err; |
773 | } | 765 | } |
774 | 766 | ||
@@ -1317,6 +1309,47 @@ static void atmel_tdes_get_cap(struct atmel_tdes_dev *dd) | |||
1317 | } | 1309 | } |
1318 | } | 1310 | } |
1319 | 1311 | ||
1312 | #if defined(CONFIG_OF) | ||
1313 | static const struct of_device_id atmel_tdes_dt_ids[] = { | ||
1314 | { .compatible = "atmel,at91sam9g46-tdes" }, | ||
1315 | { /* sentinel */ } | ||
1316 | }; | ||
1317 | MODULE_DEVICE_TABLE(of, atmel_tdes_dt_ids); | ||
1318 | |||
1319 | static struct crypto_platform_data *atmel_tdes_of_init(struct platform_device *pdev) | ||
1320 | { | ||
1321 | struct device_node *np = pdev->dev.of_node; | ||
1322 | struct crypto_platform_data *pdata; | ||
1323 | |||
1324 | if (!np) { | ||
1325 | dev_err(&pdev->dev, "device node not found\n"); | ||
1326 | return ERR_PTR(-EINVAL); | ||
1327 | } | ||
1328 | |||
1329 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
1330 | if (!pdata) { | ||
1331 | dev_err(&pdev->dev, "could not allocate memory for pdata\n"); | ||
1332 | return ERR_PTR(-ENOMEM); | ||
1333 | } | ||
1334 | |||
1335 | pdata->dma_slave = devm_kzalloc(&pdev->dev, | ||
1336 | sizeof(*(pdata->dma_slave)), | ||
1337 | GFP_KERNEL); | ||
1338 | if (!pdata->dma_slave) { | ||
1339 | dev_err(&pdev->dev, "could not allocate memory for dma_slave\n"); | ||
1340 | devm_kfree(&pdev->dev, pdata); | ||
1341 | return ERR_PTR(-ENOMEM); | ||
1342 | } | ||
1343 | |||
1344 | return pdata; | ||
1345 | } | ||
1346 | #else /* CONFIG_OF */ | ||
1347 | static inline struct crypto_platform_data *atmel_tdes_of_init(struct platform_device *pdev) | ||
1348 | { | ||
1349 | return ERR_PTR(-EINVAL); | ||
1350 | } | ||
1351 | #endif | ||
1352 | |||
1320 | static int atmel_tdes_probe(struct platform_device *pdev) | 1353 | static int atmel_tdes_probe(struct platform_device *pdev) |
1321 | { | 1354 | { |
1322 | struct atmel_tdes_dev *tdes_dd; | 1355 | struct atmel_tdes_dev *tdes_dd; |
@@ -1399,13 +1432,24 @@ static int atmel_tdes_probe(struct platform_device *pdev) | |||
1399 | if (tdes_dd->caps.has_dma) { | 1432 | if (tdes_dd->caps.has_dma) { |
1400 | pdata = pdev->dev.platform_data; | 1433 | pdata = pdev->dev.platform_data; |
1401 | if (!pdata) { | 1434 | if (!pdata) { |
1402 | dev_err(&pdev->dev, "platform data not available\n"); | 1435 | pdata = atmel_tdes_of_init(pdev); |
1436 | if (IS_ERR(pdata)) { | ||
1437 | dev_err(&pdev->dev, "platform data not available\n"); | ||
1438 | err = PTR_ERR(pdata); | ||
1439 | goto err_pdata; | ||
1440 | } | ||
1441 | } | ||
1442 | if (!pdata->dma_slave) { | ||
1403 | err = -ENXIO; | 1443 | err = -ENXIO; |
1404 | goto err_pdata; | 1444 | goto err_pdata; |
1405 | } | 1445 | } |
1406 | err = atmel_tdes_dma_init(tdes_dd, pdata); | 1446 | err = atmel_tdes_dma_init(tdes_dd, pdata); |
1407 | if (err) | 1447 | if (err) |
1408 | goto err_tdes_dma; | 1448 | goto err_tdes_dma; |
1449 | |||
1450 | dev_info(dev, "using %s, %s for DMA transfers\n", | ||
1451 | dma_chan_name(tdes_dd->dma_lch_in.chan), | ||
1452 | dma_chan_name(tdes_dd->dma_lch_out.chan)); | ||
1409 | } | 1453 | } |
1410 | 1454 | ||
1411 | spin_lock(&atmel_tdes.lock); | 1455 | spin_lock(&atmel_tdes.lock); |
@@ -1487,6 +1531,7 @@ static struct platform_driver atmel_tdes_driver = { | |||
1487 | .driver = { | 1531 | .driver = { |
1488 | .name = "atmel_tdes", | 1532 | .name = "atmel_tdes", |
1489 | .owner = THIS_MODULE, | 1533 | .owner = THIS_MODULE, |
1534 | .of_match_table = of_match_ptr(atmel_tdes_dt_ids), | ||
1490 | }, | 1535 | }, |
1491 | }; | 1536 | }; |
1492 | 1537 | ||
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 50cc557abe41..697338772b64 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -115,6 +115,13 @@ config GPIO_CLPS711X | |||
115 | help | 115 | help |
116 | Say yes here to support GPIO on CLPS711X SoCs. | 116 | Say yes here to support GPIO on CLPS711X SoCs. |
117 | 117 | ||
118 | config GPIO_DAVINCI | ||
119 | bool "TI Davinci/Keystone GPIO support" | ||
120 | default y if ARCH_DAVINCI | ||
121 | depends on ARM && (ARCH_DAVINCI || ARCH_KEYSTONE) | ||
122 | help | ||
123 | Say yes here to enable GPIO support for TI Davinci/Keystone SoCs. | ||
124 | |||
118 | config GPIO_GENERIC_PLATFORM | 125 | config GPIO_GENERIC_PLATFORM |
119 | tristate "Generic memory-mapped GPIO controller support (MMIO platform device)" | 126 | tristate "Generic memory-mapped GPIO controller support (MMIO platform device)" |
120 | select GPIO_GENERIC | 127 | select GPIO_GENERIC |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 0248471402e4..5d50179ece16 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -22,7 +22,7 @@ obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o | |||
22 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o | 22 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o |
23 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o | 23 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o |
24 | obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o | 24 | obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o |
25 | obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o | 25 | obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o |
26 | obj-$(CONFIG_GPIO_EM) += gpio-em.o | 26 | obj-$(CONFIG_GPIO_EM) += gpio-em.o |
27 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | 27 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o |
28 | obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o | 28 | obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o |
diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 84be70157ad6..7629b4f12b7f 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c | |||
@@ -16,8 +16,13 @@ | |||
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
19 | #include <linux/irqdomain.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/of_device.h> | ||
19 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
20 | #include <linux/platform_data/gpio-davinci.h> | 24 | #include <linux/platform_data/gpio-davinci.h> |
25 | #include <linux/irqchip/chained_irq.h> | ||
21 | 26 | ||
22 | struct davinci_gpio_regs { | 27 | struct davinci_gpio_regs { |
23 | u32 dir; | 28 | u32 dir; |
@@ -82,14 +87,14 @@ static inline int __davinci_direction(struct gpio_chip *chip, | |||
82 | u32 mask = 1 << offset; | 87 | u32 mask = 1 << offset; |
83 | 88 | ||
84 | spin_lock_irqsave(&d->lock, flags); | 89 | spin_lock_irqsave(&d->lock, flags); |
85 | temp = __raw_readl(&g->dir); | 90 | temp = readl_relaxed(&g->dir); |
86 | if (out) { | 91 | if (out) { |
87 | temp &= ~mask; | 92 | temp &= ~mask; |
88 | __raw_writel(mask, value ? &g->set_data : &g->clr_data); | 93 | writel_relaxed(mask, value ? &g->set_data : &g->clr_data); |
89 | } else { | 94 | } else { |
90 | temp |= mask; | 95 | temp |= mask; |
91 | } | 96 | } |
92 | __raw_writel(temp, &g->dir); | 97 | writel_relaxed(temp, &g->dir); |
93 | spin_unlock_irqrestore(&d->lock, flags); | 98 | spin_unlock_irqrestore(&d->lock, flags); |
94 | 99 | ||
95 | return 0; | 100 | return 0; |
@@ -118,7 +123,7 @@ static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset) | |||
118 | struct davinci_gpio_controller *d = chip2controller(chip); | 123 | struct davinci_gpio_controller *d = chip2controller(chip); |
119 | struct davinci_gpio_regs __iomem *g = d->regs; | 124 | struct davinci_gpio_regs __iomem *g = d->regs; |
120 | 125 | ||
121 | return (1 << offset) & __raw_readl(&g->in_data); | 126 | return (1 << offset) & readl_relaxed(&g->in_data); |
122 | } | 127 | } |
123 | 128 | ||
124 | /* | 129 | /* |
@@ -130,7 +135,41 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
130 | struct davinci_gpio_controller *d = chip2controller(chip); | 135 | struct davinci_gpio_controller *d = chip2controller(chip); |
131 | struct davinci_gpio_regs __iomem *g = d->regs; | 136 | struct davinci_gpio_regs __iomem *g = d->regs; |
132 | 137 | ||
133 | __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data); | 138 | writel_relaxed((1 << offset), value ? &g->set_data : &g->clr_data); |
139 | } | ||
140 | |||
141 | static struct davinci_gpio_platform_data * | ||
142 | davinci_gpio_get_pdata(struct platform_device *pdev) | ||
143 | { | ||
144 | struct device_node *dn = pdev->dev.of_node; | ||
145 | struct davinci_gpio_platform_data *pdata; | ||
146 | int ret; | ||
147 | u32 val; | ||
148 | |||
149 | if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node) | ||
150 | return pdev->dev.platform_data; | ||
151 | |||
152 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
153 | if (!pdata) | ||
154 | return NULL; | ||
155 | |||
156 | ret = of_property_read_u32(dn, "ti,ngpio", &val); | ||
157 | if (ret) | ||
158 | goto of_err; | ||
159 | |||
160 | pdata->ngpio = val; | ||
161 | |||
162 | ret = of_property_read_u32(dn, "ti,davinci-gpio-unbanked", &val); | ||
163 | if (ret) | ||
164 | goto of_err; | ||
165 | |||
166 | pdata->gpio_unbanked = val; | ||
167 | |||
168 | return pdata; | ||
169 | |||
170 | of_err: | ||
171 | dev_err(&pdev->dev, "Populating pdata from DT failed: err %d\n", ret); | ||
172 | return NULL; | ||
134 | } | 173 | } |
135 | 174 | ||
136 | static int davinci_gpio_probe(struct platform_device *pdev) | 175 | static int davinci_gpio_probe(struct platform_device *pdev) |
@@ -143,12 +182,14 @@ static int davinci_gpio_probe(struct platform_device *pdev) | |||
143 | struct device *dev = &pdev->dev; | 182 | struct device *dev = &pdev->dev; |
144 | struct resource *res; | 183 | struct resource *res; |
145 | 184 | ||
146 | pdata = dev->platform_data; | 185 | pdata = davinci_gpio_get_pdata(pdev); |
147 | if (!pdata) { | 186 | if (!pdata) { |
148 | dev_err(dev, "No platform data found\n"); | 187 | dev_err(dev, "No platform data found\n"); |
149 | return -EINVAL; | 188 | return -EINVAL; |
150 | } | 189 | } |
151 | 190 | ||
191 | dev->platform_data = pdata; | ||
192 | |||
152 | /* | 193 | /* |
153 | * The gpio banks conceptually expose a segmented bitmap, | 194 | * The gpio banks conceptually expose a segmented bitmap, |
154 | * and "ngpio" is one more than the largest zero-based | 195 | * and "ngpio" is one more than the largest zero-based |
@@ -160,8 +201,8 @@ static int davinci_gpio_probe(struct platform_device *pdev) | |||
160 | return -EINVAL; | 201 | return -EINVAL; |
161 | } | 202 | } |
162 | 203 | ||
163 | if (WARN_ON(DAVINCI_N_GPIO < ngpio)) | 204 | if (WARN_ON(ARCH_NR_GPIOS < ngpio)) |
164 | ngpio = DAVINCI_N_GPIO; | 205 | ngpio = ARCH_NR_GPIOS; |
165 | 206 | ||
166 | chips = devm_kzalloc(dev, | 207 | chips = devm_kzalloc(dev, |
167 | ngpio * sizeof(struct davinci_gpio_controller), | 208 | ngpio * sizeof(struct davinci_gpio_controller), |
@@ -194,6 +235,9 @@ static int davinci_gpio_probe(struct platform_device *pdev) | |||
194 | if (chips[i].chip.ngpio > 32) | 235 | if (chips[i].chip.ngpio > 32) |
195 | chips[i].chip.ngpio = 32; | 236 | chips[i].chip.ngpio = 32; |
196 | 237 | ||
238 | #ifdef CONFIG_OF_GPIO | ||
239 | chips[i].chip.of_node = dev->of_node; | ||
240 | #endif | ||
197 | spin_lock_init(&chips[i].lock); | 241 | spin_lock_init(&chips[i].lock); |
198 | 242 | ||
199 | regs = gpio2regs(base); | 243 | regs = gpio2regs(base); |
@@ -227,8 +271,8 @@ static void gpio_irq_disable(struct irq_data *d) | |||
227 | struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); | 271 | struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); |
228 | u32 mask = (u32) irq_data_get_irq_handler_data(d); | 272 | u32 mask = (u32) irq_data_get_irq_handler_data(d); |
229 | 273 | ||
230 | __raw_writel(mask, &g->clr_falling); | 274 | writel_relaxed(mask, &g->clr_falling); |
231 | __raw_writel(mask, &g->clr_rising); | 275 | writel_relaxed(mask, &g->clr_rising); |
232 | } | 276 | } |
233 | 277 | ||
234 | static void gpio_irq_enable(struct irq_data *d) | 278 | static void gpio_irq_enable(struct irq_data *d) |
@@ -242,9 +286,9 @@ static void gpio_irq_enable(struct irq_data *d) | |||
242 | status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; | 286 | status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; |
243 | 287 | ||
244 | if (status & IRQ_TYPE_EDGE_FALLING) | 288 | if (status & IRQ_TYPE_EDGE_FALLING) |
245 | __raw_writel(mask, &g->set_falling); | 289 | writel_relaxed(mask, &g->set_falling); |
246 | if (status & IRQ_TYPE_EDGE_RISING) | 290 | if (status & IRQ_TYPE_EDGE_RISING) |
247 | __raw_writel(mask, &g->set_rising); | 291 | writel_relaxed(mask, &g->set_rising); |
248 | } | 292 | } |
249 | 293 | ||
250 | static int gpio_irq_type(struct irq_data *d, unsigned trigger) | 294 | static int gpio_irq_type(struct irq_data *d, unsigned trigger) |
@@ -278,34 +322,28 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
278 | mask <<= 16; | 322 | mask <<= 16; |
279 | 323 | ||
280 | /* temporarily mask (level sensitive) parent IRQ */ | 324 | /* temporarily mask (level sensitive) parent IRQ */ |
281 | desc->irq_data.chip->irq_mask(&desc->irq_data); | 325 | chained_irq_enter(irq_desc_get_chip(desc), desc); |
282 | desc->irq_data.chip->irq_ack(&desc->irq_data); | ||
283 | while (1) { | 326 | while (1) { |
284 | u32 status; | 327 | u32 status; |
285 | int n; | 328 | int bit; |
286 | int res; | ||
287 | 329 | ||
288 | /* ack any irqs */ | 330 | /* ack any irqs */ |
289 | status = __raw_readl(&g->intstat) & mask; | 331 | status = readl_relaxed(&g->intstat) & mask; |
290 | if (!status) | 332 | if (!status) |
291 | break; | 333 | break; |
292 | __raw_writel(status, &g->intstat); | 334 | writel_relaxed(status, &g->intstat); |
293 | 335 | ||
294 | /* now demux them to the right lowlevel handler */ | 336 | /* now demux them to the right lowlevel handler */ |
295 | n = d->irq_base; | ||
296 | if (irq & 1) { | ||
297 | n += 16; | ||
298 | status >>= 16; | ||
299 | } | ||
300 | 337 | ||
301 | while (status) { | 338 | while (status) { |
302 | res = ffs(status); | 339 | bit = __ffs(status); |
303 | n += res; | 340 | status &= ~BIT(bit); |
304 | generic_handle_irq(n - 1); | 341 | generic_handle_irq( |
305 | status >>= res; | 342 | irq_find_mapping(d->irq_domain, |
343 | d->chip.base + bit)); | ||
306 | } | 344 | } |
307 | } | 345 | } |
308 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | 346 | chained_irq_exit(irq_desc_get_chip(desc), desc); |
309 | /* now it may re-trigger */ | 347 | /* now it may re-trigger */ |
310 | } | 348 | } |
311 | 349 | ||
@@ -313,10 +351,10 @@ static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset) | |||
313 | { | 351 | { |
314 | struct davinci_gpio_controller *d = chip2controller(chip); | 352 | struct davinci_gpio_controller *d = chip2controller(chip); |
315 | 353 | ||
316 | if (d->irq_base >= 0) | 354 | if (d->irq_domain) |
317 | return d->irq_base + offset; | 355 | return irq_create_mapping(d->irq_domain, d->chip.base + offset); |
318 | else | 356 | else |
319 | return -ENODEV; | 357 | return -ENXIO; |
320 | } | 358 | } |
321 | 359 | ||
322 | static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) | 360 | static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) |
@@ -346,14 +384,35 @@ static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger) | |||
346 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | 384 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
347 | return -EINVAL; | 385 | return -EINVAL; |
348 | 386 | ||
349 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING) | 387 | writel_relaxed(mask, (trigger & IRQ_TYPE_EDGE_FALLING) |
350 | ? &g->set_falling : &g->clr_falling); | 388 | ? &g->set_falling : &g->clr_falling); |
351 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING) | 389 | writel_relaxed(mask, (trigger & IRQ_TYPE_EDGE_RISING) |
352 | ? &g->set_rising : &g->clr_rising); | 390 | ? &g->set_rising : &g->clr_rising); |
353 | 391 | ||
354 | return 0; | 392 | return 0; |
355 | } | 393 | } |
356 | 394 | ||
395 | static int | ||
396 | davinci_gpio_irq_map(struct irq_domain *d, unsigned int irq, | ||
397 | irq_hw_number_t hw) | ||
398 | { | ||
399 | struct davinci_gpio_regs __iomem *g = gpio2regs(hw); | ||
400 | |||
401 | irq_set_chip_and_handler_name(irq, &gpio_irqchip, handle_simple_irq, | ||
402 | "davinci_gpio"); | ||
403 | irq_set_irq_type(irq, IRQ_TYPE_NONE); | ||
404 | irq_set_chip_data(irq, (__force void *)g); | ||
405 | irq_set_handler_data(irq, (void *)__gpio_mask(hw)); | ||
406 | set_irq_flags(irq, IRQF_VALID); | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | static const struct irq_domain_ops davinci_gpio_irq_ops = { | ||
412 | .map = davinci_gpio_irq_map, | ||
413 | .xlate = irq_domain_xlate_onetwocell, | ||
414 | }; | ||
415 | |||
357 | /* | 416 | /* |
358 | * NOTE: for suspend/resume, probably best to make a platform_device with | 417 | * NOTE: for suspend/resume, probably best to make a platform_device with |
359 | * suspend_late/resume_resume calls hooking into results of the set_wake() | 418 | * suspend_late/resume_resume calls hooking into results of the set_wake() |
@@ -373,6 +432,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) | |||
373 | struct davinci_gpio_controller *chips = platform_get_drvdata(pdev); | 432 | struct davinci_gpio_controller *chips = platform_get_drvdata(pdev); |
374 | struct davinci_gpio_platform_data *pdata = dev->platform_data; | 433 | struct davinci_gpio_platform_data *pdata = dev->platform_data; |
375 | struct davinci_gpio_regs __iomem *g; | 434 | struct davinci_gpio_regs __iomem *g; |
435 | struct irq_domain *irq_domain = NULL; | ||
376 | 436 | ||
377 | ngpio = pdata->ngpio; | 437 | ngpio = pdata->ngpio; |
378 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 438 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
@@ -396,6 +456,22 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) | |||
396 | } | 456 | } |
397 | clk_prepare_enable(clk); | 457 | clk_prepare_enable(clk); |
398 | 458 | ||
459 | if (!pdata->gpio_unbanked) { | ||
460 | irq = irq_alloc_descs(-1, 0, ngpio, 0); | ||
461 | if (irq < 0) { | ||
462 | dev_err(dev, "Couldn't allocate IRQ numbers\n"); | ||
463 | return irq; | ||
464 | } | ||
465 | |||
466 | irq_domain = irq_domain_add_legacy(NULL, ngpio, irq, 0, | ||
467 | &davinci_gpio_irq_ops, | ||
468 | chips); | ||
469 | if (!irq_domain) { | ||
470 | dev_err(dev, "Couldn't register an IRQ domain\n"); | ||
471 | return -ENODEV; | ||
472 | } | ||
473 | } | ||
474 | |||
399 | /* | 475 | /* |
400 | * Arrange gpio_to_irq() support, handling either direct IRQs or | 476 | * Arrange gpio_to_irq() support, handling either direct IRQs or |
401 | * banked IRQs. Having GPIOs in the first GPIO bank use direct | 477 | * banked IRQs. Having GPIOs in the first GPIO bank use direct |
@@ -404,9 +480,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) | |||
404 | */ | 480 | */ |
405 | for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) { | 481 | for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) { |
406 | chips[bank].chip.to_irq = gpio_to_irq_banked; | 482 | chips[bank].chip.to_irq = gpio_to_irq_banked; |
407 | chips[bank].irq_base = pdata->gpio_unbanked | 483 | chips[bank].irq_domain = irq_domain; |
408 | ? -EINVAL | ||
409 | : (pdata->intc_irq_num + gpio); | ||
410 | } | 484 | } |
411 | 485 | ||
412 | /* | 486 | /* |
@@ -432,8 +506,8 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) | |||
432 | 506 | ||
433 | /* default trigger: both edges */ | 507 | /* default trigger: both edges */ |
434 | g = gpio2regs(0); | 508 | g = gpio2regs(0); |
435 | __raw_writel(~0, &g->set_falling); | 509 | writel_relaxed(~0, &g->set_falling); |
436 | __raw_writel(~0, &g->set_rising); | 510 | writel_relaxed(~0, &g->set_rising); |
437 | 511 | ||
438 | /* set the direct IRQs up to use that irqchip */ | 512 | /* set the direct IRQs up to use that irqchip */ |
439 | for (gpio = 0; gpio < pdata->gpio_unbanked; gpio++, irq++) { | 513 | for (gpio = 0; gpio < pdata->gpio_unbanked; gpio++, irq++) { |
@@ -449,15 +523,11 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) | |||
449 | * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we | 523 | * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we |
450 | * then chain through our own handler. | 524 | * then chain through our own handler. |
451 | */ | 525 | */ |
452 | for (gpio = 0, irq = gpio_to_irq(0), bank = 0; | 526 | for (gpio = 0, bank = 0; gpio < ngpio; bank++, bank_irq++, gpio += 16) { |
453 | gpio < ngpio; | ||
454 | bank++, bank_irq++) { | ||
455 | unsigned i; | ||
456 | |||
457 | /* disabled by default, enabled only as needed */ | 527 | /* disabled by default, enabled only as needed */ |
458 | g = gpio2regs(gpio); | 528 | g = gpio2regs(gpio); |
459 | __raw_writel(~0, &g->clr_falling); | 529 | writel_relaxed(~0, &g->clr_falling); |
460 | __raw_writel(~0, &g->clr_rising); | 530 | writel_relaxed(~0, &g->clr_rising); |
461 | 531 | ||
462 | /* set up all irqs in this bank */ | 532 | /* set up all irqs in this bank */ |
463 | irq_set_chained_handler(bank_irq, gpio_irq_handler); | 533 | irq_set_chained_handler(bank_irq, gpio_irq_handler); |
@@ -469,14 +539,6 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) | |||
469 | */ | 539 | */ |
470 | irq_set_handler_data(bank_irq, &chips[gpio / 32]); | 540 | irq_set_handler_data(bank_irq, &chips[gpio / 32]); |
471 | 541 | ||
472 | for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { | ||
473 | irq_set_chip(irq, &gpio_irqchip); | ||
474 | irq_set_chip_data(irq, (__force void *)g); | ||
475 | irq_set_handler_data(irq, (void *)__gpio_mask(gpio)); | ||
476 | irq_set_handler(irq, handle_simple_irq); | ||
477 | set_irq_flags(irq, IRQF_VALID); | ||
478 | } | ||
479 | |||
480 | binten |= BIT(bank); | 542 | binten |= BIT(bank); |
481 | } | 543 | } |
482 | 544 | ||
@@ -485,18 +547,25 @@ done: | |||
485 | * BINTEN -- per-bank interrupt enable. genirq would also let these | 547 | * BINTEN -- per-bank interrupt enable. genirq would also let these |
486 | * bits be set/cleared dynamically. | 548 | * bits be set/cleared dynamically. |
487 | */ | 549 | */ |
488 | __raw_writel(binten, gpio_base + BINTEN); | 550 | writel_relaxed(binten, gpio_base + BINTEN); |
489 | |||
490 | printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); | ||
491 | 551 | ||
492 | return 0; | 552 | return 0; |
493 | } | 553 | } |
494 | 554 | ||
555 | #if IS_ENABLED(CONFIG_OF) | ||
556 | static const struct of_device_id davinci_gpio_ids[] = { | ||
557 | { .compatible = "ti,dm6441-gpio", }, | ||
558 | { /* sentinel */ }, | ||
559 | }; | ||
560 | MODULE_DEVICE_TABLE(of, davinci_gpio_ids); | ||
561 | #endif | ||
562 | |||
495 | static struct platform_driver davinci_gpio_driver = { | 563 | static struct platform_driver davinci_gpio_driver = { |
496 | .probe = davinci_gpio_probe, | 564 | .probe = davinci_gpio_probe, |
497 | .driver = { | 565 | .driver = { |
498 | .name = "davinci_gpio", | 566 | .name = "davinci_gpio", |
499 | .owner = THIS_MODULE, | 567 | .owner = THIS_MODULE, |
568 | .of_match_table = of_match_ptr(davinci_gpio_ids), | ||
500 | }, | 569 | }, |
501 | }; | 570 | }; |
502 | 571 | ||
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index 868ed40cb6bf..40e6440348ff 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c | |||
@@ -171,8 +171,7 @@ static struct irq_domain_ops combiner_irq_domain_ops = { | |||
171 | 171 | ||
172 | static void __init combiner_init(void __iomem *combiner_base, | 172 | static void __init combiner_init(void __iomem *combiner_base, |
173 | struct device_node *np, | 173 | struct device_node *np, |
174 | unsigned int max_nr, | 174 | unsigned int max_nr) |
175 | int irq_base) | ||
176 | { | 175 | { |
177 | int i, irq; | 176 | int i, irq; |
178 | unsigned int nr_irq; | 177 | unsigned int nr_irq; |
@@ -186,7 +185,7 @@ static void __init combiner_init(void __iomem *combiner_base, | |||
186 | return; | 185 | return; |
187 | } | 186 | } |
188 | 187 | ||
189 | combiner_irq_domain = irq_domain_add_simple(np, nr_irq, irq_base, | 188 | combiner_irq_domain = irq_domain_add_linear(np, nr_irq, |
190 | &combiner_irq_domain_ops, combiner_data); | 189 | &combiner_irq_domain_ops, combiner_data); |
191 | if (WARN_ON(!combiner_irq_domain)) { | 190 | if (WARN_ON(!combiner_irq_domain)) { |
192 | pr_warning("%s: irq domain init failed\n", __func__); | 191 | pr_warning("%s: irq domain init failed\n", __func__); |
@@ -207,7 +206,6 @@ static int __init combiner_of_init(struct device_node *np, | |||
207 | { | 206 | { |
208 | void __iomem *combiner_base; | 207 | void __iomem *combiner_base; |
209 | unsigned int max_nr = 20; | 208 | unsigned int max_nr = 20; |
210 | int irq_base = -1; | ||
211 | 209 | ||
212 | combiner_base = of_iomap(np, 0); | 210 | combiner_base = of_iomap(np, 0); |
213 | if (!combiner_base) { | 211 | if (!combiner_base) { |
@@ -221,14 +219,7 @@ static int __init combiner_of_init(struct device_node *np, | |||
221 | __func__, max_nr); | 219 | __func__, max_nr); |
222 | } | 220 | } |
223 | 221 | ||
224 | /* | 222 | combiner_init(combiner_base, np, max_nr); |
225 | * FIXME: This is a hardwired COMBINER_IRQ(0,0). Once all devices | ||
226 | * get their IRQ from DT, remove this in order to get dynamic | ||
227 | * allocation. | ||
228 | */ | ||
229 | irq_base = 160; | ||
230 | |||
231 | combiner_init(combiner_base, np, max_nr, irq_base); | ||
232 | 223 | ||
233 | return 0; | 224 | return 0; |
234 | } | 225 | } |
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c index 2f404ba61c6c..8777065012a5 100644 --- a/drivers/irqchip/irq-renesas-irqc.c +++ b/drivers/irqchip/irq-renesas-irqc.c | |||
@@ -81,15 +81,12 @@ static void irqc_irq_disable(struct irq_data *d) | |||
81 | iowrite32(BIT(hw_irq), p->cpu_int_base + IRQC_EN_STS); | 81 | iowrite32(BIT(hw_irq), p->cpu_int_base + IRQC_EN_STS); |
82 | } | 82 | } |
83 | 83 | ||
84 | #define INTC_IRQ_SENSE_VALID 0x10 | ||
85 | #define INTC_IRQ_SENSE(x) (x + INTC_IRQ_SENSE_VALID) | ||
86 | |||
87 | static unsigned char irqc_sense[IRQ_TYPE_SENSE_MASK + 1] = { | 84 | static unsigned char irqc_sense[IRQ_TYPE_SENSE_MASK + 1] = { |
88 | [IRQ_TYPE_LEVEL_LOW] = INTC_IRQ_SENSE(0x01), | 85 | [IRQ_TYPE_LEVEL_LOW] = 0x01, |
89 | [IRQ_TYPE_LEVEL_HIGH] = INTC_IRQ_SENSE(0x02), | 86 | [IRQ_TYPE_LEVEL_HIGH] = 0x02, |
90 | [IRQ_TYPE_EDGE_FALLING] = INTC_IRQ_SENSE(0x04), /* Synchronous */ | 87 | [IRQ_TYPE_EDGE_FALLING] = 0x04, /* Synchronous */ |
91 | [IRQ_TYPE_EDGE_RISING] = INTC_IRQ_SENSE(0x08), /* Synchronous */ | 88 | [IRQ_TYPE_EDGE_RISING] = 0x08, /* Synchronous */ |
92 | [IRQ_TYPE_EDGE_BOTH] = INTC_IRQ_SENSE(0x0c), /* Synchronous */ | 89 | [IRQ_TYPE_EDGE_BOTH] = 0x0c, /* Synchronous */ |
93 | }; | 90 | }; |
94 | 91 | ||
95 | static int irqc_irq_set_type(struct irq_data *d, unsigned int type) | 92 | static int irqc_irq_set_type(struct irq_data *d, unsigned int type) |
@@ -101,12 +98,12 @@ static int irqc_irq_set_type(struct irq_data *d, unsigned int type) | |||
101 | 98 | ||
102 | irqc_dbg(&p->irq[hw_irq], "sense"); | 99 | irqc_dbg(&p->irq[hw_irq], "sense"); |
103 | 100 | ||
104 | if (!(value & INTC_IRQ_SENSE_VALID)) | 101 | if (!value) |
105 | return -EINVAL; | 102 | return -EINVAL; |
106 | 103 | ||
107 | tmp = ioread32(p->iomem + IRQC_CONFIG(hw_irq)); | 104 | tmp = ioread32(p->iomem + IRQC_CONFIG(hw_irq)); |
108 | tmp &= ~0x3f; | 105 | tmp &= ~0x3f; |
109 | tmp |= value ^ INTC_IRQ_SENSE_VALID; | 106 | tmp |= value; |
110 | iowrite32(tmp, p->iomem + IRQC_CONFIG(hw_irq)); | 107 | iowrite32(tmp, p->iomem + IRQC_CONFIG(hw_irq)); |
111 | return 0; | 108 | return 0; |
112 | } | 109 | } |
@@ -212,10 +209,8 @@ static int irqc_probe(struct platform_device *pdev) | |||
212 | irq_chip->name = name; | 209 | irq_chip->name = name; |
213 | irq_chip->irq_mask = irqc_irq_disable; | 210 | irq_chip->irq_mask = irqc_irq_disable; |
214 | irq_chip->irq_unmask = irqc_irq_enable; | 211 | irq_chip->irq_unmask = irqc_irq_enable; |
215 | irq_chip->irq_enable = irqc_irq_enable; | ||
216 | irq_chip->irq_disable = irqc_irq_disable; | ||
217 | irq_chip->irq_set_type = irqc_irq_set_type; | 212 | irq_chip->irq_set_type = irqc_irq_set_type; |
218 | irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; | 213 | irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; |
219 | 214 | ||
220 | p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, | 215 | p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, |
221 | p->number_of_irqs, | 216 | p->number_of_irqs, |
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c index 47a52ab580d8..3ae2bb8d9cf2 100644 --- a/drivers/irqchip/irq-versatile-fpga.c +++ b/drivers/irqchip/irq-versatile-fpga.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/of.h> | 10 | #include <linux/of.h> |
11 | #include <linux/of_address.h> | 11 | #include <linux/of_address.h> |
12 | #include <linux/of_irq.h> | ||
12 | 13 | ||
13 | #include <asm/exception.h> | 14 | #include <asm/exception.h> |
14 | #include <asm/mach/irq.h> | 15 | #include <asm/mach/irq.h> |
@@ -167,8 +168,12 @@ void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, | |||
167 | f->used_irqs++; | 168 | f->used_irqs++; |
168 | } | 169 | } |
169 | 170 | ||
170 | pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", | 171 | pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs", |
171 | fpga_irq_id, name, base, f->used_irqs); | 172 | fpga_irq_id, name, base, f->used_irqs); |
173 | if (parent_irq != -1) | ||
174 | pr_cont(", parent IRQ: %d\n", parent_irq); | ||
175 | else | ||
176 | pr_cont("\n"); | ||
172 | 177 | ||
173 | fpga_irq_id++; | 178 | fpga_irq_id++; |
174 | } | 179 | } |
@@ -180,6 +185,7 @@ int __init fpga_irq_of_init(struct device_node *node, | |||
180 | void __iomem *base; | 185 | void __iomem *base; |
181 | u32 clear_mask; | 186 | u32 clear_mask; |
182 | u32 valid_mask; | 187 | u32 valid_mask; |
188 | int parent_irq; | ||
183 | 189 | ||
184 | if (WARN_ON(!node)) | 190 | if (WARN_ON(!node)) |
185 | return -ENODEV; | 191 | return -ENODEV; |
@@ -193,7 +199,12 @@ int __init fpga_irq_of_init(struct device_node *node, | |||
193 | if (of_property_read_u32(node, "valid-mask", &valid_mask)) | 199 | if (of_property_read_u32(node, "valid-mask", &valid_mask)) |
194 | valid_mask = 0; | 200 | valid_mask = 0; |
195 | 201 | ||
196 | fpga_irq_init(base, node->name, 0, -1, valid_mask, node); | 202 | /* Some chips are cascaded from a parent IRQ */ |
203 | parent_irq = irq_of_parse_and_map(node, 0); | ||
204 | if (!parent_irq) | ||
205 | parent_irq = -1; | ||
206 | |||
207 | fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node); | ||
197 | 208 | ||
198 | writel(clear_mask, base + IRQ_ENABLE_CLEAR); | 209 | writel(clear_mask, base + IRQ_ENABLE_CLEAR); |
199 | writel(clear_mask, base + FIQ_ENABLE_CLEAR); | 210 | writel(clear_mask, base + FIQ_ENABLE_CLEAR); |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7fc5099e44b2..4e8ca9d5570f 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -324,7 +324,7 @@ config MMC_ATMELMCI | |||
324 | 324 | ||
325 | config MMC_MSM | 325 | config MMC_MSM |
326 | tristate "Qualcomm SDCC Controller Support" | 326 | tristate "Qualcomm SDCC Controller Support" |
327 | depends on MMC && ARCH_MSM | 327 | depends on MMC && (ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50) |
328 | help | 328 | help |
329 | This provides support for the SD/MMC cell found in the | 329 | This provides support for the SD/MMC cell found in the |
330 | MSM and QSD SOCs from Qualcomm. The controller also has | 330 | MSM and QSD SOCs from Qualcomm. The controller also has |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 007730222116..b1328a45b095 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -304,6 +304,17 @@ config RTC_DRV_ISL12022 | |||
304 | This driver can also be built as a module. If so, the module | 304 | This driver can also be built as a module. If so, the module |
305 | will be called rtc-isl12022. | 305 | will be called rtc-isl12022. |
306 | 306 | ||
307 | config RTC_DRV_ISL12057 | ||
308 | depends on I2C | ||
309 | select REGMAP_I2C | ||
310 | tristate "Intersil ISL12057" | ||
311 | help | ||
312 | If you say yes here you get support for the Intersil ISL12057 | ||
313 | I2C RTC chip. | ||
314 | |||
315 | This driver can also be built as a module. If so, the module | ||
316 | will be called rtc-isl12057. | ||
317 | |||
307 | config RTC_DRV_X1205 | 318 | config RTC_DRV_X1205 |
308 | tristate "Xicor/Intersil X1205" | 319 | tristate "Xicor/Intersil X1205" |
309 | help | 320 | help |
@@ -1104,6 +1115,13 @@ config RTC_DRV_SUN4V | |||
1104 | If you say Y here you will get support for the Hypervisor | 1115 | If you say Y here you will get support for the Hypervisor |
1105 | based RTC on SUN4V systems. | 1116 | based RTC on SUN4V systems. |
1106 | 1117 | ||
1118 | config RTC_DRV_SUNXI | ||
1119 | tristate "Allwinner sun4i/sun7i RTC" | ||
1120 | depends on ARCH_SUNXI | ||
1121 | help | ||
1122 | If you say Y here you will get support for the RTC found on | ||
1123 | Allwinner A10/A20. | ||
1124 | |||
1107 | config RTC_DRV_STARFIRE | 1125 | config RTC_DRV_STARFIRE |
1108 | bool "Starfire RTC" | 1126 | bool "Starfire RTC" |
1109 | depends on SPARC64 | 1127 | depends on SPARC64 |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 27b4bd884066..c00741a0bf10 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -58,6 +58,7 @@ obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o | |||
58 | obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o | 58 | obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o |
59 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | 59 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o |
60 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o | 60 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o |
61 | obj-$(CONFIG_RTC_DRV_ISL12057) += rtc-isl12057.o | ||
61 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o | 62 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o |
62 | obj-$(CONFIG_RTC_DRV_LP8788) += rtc-lp8788.o | 63 | obj-$(CONFIG_RTC_DRV_LP8788) += rtc-lp8788.o |
63 | obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o | 64 | obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o |
@@ -117,6 +118,7 @@ obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o | |||
117 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o | 118 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o |
118 | obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o | 119 | obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o |
119 | obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o | 120 | obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o |
121 | obj-$(CONFIG_RTC_DRV_SUNXI) += rtc-sunxi.o | ||
120 | obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o | 122 | obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o |
121 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o | 123 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o |
122 | obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o | 124 | obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o |
diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c new file mode 100644 index 000000000000..7854a656628f --- /dev/null +++ b/drivers/rtc/rtc-isl12057.c | |||
@@ -0,0 +1,310 @@ | |||
1 | /* | ||
2 | * rtc-isl12057 - Driver for Intersil ISL12057 I2C Real Time Clock | ||
3 | * | ||
4 | * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org> | ||
5 | * | ||
6 | * This work is largely based on Intersil ISL1208 driver developed by | ||
7 | * Hebert Valerio Riedel <hvr@gnu.org>. | ||
8 | * | ||
9 | * Detailed datasheet on which this development is based is available here: | ||
10 | * | ||
11 | * http://natisbad.org/NAS2/refs/ISL12057.pdf | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/mutex.h> | ||
26 | #include <linux/rtc.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/bcd.h> | ||
29 | #include <linux/rtc.h> | ||
30 | #include <linux/of.h> | ||
31 | #include <linux/of_device.h> | ||
32 | #include <linux/regmap.h> | ||
33 | |||
34 | #define DRV_NAME "rtc-isl12057" | ||
35 | |||
36 | /* RTC section */ | ||
37 | #define ISL12057_REG_RTC_SC 0x00 /* Seconds */ | ||
38 | #define ISL12057_REG_RTC_MN 0x01 /* Minutes */ | ||
39 | #define ISL12057_REG_RTC_HR 0x02 /* Hours */ | ||
40 | #define ISL12057_REG_RTC_HR_PM BIT(5) /* AM/PM bit in 12h format */ | ||
41 | #define ISL12057_REG_RTC_HR_MIL BIT(6) /* 24h/12h format */ | ||
42 | #define ISL12057_REG_RTC_DW 0x03 /* Day of the Week */ | ||
43 | #define ISL12057_REG_RTC_DT 0x04 /* Date */ | ||
44 | #define ISL12057_REG_RTC_MO 0x05 /* Month */ | ||
45 | #define ISL12057_REG_RTC_YR 0x06 /* Year */ | ||
46 | #define ISL12057_RTC_SEC_LEN 7 | ||
47 | |||
48 | /* Alarm 1 section */ | ||
49 | #define ISL12057_REG_A1_SC 0x07 /* Alarm 1 Seconds */ | ||
50 | #define ISL12057_REG_A1_MN 0x08 /* Alarm 1 Minutes */ | ||
51 | #define ISL12057_REG_A1_HR 0x09 /* Alarm 1 Hours */ | ||
52 | #define ISL12057_REG_A1_HR_PM BIT(5) /* AM/PM bit in 12h format */ | ||
53 | #define ISL12057_REG_A1_HR_MIL BIT(6) /* 24h/12h format */ | ||
54 | #define ISL12057_REG_A1_DWDT 0x0A /* Alarm 1 Date / Day of the week */ | ||
55 | #define ISL12057_REG_A1_DWDT_B BIT(6) /* DW / DT selection bit */ | ||
56 | #define ISL12057_A1_SEC_LEN 4 | ||
57 | |||
58 | /* Alarm 2 section */ | ||
59 | #define ISL12057_REG_A2_MN 0x0B /* Alarm 2 Minutes */ | ||
60 | #define ISL12057_REG_A2_HR 0x0C /* Alarm 2 Hours */ | ||
61 | #define ISL12057_REG_A2_DWDT 0x0D /* Alarm 2 Date / Day of the week */ | ||
62 | #define ISL12057_A2_SEC_LEN 3 | ||
63 | |||
64 | /* Control/Status registers */ | ||
65 | #define ISL12057_REG_INT 0x0E | ||
66 | #define ISL12057_REG_INT_A1IE BIT(0) /* Alarm 1 interrupt enable bit */ | ||
67 | #define ISL12057_REG_INT_A2IE BIT(1) /* Alarm 2 interrupt enable bit */ | ||
68 | #define ISL12057_REG_INT_INTCN BIT(2) /* Interrupt control enable bit */ | ||
69 | #define ISL12057_REG_INT_RS1 BIT(3) /* Freq out control bit 1 */ | ||
70 | #define ISL12057_REG_INT_RS2 BIT(4) /* Freq out control bit 2 */ | ||
71 | #define ISL12057_REG_INT_EOSC BIT(7) /* Oscillator enable bit */ | ||
72 | |||
73 | #define ISL12057_REG_SR 0x0F | ||
74 | #define ISL12057_REG_SR_A1F BIT(0) /* Alarm 1 interrupt bit */ | ||
75 | #define ISL12057_REG_SR_A2F BIT(1) /* Alarm 2 interrupt bit */ | ||
76 | #define ISL12057_REG_SR_OSF BIT(7) /* Oscillator failure bit */ | ||
77 | |||
78 | /* Register memory map length */ | ||
79 | #define ISL12057_MEM_MAP_LEN 0x10 | ||
80 | |||
81 | struct isl12057_rtc_data { | ||
82 | struct regmap *regmap; | ||
83 | struct mutex lock; | ||
84 | }; | ||
85 | |||
86 | static void isl12057_rtc_regs_to_tm(struct rtc_time *tm, u8 *regs) | ||
87 | { | ||
88 | tm->tm_sec = bcd2bin(regs[ISL12057_REG_RTC_SC]); | ||
89 | tm->tm_min = bcd2bin(regs[ISL12057_REG_RTC_MN]); | ||
90 | |||
91 | if (regs[ISL12057_REG_RTC_HR] & ISL12057_REG_RTC_HR_MIL) { /* AM/PM */ | ||
92 | tm->tm_hour = bcd2bin(regs[ISL12057_REG_RTC_HR] & 0x0f); | ||
93 | if (regs[ISL12057_REG_RTC_HR] & ISL12057_REG_RTC_HR_PM) | ||
94 | tm->tm_hour += 12; | ||
95 | } else { /* 24 hour mode */ | ||
96 | tm->tm_hour = bcd2bin(regs[ISL12057_REG_RTC_HR] & 0x3f); | ||
97 | } | ||
98 | |||
99 | tm->tm_mday = bcd2bin(regs[ISL12057_REG_RTC_DT]); | ||
100 | tm->tm_wday = bcd2bin(regs[ISL12057_REG_RTC_DW]) - 1; /* starts at 1 */ | ||
101 | tm->tm_mon = bcd2bin(regs[ISL12057_REG_RTC_MO]) - 1; /* starts at 1 */ | ||
102 | tm->tm_year = bcd2bin(regs[ISL12057_REG_RTC_YR]) + 100; | ||
103 | } | ||
104 | |||
105 | static int isl12057_rtc_tm_to_regs(u8 *regs, struct rtc_time *tm) | ||
106 | { | ||
107 | /* | ||
108 | * The clock has an 8 bit wide bcd-coded register for the year. | ||
109 | * tm_year is an offset from 1900 and we are interested in the | ||
110 | * 2000-2099 range, so any value less than 100 is invalid. | ||
111 | */ | ||
112 | if (tm->tm_year < 100) | ||
113 | return -EINVAL; | ||
114 | |||
115 | regs[ISL12057_REG_RTC_SC] = bin2bcd(tm->tm_sec); | ||
116 | regs[ISL12057_REG_RTC_MN] = bin2bcd(tm->tm_min); | ||
117 | regs[ISL12057_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */ | ||
118 | regs[ISL12057_REG_RTC_DT] = bin2bcd(tm->tm_mday); | ||
119 | regs[ISL12057_REG_RTC_MO] = bin2bcd(tm->tm_mon + 1); | ||
120 | regs[ISL12057_REG_RTC_YR] = bin2bcd(tm->tm_year - 100); | ||
121 | regs[ISL12057_REG_RTC_DW] = bin2bcd(tm->tm_wday + 1); | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Try and match register bits w/ fixed null values to see whether we | ||
128 | * are dealing with an ISL12057. Note: this function is called early | ||
129 | * during init and hence does need mutex protection. | ||
130 | */ | ||
131 | static int isl12057_i2c_validate_chip(struct regmap *regmap) | ||
132 | { | ||
133 | u8 regs[ISL12057_MEM_MAP_LEN]; | ||
134 | static const u8 mask[ISL12057_MEM_MAP_LEN] = { 0x80, 0x80, 0x80, 0xf8, | ||
135 | 0xc0, 0x60, 0x00, 0x00, | ||
136 | 0x00, 0x00, 0x00, 0x00, | ||
137 | 0x00, 0x00, 0x60, 0x7c }; | ||
138 | int ret, i; | ||
139 | |||
140 | ret = regmap_bulk_read(regmap, 0, regs, ISL12057_MEM_MAP_LEN); | ||
141 | if (ret) | ||
142 | return ret; | ||
143 | |||
144 | for (i = 0; i < ISL12057_MEM_MAP_LEN; ++i) { | ||
145 | if (regs[i] & mask[i]) /* check if bits are cleared */ | ||
146 | return -ENODEV; | ||
147 | } | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static int isl12057_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
153 | { | ||
154 | struct isl12057_rtc_data *data = dev_get_drvdata(dev); | ||
155 | u8 regs[ISL12057_RTC_SEC_LEN]; | ||
156 | int ret; | ||
157 | |||
158 | mutex_lock(&data->lock); | ||
159 | ret = regmap_bulk_read(data->regmap, ISL12057_REG_RTC_SC, regs, | ||
160 | ISL12057_RTC_SEC_LEN); | ||
161 | mutex_unlock(&data->lock); | ||
162 | |||
163 | if (ret) { | ||
164 | dev_err(dev, "%s: RTC read failed\n", __func__); | ||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | isl12057_rtc_regs_to_tm(tm, regs); | ||
169 | |||
170 | return rtc_valid_tm(tm); | ||
171 | } | ||
172 | |||
173 | static int isl12057_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
174 | { | ||
175 | struct isl12057_rtc_data *data = dev_get_drvdata(dev); | ||
176 | u8 regs[ISL12057_RTC_SEC_LEN]; | ||
177 | int ret; | ||
178 | |||
179 | ret = isl12057_rtc_tm_to_regs(regs, tm); | ||
180 | if (ret) | ||
181 | return ret; | ||
182 | |||
183 | mutex_lock(&data->lock); | ||
184 | ret = regmap_bulk_write(data->regmap, ISL12057_REG_RTC_SC, regs, | ||
185 | ISL12057_RTC_SEC_LEN); | ||
186 | mutex_unlock(&data->lock); | ||
187 | |||
188 | if (ret) | ||
189 | dev_err(dev, "%s: RTC write failed\n", __func__); | ||
190 | |||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * Check current RTC status and enable/disable what needs to be. Return 0 if | ||
196 | * everything went ok and a negative value upon error. Note: this function | ||
197 | * is called early during init and hence does need mutex protection. | ||
198 | */ | ||
199 | static int isl12057_check_rtc_status(struct device *dev, struct regmap *regmap) | ||
200 | { | ||
201 | int ret; | ||
202 | |||
203 | /* Enable oscillator if not already running */ | ||
204 | ret = regmap_update_bits(regmap, ISL12057_REG_INT, | ||
205 | ISL12057_REG_INT_EOSC, 0); | ||
206 | if (ret < 0) { | ||
207 | dev_err(dev, "Unable to enable oscillator\n"); | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | /* Clear oscillator failure bit if needed */ | ||
212 | ret = regmap_update_bits(regmap, ISL12057_REG_SR, | ||
213 | ISL12057_REG_SR_OSF, 0); | ||
214 | if (ret < 0) { | ||
215 | dev_err(dev, "Unable to clear oscillator failure bit\n"); | ||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | /* Clear alarm bit if needed */ | ||
220 | ret = regmap_update_bits(regmap, ISL12057_REG_SR, | ||
221 | ISL12057_REG_SR_A1F, 0); | ||
222 | if (ret < 0) { | ||
223 | dev_err(dev, "Unable to clear alarm bit\n"); | ||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static const struct rtc_class_ops rtc_ops = { | ||
231 | .read_time = isl12057_rtc_read_time, | ||
232 | .set_time = isl12057_rtc_set_time, | ||
233 | }; | ||
234 | |||
235 | static struct regmap_config isl12057_rtc_regmap_config = { | ||
236 | .reg_bits = 8, | ||
237 | .val_bits = 8, | ||
238 | }; | ||
239 | |||
240 | static int isl12057_probe(struct i2c_client *client, | ||
241 | const struct i2c_device_id *id) | ||
242 | { | ||
243 | struct device *dev = &client->dev; | ||
244 | struct isl12057_rtc_data *data; | ||
245 | struct rtc_device *rtc; | ||
246 | struct regmap *regmap; | ||
247 | int ret; | ||
248 | |||
249 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | | ||
250 | I2C_FUNC_SMBUS_BYTE_DATA | | ||
251 | I2C_FUNC_SMBUS_I2C_BLOCK)) | ||
252 | return -ENODEV; | ||
253 | |||
254 | regmap = devm_regmap_init_i2c(client, &isl12057_rtc_regmap_config); | ||
255 | if (IS_ERR(regmap)) { | ||
256 | ret = PTR_ERR(regmap); | ||
257 | dev_err(dev, "regmap allocation failed: %d\n", ret); | ||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | ret = isl12057_i2c_validate_chip(regmap); | ||
262 | if (ret) | ||
263 | return ret; | ||
264 | |||
265 | ret = isl12057_check_rtc_status(dev, regmap); | ||
266 | if (ret) | ||
267 | return ret; | ||
268 | |||
269 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); | ||
270 | if (!data) | ||
271 | return -ENOMEM; | ||
272 | |||
273 | mutex_init(&data->lock); | ||
274 | data->regmap = regmap; | ||
275 | dev_set_drvdata(dev, data); | ||
276 | |||
277 | rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, THIS_MODULE); | ||
278 | if (IS_ERR(rtc)) | ||
279 | return PTR_ERR(rtc); | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | #ifdef CONFIG_OF | ||
285 | static struct of_device_id isl12057_dt_match[] = { | ||
286 | { .compatible = "isl,isl12057" }, | ||
287 | { }, | ||
288 | }; | ||
289 | #endif | ||
290 | |||
291 | static const struct i2c_device_id isl12057_id[] = { | ||
292 | { "isl12057", 0 }, | ||
293 | { } | ||
294 | }; | ||
295 | MODULE_DEVICE_TABLE(i2c, isl12057_id); | ||
296 | |||
297 | static struct i2c_driver isl12057_driver = { | ||
298 | .driver = { | ||
299 | .name = DRV_NAME, | ||
300 | .owner = THIS_MODULE, | ||
301 | .of_match_table = of_match_ptr(isl12057_dt_match), | ||
302 | }, | ||
303 | .probe = isl12057_probe, | ||
304 | .id_table = isl12057_id, | ||
305 | }; | ||
306 | module_i2c_driver(isl12057_driver); | ||
307 | |||
308 | MODULE_AUTHOR("Arnaud EBALARD <arno@natisbad.org>"); | ||
309 | MODULE_DESCRIPTION("Intersil ISL12057 RTC driver"); | ||
310 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c new file mode 100644 index 000000000000..68a35284e5ad --- /dev/null +++ b/drivers/rtc/rtc-sunxi.c | |||
@@ -0,0 +1,523 @@ | |||
1 | /* | ||
2 | * An RTC driver for Allwinner A10/A20 | ||
3 | * | ||
4 | * Copyright (c) 2013, Carlo Caione <carlo.caione@gmail.com> | ||
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 as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/delay.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/fs.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/of.h> | ||
30 | #include <linux/of_address.h> | ||
31 | #include <linux/of_device.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/rtc.h> | ||
34 | #include <linux/types.h> | ||
35 | |||
36 | #define SUNXI_LOSC_CTRL 0x0000 | ||
37 | #define SUNXI_LOSC_CTRL_RTC_HMS_ACC BIT(8) | ||
38 | #define SUNXI_LOSC_CTRL_RTC_YMD_ACC BIT(7) | ||
39 | |||
40 | #define SUNXI_RTC_YMD 0x0004 | ||
41 | |||
42 | #define SUNXI_RTC_HMS 0x0008 | ||
43 | |||
44 | #define SUNXI_ALRM_DHMS 0x000c | ||
45 | |||
46 | #define SUNXI_ALRM_EN 0x0014 | ||
47 | #define SUNXI_ALRM_EN_CNT_EN BIT(8) | ||
48 | |||
49 | #define SUNXI_ALRM_IRQ_EN 0x0018 | ||
50 | #define SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN BIT(0) | ||
51 | |||
52 | #define SUNXI_ALRM_IRQ_STA 0x001c | ||
53 | #define SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND BIT(0) | ||
54 | |||
55 | #define SUNXI_MASK_DH 0x0000001f | ||
56 | #define SUNXI_MASK_SM 0x0000003f | ||
57 | #define SUNXI_MASK_M 0x0000000f | ||
58 | #define SUNXI_MASK_LY 0x00000001 | ||
59 | #define SUNXI_MASK_D 0x00000ffe | ||
60 | #define SUNXI_MASK_M 0x0000000f | ||
61 | |||
62 | #define SUNXI_GET(x, mask, shift) (((x) & ((mask) << (shift))) \ | ||
63 | >> (shift)) | ||
64 | |||
65 | #define SUNXI_SET(x, mask, shift) (((x) & (mask)) << (shift)) | ||
66 | |||
67 | /* | ||
68 | * Get date values | ||
69 | */ | ||
70 | #define SUNXI_DATE_GET_DAY_VALUE(x) SUNXI_GET(x, SUNXI_MASK_DH, 0) | ||
71 | #define SUNXI_DATE_GET_MON_VALUE(x) SUNXI_GET(x, SUNXI_MASK_M, 8) | ||
72 | #define SUNXI_DATE_GET_YEAR_VALUE(x, mask) SUNXI_GET(x, mask, 16) | ||
73 | |||
74 | /* | ||
75 | * Get time values | ||
76 | */ | ||
77 | #define SUNXI_TIME_GET_SEC_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 0) | ||
78 | #define SUNXI_TIME_GET_MIN_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 8) | ||
79 | #define SUNXI_TIME_GET_HOUR_VALUE(x) SUNXI_GET(x, SUNXI_MASK_DH, 16) | ||
80 | |||
81 | /* | ||
82 | * Get alarm values | ||
83 | */ | ||
84 | #define SUNXI_ALRM_GET_SEC_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 0) | ||
85 | #define SUNXI_ALRM_GET_MIN_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 8) | ||
86 | #define SUNXI_ALRM_GET_HOUR_VALUE(x) SUNXI_GET(x, SUNXI_MASK_DH, 16) | ||
87 | |||
88 | /* | ||
89 | * Set date values | ||
90 | */ | ||
91 | #define SUNXI_DATE_SET_DAY_VALUE(x) SUNXI_DATE_GET_DAY_VALUE(x) | ||
92 | #define SUNXI_DATE_SET_MON_VALUE(x) SUNXI_SET(x, SUNXI_MASK_M, 8) | ||
93 | #define SUNXI_DATE_SET_YEAR_VALUE(x, mask) SUNXI_SET(x, mask, 16) | ||
94 | #define SUNXI_LEAP_SET_VALUE(x, shift) SUNXI_SET(x, SUNXI_MASK_LY, shift) | ||
95 | |||
96 | /* | ||
97 | * Set time values | ||
98 | */ | ||
99 | #define SUNXI_TIME_SET_SEC_VALUE(x) SUNXI_TIME_GET_SEC_VALUE(x) | ||
100 | #define SUNXI_TIME_SET_MIN_VALUE(x) SUNXI_SET(x, SUNXI_MASK_SM, 8) | ||
101 | #define SUNXI_TIME_SET_HOUR_VALUE(x) SUNXI_SET(x, SUNXI_MASK_DH, 16) | ||
102 | |||
103 | /* | ||
104 | * Set alarm values | ||
105 | */ | ||
106 | #define SUNXI_ALRM_SET_SEC_VALUE(x) SUNXI_ALRM_GET_SEC_VALUE(x) | ||
107 | #define SUNXI_ALRM_SET_MIN_VALUE(x) SUNXI_SET(x, SUNXI_MASK_SM, 8) | ||
108 | #define SUNXI_ALRM_SET_HOUR_VALUE(x) SUNXI_SET(x, SUNXI_MASK_DH, 16) | ||
109 | #define SUNXI_ALRM_SET_DAY_VALUE(x) SUNXI_SET(x, SUNXI_MASK_D, 21) | ||
110 | |||
111 | /* | ||
112 | * Time unit conversions | ||
113 | */ | ||
114 | #define SEC_IN_MIN 60 | ||
115 | #define SEC_IN_HOUR (60 * SEC_IN_MIN) | ||
116 | #define SEC_IN_DAY (24 * SEC_IN_HOUR) | ||
117 | |||
118 | /* | ||
119 | * The year parameter passed to the driver is usually an offset relative to | ||
120 | * the year 1900. This macro is used to convert this offset to another one | ||
121 | * relative to the minimum year allowed by the hardware. | ||
122 | */ | ||
123 | #define SUNXI_YEAR_OFF(x) ((x)->min - 1900) | ||
124 | |||
125 | /* | ||
126 | * min and max year are arbitrary set considering the limited range of the | ||
127 | * hardware register field | ||
128 | */ | ||
129 | struct sunxi_rtc_data_year { | ||
130 | unsigned int min; /* min year allowed */ | ||
131 | unsigned int max; /* max year allowed */ | ||
132 | unsigned int mask; /* mask for the year field */ | ||
133 | unsigned char leap_shift; /* bit shift to get the leap year */ | ||
134 | }; | ||
135 | |||
136 | static struct sunxi_rtc_data_year data_year_param[] = { | ||
137 | [0] = { | ||
138 | .min = 2010, | ||
139 | .max = 2073, | ||
140 | .mask = 0x3f, | ||
141 | .leap_shift = 22, | ||
142 | }, | ||
143 | [1] = { | ||
144 | .min = 1970, | ||
145 | .max = 2225, | ||
146 | .mask = 0xff, | ||
147 | .leap_shift = 24, | ||
148 | }, | ||
149 | }; | ||
150 | |||
151 | struct sunxi_rtc_dev { | ||
152 | struct rtc_device *rtc; | ||
153 | struct device *dev; | ||
154 | struct sunxi_rtc_data_year *data_year; | ||
155 | void __iomem *base; | ||
156 | int irq; | ||
157 | }; | ||
158 | |||
159 | static irqreturn_t sunxi_rtc_alarmirq(int irq, void *id) | ||
160 | { | ||
161 | struct sunxi_rtc_dev *chip = (struct sunxi_rtc_dev *) id; | ||
162 | u32 val; | ||
163 | |||
164 | val = readl(chip->base + SUNXI_ALRM_IRQ_STA); | ||
165 | |||
166 | if (val & SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND) { | ||
167 | val |= SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND; | ||
168 | writel(val, chip->base + SUNXI_ALRM_IRQ_STA); | ||
169 | |||
170 | rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF); | ||
171 | |||
172 | return IRQ_HANDLED; | ||
173 | } | ||
174 | |||
175 | return IRQ_NONE; | ||
176 | } | ||
177 | |||
178 | static void sunxi_rtc_setaie(int to, struct sunxi_rtc_dev *chip) | ||
179 | { | ||
180 | u32 alrm_val = 0; | ||
181 | u32 alrm_irq_val = 0; | ||
182 | |||
183 | if (to) { | ||
184 | alrm_val = readl(chip->base + SUNXI_ALRM_EN); | ||
185 | alrm_val |= SUNXI_ALRM_EN_CNT_EN; | ||
186 | |||
187 | alrm_irq_val = readl(chip->base + SUNXI_ALRM_IRQ_EN); | ||
188 | alrm_irq_val |= SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN; | ||
189 | } else { | ||
190 | writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND, | ||
191 | chip->base + SUNXI_ALRM_IRQ_STA); | ||
192 | } | ||
193 | |||
194 | writel(alrm_val, chip->base + SUNXI_ALRM_EN); | ||
195 | writel(alrm_irq_val, chip->base + SUNXI_ALRM_IRQ_EN); | ||
196 | } | ||
197 | |||
198 | static int sunxi_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm) | ||
199 | { | ||
200 | struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); | ||
201 | struct rtc_time *alrm_tm = &wkalrm->time; | ||
202 | u32 alrm; | ||
203 | u32 alrm_en; | ||
204 | u32 date; | ||
205 | |||
206 | alrm = readl(chip->base + SUNXI_ALRM_DHMS); | ||
207 | date = readl(chip->base + SUNXI_RTC_YMD); | ||
208 | |||
209 | alrm_tm->tm_sec = SUNXI_ALRM_GET_SEC_VALUE(alrm); | ||
210 | alrm_tm->tm_min = SUNXI_ALRM_GET_MIN_VALUE(alrm); | ||
211 | alrm_tm->tm_hour = SUNXI_ALRM_GET_HOUR_VALUE(alrm); | ||
212 | |||
213 | alrm_tm->tm_mday = SUNXI_DATE_GET_DAY_VALUE(date); | ||
214 | alrm_tm->tm_mon = SUNXI_DATE_GET_MON_VALUE(date); | ||
215 | alrm_tm->tm_year = SUNXI_DATE_GET_YEAR_VALUE(date, | ||
216 | chip->data_year->mask); | ||
217 | |||
218 | alrm_tm->tm_mon -= 1; | ||
219 | |||
220 | /* | ||
221 | * switch from (data_year->min)-relative offset to | ||
222 | * a (1900)-relative one | ||
223 | */ | ||
224 | alrm_tm->tm_year += SUNXI_YEAR_OFF(chip->data_year); | ||
225 | |||
226 | alrm_en = readl(chip->base + SUNXI_ALRM_IRQ_EN); | ||
227 | if (alrm_en & SUNXI_ALRM_EN_CNT_EN) | ||
228 | wkalrm->enabled = 1; | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static int sunxi_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | ||
234 | { | ||
235 | struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); | ||
236 | u32 date, time; | ||
237 | |||
238 | /* | ||
239 | * read again in case it changes | ||
240 | */ | ||
241 | do { | ||
242 | date = readl(chip->base + SUNXI_RTC_YMD); | ||
243 | time = readl(chip->base + SUNXI_RTC_HMS); | ||
244 | } while ((date != readl(chip->base + SUNXI_RTC_YMD)) || | ||
245 | (time != readl(chip->base + SUNXI_RTC_HMS))); | ||
246 | |||
247 | rtc_tm->tm_sec = SUNXI_TIME_GET_SEC_VALUE(time); | ||
248 | rtc_tm->tm_min = SUNXI_TIME_GET_MIN_VALUE(time); | ||
249 | rtc_tm->tm_hour = SUNXI_TIME_GET_HOUR_VALUE(time); | ||
250 | |||
251 | rtc_tm->tm_mday = SUNXI_DATE_GET_DAY_VALUE(date); | ||
252 | rtc_tm->tm_mon = SUNXI_DATE_GET_MON_VALUE(date); | ||
253 | rtc_tm->tm_year = SUNXI_DATE_GET_YEAR_VALUE(date, | ||
254 | chip->data_year->mask); | ||
255 | |||
256 | rtc_tm->tm_mon -= 1; | ||
257 | |||
258 | /* | ||
259 | * switch from (data_year->min)-relative offset to | ||
260 | * a (1900)-relative one | ||
261 | */ | ||
262 | rtc_tm->tm_year += SUNXI_YEAR_OFF(chip->data_year); | ||
263 | |||
264 | return rtc_valid_tm(rtc_tm); | ||
265 | } | ||
266 | |||
267 | static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm) | ||
268 | { | ||
269 | struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); | ||
270 | struct rtc_time *alrm_tm = &wkalrm->time; | ||
271 | struct rtc_time tm_now; | ||
272 | u32 alrm = 0; | ||
273 | unsigned long time_now = 0; | ||
274 | unsigned long time_set = 0; | ||
275 | unsigned long time_gap = 0; | ||
276 | unsigned long time_gap_day = 0; | ||
277 | unsigned long time_gap_hour = 0; | ||
278 | unsigned long time_gap_min = 0; | ||
279 | int ret = 0; | ||
280 | |||
281 | ret = sunxi_rtc_gettime(dev, &tm_now); | ||
282 | if (ret < 0) { | ||
283 | dev_err(dev, "Error in getting time\n"); | ||
284 | return -EINVAL; | ||
285 | } | ||
286 | |||
287 | rtc_tm_to_time(alrm_tm, &time_set); | ||
288 | rtc_tm_to_time(&tm_now, &time_now); | ||
289 | if (time_set <= time_now) { | ||
290 | dev_err(dev, "Date to set in the past\n"); | ||
291 | return -EINVAL; | ||
292 | } | ||
293 | |||
294 | time_gap = time_set - time_now; | ||
295 | time_gap_day = time_gap / SEC_IN_DAY; | ||
296 | time_gap -= time_gap_day * SEC_IN_DAY; | ||
297 | time_gap_hour = time_gap / SEC_IN_HOUR; | ||
298 | time_gap -= time_gap_hour * SEC_IN_HOUR; | ||
299 | time_gap_min = time_gap / SEC_IN_MIN; | ||
300 | time_gap -= time_gap_min * SEC_IN_MIN; | ||
301 | |||
302 | if (time_gap_day > 255) { | ||
303 | dev_err(dev, "Day must be in the range 0 - 255\n"); | ||
304 | return -EINVAL; | ||
305 | } | ||
306 | |||
307 | sunxi_rtc_setaie(0, chip); | ||
308 | writel(0, chip->base + SUNXI_ALRM_DHMS); | ||
309 | usleep_range(100, 300); | ||
310 | |||
311 | alrm = SUNXI_ALRM_SET_SEC_VALUE(time_gap) | | ||
312 | SUNXI_ALRM_SET_MIN_VALUE(time_gap_min) | | ||
313 | SUNXI_ALRM_SET_HOUR_VALUE(time_gap_hour) | | ||
314 | SUNXI_ALRM_SET_DAY_VALUE(time_gap_day); | ||
315 | writel(alrm, chip->base + SUNXI_ALRM_DHMS); | ||
316 | |||
317 | writel(0, chip->base + SUNXI_ALRM_IRQ_EN); | ||
318 | writel(SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN, chip->base + SUNXI_ALRM_IRQ_EN); | ||
319 | |||
320 | sunxi_rtc_setaie(wkalrm->enabled, chip); | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int sunxi_rtc_wait(struct sunxi_rtc_dev *chip, int offset, | ||
326 | unsigned int mask, unsigned int ms_timeout) | ||
327 | { | ||
328 | const unsigned long timeout = jiffies + msecs_to_jiffies(ms_timeout); | ||
329 | u32 reg; | ||
330 | |||
331 | do { | ||
332 | reg = readl(chip->base + offset); | ||
333 | reg &= mask; | ||
334 | |||
335 | if (reg == mask) | ||
336 | return 0; | ||
337 | |||
338 | } while (time_before(jiffies, timeout)); | ||
339 | |||
340 | return -ETIMEDOUT; | ||
341 | } | ||
342 | |||
343 | static int sunxi_rtc_settime(struct device *dev, struct rtc_time *rtc_tm) | ||
344 | { | ||
345 | struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); | ||
346 | u32 date = 0; | ||
347 | u32 time = 0; | ||
348 | int year; | ||
349 | |||
350 | /* | ||
351 | * the input rtc_tm->tm_year is the offset relative to 1900. We use | ||
352 | * the SUNXI_YEAR_OFF macro to rebase it with respect to the min year | ||
353 | * allowed by the hardware | ||
354 | */ | ||
355 | |||
356 | year = rtc_tm->tm_year + 1900; | ||
357 | if (year < chip->data_year->min || year > chip->data_year->max) { | ||
358 | dev_err(dev, "rtc only supports year in range %d - %d\n", | ||
359 | chip->data_year->min, chip->data_year->max); | ||
360 | return -EINVAL; | ||
361 | } | ||
362 | |||
363 | rtc_tm->tm_year -= SUNXI_YEAR_OFF(chip->data_year); | ||
364 | rtc_tm->tm_mon += 1; | ||
365 | |||
366 | date = SUNXI_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) | | ||
367 | SUNXI_DATE_SET_MON_VALUE(rtc_tm->tm_mon) | | ||
368 | SUNXI_DATE_SET_YEAR_VALUE(rtc_tm->tm_year, | ||
369 | chip->data_year->mask); | ||
370 | |||
371 | if (is_leap_year(year)) | ||
372 | date |= SUNXI_LEAP_SET_VALUE(1, chip->data_year->leap_shift); | ||
373 | |||
374 | time = SUNXI_TIME_SET_SEC_VALUE(rtc_tm->tm_sec) | | ||
375 | SUNXI_TIME_SET_MIN_VALUE(rtc_tm->tm_min) | | ||
376 | SUNXI_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour); | ||
377 | |||
378 | writel(0, chip->base + SUNXI_RTC_HMS); | ||
379 | writel(0, chip->base + SUNXI_RTC_YMD); | ||
380 | |||
381 | writel(time, chip->base + SUNXI_RTC_HMS); | ||
382 | |||
383 | /* | ||
384 | * After writing the RTC HH-MM-SS register, the | ||
385 | * SUNXI_LOSC_CTRL_RTC_HMS_ACC bit is set and it will not | ||
386 | * be cleared until the real writing operation is finished | ||
387 | */ | ||
388 | |||
389 | if (sunxi_rtc_wait(chip, SUNXI_LOSC_CTRL, | ||
390 | SUNXI_LOSC_CTRL_RTC_HMS_ACC, 50)) { | ||
391 | dev_err(dev, "Failed to set rtc time.\n"); | ||
392 | return -1; | ||
393 | } | ||
394 | |||
395 | writel(date, chip->base + SUNXI_RTC_YMD); | ||
396 | |||
397 | /* | ||
398 | * After writing the RTC YY-MM-DD register, the | ||
399 | * SUNXI_LOSC_CTRL_RTC_YMD_ACC bit is set and it will not | ||
400 | * be cleared until the real writing operation is finished | ||
401 | */ | ||
402 | |||
403 | if (sunxi_rtc_wait(chip, SUNXI_LOSC_CTRL, | ||
404 | SUNXI_LOSC_CTRL_RTC_YMD_ACC, 50)) { | ||
405 | dev_err(dev, "Failed to set rtc time.\n"); | ||
406 | return -1; | ||
407 | } | ||
408 | |||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | static int sunxi_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
413 | { | ||
414 | struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); | ||
415 | |||
416 | if (!enabled) | ||
417 | sunxi_rtc_setaie(enabled, chip); | ||
418 | |||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | static const struct rtc_class_ops sunxi_rtc_ops = { | ||
423 | .read_time = sunxi_rtc_gettime, | ||
424 | .set_time = sunxi_rtc_settime, | ||
425 | .read_alarm = sunxi_rtc_getalarm, | ||
426 | .set_alarm = sunxi_rtc_setalarm, | ||
427 | .alarm_irq_enable = sunxi_rtc_alarm_irq_enable | ||
428 | }; | ||
429 | |||
430 | static const struct of_device_id sunxi_rtc_dt_ids[] = { | ||
431 | { .compatible = "allwinner,sun4i-rtc", .data = &data_year_param[0] }, | ||
432 | { .compatible = "allwinner,sun7i-a20-rtc", .data = &data_year_param[1] }, | ||
433 | { /* sentinel */ }, | ||
434 | }; | ||
435 | MODULE_DEVICE_TABLE(of, sunxi_rtc_dt_ids); | ||
436 | |||
437 | static int sunxi_rtc_probe(struct platform_device *pdev) | ||
438 | { | ||
439 | struct sunxi_rtc_dev *chip; | ||
440 | struct resource *res; | ||
441 | const struct of_device_id *of_id; | ||
442 | int ret; | ||
443 | |||
444 | chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); | ||
445 | if (!chip) | ||
446 | return -ENOMEM; | ||
447 | |||
448 | platform_set_drvdata(pdev, chip); | ||
449 | chip->dev = &pdev->dev; | ||
450 | |||
451 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
452 | chip->base = devm_ioremap_resource(&pdev->dev, res); | ||
453 | if (IS_ERR(chip->base)) | ||
454 | return PTR_ERR(chip->base); | ||
455 | |||
456 | chip->irq = platform_get_irq(pdev, 0); | ||
457 | if (chip->irq < 0) { | ||
458 | dev_err(&pdev->dev, "No IRQ resource\n"); | ||
459 | return chip->irq; | ||
460 | } | ||
461 | ret = devm_request_irq(&pdev->dev, chip->irq, sunxi_rtc_alarmirq, | ||
462 | 0, dev_name(&pdev->dev), chip); | ||
463 | if (ret) { | ||
464 | dev_err(&pdev->dev, "Could not request IRQ\n"); | ||
465 | return ret; | ||
466 | } | ||
467 | |||
468 | of_id = of_match_device(sunxi_rtc_dt_ids, &pdev->dev); | ||
469 | if (!of_id) { | ||
470 | dev_err(&pdev->dev, "Unable to setup RTC data\n"); | ||
471 | return -ENODEV; | ||
472 | } | ||
473 | chip->data_year = (struct sunxi_rtc_data_year *) of_id->data; | ||
474 | |||
475 | /* clear the alarm count value */ | ||
476 | writel(0, chip->base + SUNXI_ALRM_DHMS); | ||
477 | |||
478 | /* disable alarm, not generate irq pending */ | ||
479 | writel(0, chip->base + SUNXI_ALRM_EN); | ||
480 | |||
481 | /* disable alarm week/cnt irq, unset to cpu */ | ||
482 | writel(0, chip->base + SUNXI_ALRM_IRQ_EN); | ||
483 | |||
484 | /* clear alarm week/cnt irq pending */ | ||
485 | writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND, chip->base + | ||
486 | SUNXI_ALRM_IRQ_STA); | ||
487 | |||
488 | chip->rtc = rtc_device_register("rtc-sunxi", &pdev->dev, | ||
489 | &sunxi_rtc_ops, THIS_MODULE); | ||
490 | if (IS_ERR(chip->rtc)) { | ||
491 | dev_err(&pdev->dev, "unable to register device\n"); | ||
492 | return PTR_ERR(chip->rtc); | ||
493 | } | ||
494 | |||
495 | dev_info(&pdev->dev, "RTC enabled\n"); | ||
496 | |||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | static int sunxi_rtc_remove(struct platform_device *pdev) | ||
501 | { | ||
502 | struct sunxi_rtc_dev *chip = platform_get_drvdata(pdev); | ||
503 | |||
504 | rtc_device_unregister(chip->rtc); | ||
505 | |||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | static struct platform_driver sunxi_rtc_driver = { | ||
510 | .probe = sunxi_rtc_probe, | ||
511 | .remove = sunxi_rtc_remove, | ||
512 | .driver = { | ||
513 | .name = "sunxi-rtc", | ||
514 | .owner = THIS_MODULE, | ||
515 | .of_match_table = sunxi_rtc_dt_ids, | ||
516 | }, | ||
517 | }; | ||
518 | |||
519 | module_platform_driver(sunxi_rtc_driver); | ||
520 | |||
521 | MODULE_DESCRIPTION("sunxi RTC driver"); | ||
522 | MODULE_AUTHOR("Carlo Caione <carlo.caione@gmail.com>"); | ||
523 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 441ada489874..a3815eaed421 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -1034,7 +1034,7 @@ config SERIAL_MSM_CONSOLE | |||
1034 | 1034 | ||
1035 | config SERIAL_MSM_HS | 1035 | config SERIAL_MSM_HS |
1036 | tristate "MSM UART High Speed: Serial Driver" | 1036 | tristate "MSM UART High Speed: Serial Driver" |
1037 | depends on ARCH_MSM | 1037 | depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 |
1038 | select SERIAL_CORE | 1038 | select SERIAL_CORE |
1039 | help | 1039 | help |
1040 | If you have a machine based on MSM family of SoCs, you | 1040 | If you have a machine based on MSM family of SoCs, you |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index e4bf0e435af6..be33d2b0613b 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <linux/mm.h> | 40 | #include <linux/mm.h> |
41 | #include <linux/notifier.h> | 41 | #include <linux/notifier.h> |
42 | #include <linux/of.h> | ||
42 | #include <linux/platform_device.h> | 43 | #include <linux/platform_device.h> |
43 | #include <linux/pm_runtime.h> | 44 | #include <linux/pm_runtime.h> |
44 | #include <linux/scatterlist.h> | 45 | #include <linux/scatterlist.h> |
@@ -58,6 +59,23 @@ | |||
58 | 59 | ||
59 | #include "sh-sci.h" | 60 | #include "sh-sci.h" |
60 | 61 | ||
62 | /* Offsets into the sci_port->irqs array */ | ||
63 | enum { | ||
64 | SCIx_ERI_IRQ, | ||
65 | SCIx_RXI_IRQ, | ||
66 | SCIx_TXI_IRQ, | ||
67 | SCIx_BRI_IRQ, | ||
68 | SCIx_NR_IRQS, | ||
69 | |||
70 | SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */ | ||
71 | }; | ||
72 | |||
73 | #define SCIx_IRQ_IS_MUXED(port) \ | ||
74 | ((port)->irqs[SCIx_ERI_IRQ] == \ | ||
75 | (port)->irqs[SCIx_RXI_IRQ]) || \ | ||
76 | ((port)->irqs[SCIx_ERI_IRQ] && \ | ||
77 | ((port)->irqs[SCIx_RXI_IRQ] < 0)) | ||
78 | |||
61 | struct sci_port { | 79 | struct sci_port { |
62 | struct uart_port port; | 80 | struct uart_port port; |
63 | 81 | ||
@@ -1757,17 +1775,6 @@ static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, | |||
1757 | if (s->sampling_rate) | 1775 | if (s->sampling_rate) |
1758 | return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1; | 1776 | return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1; |
1759 | 1777 | ||
1760 | switch (s->cfg->scbrr_algo_id) { | ||
1761 | case SCBRR_ALGO_1: | ||
1762 | return freq / (16 * bps); | ||
1763 | case SCBRR_ALGO_2: | ||
1764 | return DIV_ROUND_CLOSEST(freq, 32 * bps) - 1; | ||
1765 | case SCBRR_ALGO_3: | ||
1766 | return freq / (8 * bps); | ||
1767 | case SCBRR_ALGO_4: | ||
1768 | return DIV_ROUND_CLOSEST(freq, 16 * bps) - 1; | ||
1769 | } | ||
1770 | |||
1771 | /* Warn, but use a safe default */ | 1778 | /* Warn, but use a safe default */ |
1772 | WARN_ON(1); | 1779 | WARN_ON(1); |
1773 | 1780 | ||
@@ -2105,36 +2112,27 @@ static int sci_init_single(struct platform_device *dev, | |||
2105 | port->iotype = UPIO_MEM; | 2112 | port->iotype = UPIO_MEM; |
2106 | port->line = index; | 2113 | port->line = index; |
2107 | 2114 | ||
2108 | if (dev->num_resources) { | 2115 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
2109 | /* Device has resources, use them. */ | 2116 | if (res == NULL) |
2110 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | 2117 | return -ENOMEM; |
2111 | if (res == NULL) | ||
2112 | return -ENOMEM; | ||
2113 | 2118 | ||
2114 | port->mapbase = res->start; | 2119 | port->mapbase = res->start; |
2115 | 2120 | ||
2116 | for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) | 2121 | for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) |
2117 | sci_port->irqs[i] = platform_get_irq(dev, i); | 2122 | sci_port->irqs[i] = platform_get_irq(dev, i); |
2118 | 2123 | ||
2119 | /* The SCI generates several interrupts. They can be muxed | 2124 | /* The SCI generates several interrupts. They can be muxed together or |
2120 | * together or connected to different interrupt lines. In the | 2125 | * connected to different interrupt lines. In the muxed case only one |
2121 | * muxed case only one interrupt resource is specified. In the | 2126 | * interrupt resource is specified. In the non-muxed case three or four |
2122 | * non-muxed case three or four interrupt resources are | 2127 | * interrupt resources are specified, as the BRI interrupt is optional. |
2123 | * specified, as the BRI interrupt is optional. | 2128 | */ |
2124 | */ | 2129 | if (sci_port->irqs[0] < 0) |
2125 | if (sci_port->irqs[0] < 0) | 2130 | return -ENXIO; |
2126 | return -ENXIO; | ||
2127 | 2131 | ||
2128 | if (sci_port->irqs[1] < 0) { | 2132 | if (sci_port->irqs[1] < 0) { |
2129 | sci_port->irqs[1] = sci_port->irqs[0]; | 2133 | sci_port->irqs[1] = sci_port->irqs[0]; |
2130 | sci_port->irqs[2] = sci_port->irqs[0]; | 2134 | sci_port->irqs[2] = sci_port->irqs[0]; |
2131 | sci_port->irqs[3] = sci_port->irqs[0]; | 2135 | sci_port->irqs[3] = sci_port->irqs[0]; |
2132 | } | ||
2133 | } else { | ||
2134 | /* No resources, use old-style platform data. */ | ||
2135 | port->mapbase = p->mapbase; | ||
2136 | for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) | ||
2137 | sci_port->irqs[i] = p->irqs[i] ? p->irqs[i] : -ENXIO; | ||
2138 | } | 2136 | } |
2139 | 2137 | ||
2140 | if (p->regtype == SCIx_PROBE_REGTYPE) { | 2138 | if (p->regtype == SCIx_PROBE_REGTYPE) { |
@@ -2176,17 +2174,12 @@ static int sci_init_single(struct platform_device *dev, | |||
2176 | break; | 2174 | break; |
2177 | } | 2175 | } |
2178 | 2176 | ||
2179 | /* Set the sampling rate if the baud rate calculation algorithm isn't | 2177 | /* SCIFA on sh7723 and sh7724 need a custom sampling rate that doesn't |
2180 | * specified. | 2178 | * match the SoC datasheet, this should be investigated. Let platform |
2179 | * data override the sampling rate for now. | ||
2181 | */ | 2180 | */ |
2182 | if (p->scbrr_algo_id == SCBRR_ALGO_NONE) { | 2181 | sci_port->sampling_rate = p->sampling_rate ? p->sampling_rate |
2183 | /* SCIFA on sh7723 and sh7724 need a custom sampling rate that | 2182 | : sampling_rate; |
2184 | * doesn't match the SoC datasheet, this should be investigated. | ||
2185 | * Let platform data override the sampling rate for now. | ||
2186 | */ | ||
2187 | sci_port->sampling_rate = p->sampling_rate ? p->sampling_rate | ||
2188 | : sampling_rate; | ||
2189 | } | ||
2190 | 2183 | ||
2191 | if (!early) { | 2184 | if (!early) { |
2192 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); | 2185 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); |
@@ -2423,6 +2416,83 @@ static int sci_remove(struct platform_device *dev) | |||
2423 | return 0; | 2416 | return 0; |
2424 | } | 2417 | } |
2425 | 2418 | ||
2419 | struct sci_port_info { | ||
2420 | unsigned int type; | ||
2421 | unsigned int regtype; | ||
2422 | }; | ||
2423 | |||
2424 | static const struct of_device_id of_sci_match[] = { | ||
2425 | { | ||
2426 | .compatible = "renesas,scif", | ||
2427 | .data = (void *)&(const struct sci_port_info) { | ||
2428 | .type = PORT_SCIF, | ||
2429 | .regtype = SCIx_SH4_SCIF_REGTYPE, | ||
2430 | }, | ||
2431 | }, { | ||
2432 | .compatible = "renesas,scifa", | ||
2433 | .data = (void *)&(const struct sci_port_info) { | ||
2434 | .type = PORT_SCIFA, | ||
2435 | .regtype = SCIx_SCIFA_REGTYPE, | ||
2436 | }, | ||
2437 | }, { | ||
2438 | .compatible = "renesas,scifb", | ||
2439 | .data = (void *)&(const struct sci_port_info) { | ||
2440 | .type = PORT_SCIFB, | ||
2441 | .regtype = SCIx_SCIFB_REGTYPE, | ||
2442 | }, | ||
2443 | }, { | ||
2444 | .compatible = "renesas,hscif", | ||
2445 | .data = (void *)&(const struct sci_port_info) { | ||
2446 | .type = PORT_HSCIF, | ||
2447 | .regtype = SCIx_HSCIF_REGTYPE, | ||
2448 | }, | ||
2449 | }, { | ||
2450 | /* Terminator */ | ||
2451 | }, | ||
2452 | }; | ||
2453 | MODULE_DEVICE_TABLE(of, of_sci_match); | ||
2454 | |||
2455 | static struct plat_sci_port * | ||
2456 | sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) | ||
2457 | { | ||
2458 | struct device_node *np = pdev->dev.of_node; | ||
2459 | const struct of_device_id *match; | ||
2460 | const struct sci_port_info *info; | ||
2461 | struct plat_sci_port *p; | ||
2462 | int id; | ||
2463 | |||
2464 | if (!IS_ENABLED(CONFIG_OF) || !np) | ||
2465 | return NULL; | ||
2466 | |||
2467 | match = of_match_node(of_sci_match, pdev->dev.of_node); | ||
2468 | if (!match) | ||
2469 | return NULL; | ||
2470 | |||
2471 | info = match->data; | ||
2472 | |||
2473 | p = devm_kzalloc(&pdev->dev, sizeof(struct plat_sci_port), GFP_KERNEL); | ||
2474 | if (!p) { | ||
2475 | dev_err(&pdev->dev, "failed to allocate DT config data\n"); | ||
2476 | return NULL; | ||
2477 | } | ||
2478 | |||
2479 | /* Get the line number for the aliases node. */ | ||
2480 | id = of_alias_get_id(np, "serial"); | ||
2481 | if (id < 0) { | ||
2482 | dev_err(&pdev->dev, "failed to get alias id (%d)\n", id); | ||
2483 | return NULL; | ||
2484 | } | ||
2485 | |||
2486 | *dev_id = id; | ||
2487 | |||
2488 | p->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; | ||
2489 | p->type = info->type; | ||
2490 | p->regtype = info->regtype; | ||
2491 | p->scscr = SCSCR_RE | SCSCR_TE; | ||
2492 | |||
2493 | return p; | ||
2494 | } | ||
2495 | |||
2426 | static int sci_probe_single(struct platform_device *dev, | 2496 | static int sci_probe_single(struct platform_device *dev, |
2427 | unsigned int index, | 2497 | unsigned int index, |
2428 | struct plat_sci_port *p, | 2498 | struct plat_sci_port *p, |
@@ -2455,8 +2525,9 @@ static int sci_probe_single(struct platform_device *dev, | |||
2455 | 2525 | ||
2456 | static int sci_probe(struct platform_device *dev) | 2526 | static int sci_probe(struct platform_device *dev) |
2457 | { | 2527 | { |
2458 | struct plat_sci_port *p = dev_get_platdata(&dev->dev); | 2528 | struct plat_sci_port *p; |
2459 | struct sci_port *sp = &sci_ports[dev->id]; | 2529 | struct sci_port *sp; |
2530 | unsigned int dev_id; | ||
2460 | int ret; | 2531 | int ret; |
2461 | 2532 | ||
2462 | /* | 2533 | /* |
@@ -2467,9 +2538,24 @@ static int sci_probe(struct platform_device *dev) | |||
2467 | if (is_early_platform_device(dev)) | 2538 | if (is_early_platform_device(dev)) |
2468 | return sci_probe_earlyprintk(dev); | 2539 | return sci_probe_earlyprintk(dev); |
2469 | 2540 | ||
2541 | if (dev->dev.of_node) { | ||
2542 | p = sci_parse_dt(dev, &dev_id); | ||
2543 | if (p == NULL) | ||
2544 | return -EINVAL; | ||
2545 | } else { | ||
2546 | p = dev->dev.platform_data; | ||
2547 | if (p == NULL) { | ||
2548 | dev_err(&dev->dev, "no platform data supplied\n"); | ||
2549 | return -EINVAL; | ||
2550 | } | ||
2551 | |||
2552 | dev_id = dev->id; | ||
2553 | } | ||
2554 | |||
2555 | sp = &sci_ports[dev_id]; | ||
2470 | platform_set_drvdata(dev, sp); | 2556 | platform_set_drvdata(dev, sp); |
2471 | 2557 | ||
2472 | ret = sci_probe_single(dev, dev->id, p, sp); | 2558 | ret = sci_probe_single(dev, dev_id, p, sp); |
2473 | if (ret) | 2559 | if (ret) |
2474 | return ret; | 2560 | return ret; |
2475 | 2561 | ||
@@ -2521,6 +2607,7 @@ static struct platform_driver sci_driver = { | |||
2521 | .name = "sh-sci", | 2607 | .name = "sh-sci", |
2522 | .owner = THIS_MODULE, | 2608 | .owner = THIS_MODULE, |
2523 | .pm = &sci_dev_pm_ops, | 2609 | .pm = &sci_dev_pm_ops, |
2610 | .of_match_table = of_match_ptr(of_sci_match), | ||
2524 | }, | 2611 | }, |
2525 | }; | 2612 | }; |
2526 | 2613 | ||
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index c6c325e4d80d..110b4b9ebeaa 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -94,7 +94,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) | |||
94 | int i = 0; | 94 | int i = 0; |
95 | 95 | ||
96 | if (r8a66597->pdata->on_chip) { | 96 | if (r8a66597->pdata->on_chip) { |
97 | clk_enable(r8a66597->clk); | 97 | clk_prepare_enable(r8a66597->clk); |
98 | do { | 98 | do { |
99 | r8a66597_write(r8a66597, SCKE, SYSCFG0); | 99 | r8a66597_write(r8a66597, SCKE, SYSCFG0); |
100 | tmp = r8a66597_read(r8a66597, SYSCFG0); | 100 | tmp = r8a66597_read(r8a66597, SYSCFG0); |
@@ -138,7 +138,7 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597) | |||
138 | udelay(1); | 138 | udelay(1); |
139 | 139 | ||
140 | if (r8a66597->pdata->on_chip) { | 140 | if (r8a66597->pdata->on_chip) { |
141 | clk_disable(r8a66597->clk); | 141 | clk_disable_unprepare(r8a66597->clk); |
142 | } else { | 142 | } else { |
143 | r8a66597_bclr(r8a66597, PLLC, SYSCFG0); | 143 | r8a66597_bclr(r8a66597, PLLC, SYSCFG0); |
144 | r8a66597_bclr(r8a66597, XCKE, SYSCFG0); | 144 | r8a66597_bclr(r8a66597, XCKE, SYSCFG0); |
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 37752832b770..8546c8dccd51 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c | |||
@@ -40,8 +40,6 @@ | |||
40 | #include <linux/usb/msm_hsusb_hw.h> | 40 | #include <linux/usb/msm_hsusb_hw.h> |
41 | #include <linux/regulator/consumer.h> | 41 | #include <linux/regulator/consumer.h> |
42 | 42 | ||
43 | #include <mach/clk.h> | ||
44 | |||
45 | #define MSM_USB_BASE (motg->regs) | 43 | #define MSM_USB_BASE (motg->regs) |
46 | #define DRIVER_NAME "msm_otg" | 44 | #define DRIVER_NAME "msm_otg" |
47 | 45 | ||
@@ -308,33 +306,30 @@ static void ulpi_init(struct msm_otg *motg) | |||
308 | 306 | ||
309 | static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) | 307 | static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) |
310 | { | 308 | { |
311 | int ret; | 309 | int ret = 0; |
310 | |||
311 | if (!motg->pdata->link_clk_reset) | ||
312 | return ret; | ||
313 | |||
314 | ret = motg->pdata->link_clk_reset(motg->clk, assert); | ||
315 | if (ret) | ||
316 | dev_err(motg->phy.dev, "usb link clk reset %s failed\n", | ||
317 | assert ? "assert" : "deassert"); | ||
312 | 318 | ||
313 | if (assert) { | ||
314 | ret = clk_reset(motg->clk, CLK_RESET_ASSERT); | ||
315 | if (ret) | ||
316 | dev_err(motg->phy.dev, "usb hs_clk assert failed\n"); | ||
317 | } else { | ||
318 | ret = clk_reset(motg->clk, CLK_RESET_DEASSERT); | ||
319 | if (ret) | ||
320 | dev_err(motg->phy.dev, "usb hs_clk deassert failed\n"); | ||
321 | } | ||
322 | return ret; | 319 | return ret; |
323 | } | 320 | } |
324 | 321 | ||
325 | static int msm_otg_phy_clk_reset(struct msm_otg *motg) | 322 | static int msm_otg_phy_clk_reset(struct msm_otg *motg) |
326 | { | 323 | { |
327 | int ret; | 324 | int ret = 0; |
328 | 325 | ||
329 | ret = clk_reset(motg->phy_reset_clk, CLK_RESET_ASSERT); | 326 | if (!motg->pdata->phy_clk_reset) |
330 | if (ret) { | ||
331 | dev_err(motg->phy.dev, "usb phy clk assert failed\n"); | ||
332 | return ret; | 327 | return ret; |
333 | } | 328 | |
334 | usleep_range(10000, 12000); | 329 | ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk); |
335 | ret = clk_reset(motg->phy_reset_clk, CLK_RESET_DEASSERT); | ||
336 | if (ret) | 330 | if (ret) |
337 | dev_err(motg->phy.dev, "usb phy clk deassert failed\n"); | 331 | dev_err(motg->phy.dev, "usb phy clk reset failed\n"); |
332 | |||
338 | return ret; | 333 | return ret; |
339 | } | 334 | } |
340 | 335 | ||
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index dd625cca1ae5..12591f6596ef 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c | |||
@@ -247,7 +247,7 @@ MODULE_DEVICE_TABLE(of, davinci_wdt_of_match); | |||
247 | 247 | ||
248 | static struct platform_driver platform_wdt_driver = { | 248 | static struct platform_driver platform_wdt_driver = { |
249 | .driver = { | 249 | .driver = { |
250 | .name = "watchdog", | 250 | .name = "davinci-wdt", |
251 | .owner = THIS_MODULE, | 251 | .owner = THIS_MODULE, |
252 | .of_match_table = davinci_wdt_of_match, | 252 | .of_match_table = davinci_wdt_of_match, |
253 | }, | 253 | }, |
@@ -267,4 +267,4 @@ MODULE_PARM_DESC(heartbeat, | |||
267 | __MODULE_STRING(DEFAULT_HEARTBEAT)); | 267 | __MODULE_STRING(DEFAULT_HEARTBEAT)); |
268 | 268 | ||
269 | MODULE_LICENSE("GPL"); | 269 | MODULE_LICENSE("GPL"); |
270 | MODULE_ALIAS("platform:watchdog"); | 270 | MODULE_ALIAS("platform:davinci-wdt"); |