diff options
Diffstat (limited to 'drivers')
159 files changed, 7152 insertions, 1896 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 807a88a0f394..9d75ead2a1f9 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -1164,7 +1164,8 @@ static bool acpi_video_device_in_dod(struct acpi_video_device *device) | |||
1164 | return true; | 1164 | return true; |
1165 | 1165 | ||
1166 | for (i = 0; i < video->attached_count; i++) { | 1166 | for (i = 0; i < video->attached_count; i++) { |
1167 | if (video->attached_array[i].bind_info == device) | 1167 | if ((video->attached_array[i].value.int_val & 0xfff) == |
1168 | (device->device_id & 0xfff)) | ||
1168 | return true; | 1169 | return true; |
1169 | } | 1170 | } |
1170 | 1171 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e45f83789809..49f1e6890587 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -321,6 +321,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
321 | { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */ | 321 | { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */ |
322 | { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ | 322 | { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ |
323 | { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */ | 323 | { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */ |
324 | { PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */ | ||
325 | { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */ | ||
326 | { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */ | ||
324 | { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ | 327 | { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ |
325 | { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */ | 328 | { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */ |
326 | { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ | 329 | { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ |
@@ -492,6 +495,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
492 | * enabled. https://bugzilla.kernel.org/show_bug.cgi?id=60731 | 495 | * enabled. https://bugzilla.kernel.org/show_bug.cgi?id=60731 |
493 | */ | 496 | */ |
494 | { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi }, | 497 | { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi }, |
498 | { PCI_VDEVICE(SAMSUNG, 0xa800), board_ahci_nomsi }, | ||
495 | 499 | ||
496 | /* Enmotus */ | 500 | /* Enmotus */ |
497 | { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, | 501 | { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, |
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 07bc7e4dbd04..65071591b143 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c | |||
@@ -1488,7 +1488,7 @@ static int sata_fsl_probe(struct platform_device *ofdev) | |||
1488 | host_priv->csr_base = csr_base; | 1488 | host_priv->csr_base = csr_base; |
1489 | 1489 | ||
1490 | irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); | 1490 | irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); |
1491 | if (irq < 0) { | 1491 | if (!irq) { |
1492 | dev_err(&ofdev->dev, "invalid irq from platform\n"); | 1492 | dev_err(&ofdev->dev, "invalid irq from platform\n"); |
1493 | goto error_exit_with_cleanup; | 1493 | goto error_exit_with_cleanup; |
1494 | } | 1494 | } |
diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig index 8a3f51f7b1b9..db9d00c36a3e 100644 --- a/drivers/base/regmap/Kconfig +++ b/drivers/base/regmap/Kconfig | |||
@@ -3,12 +3,15 @@ | |||
3 | # subsystems should select the appropriate symbols. | 3 | # subsystems should select the appropriate symbols. |
4 | 4 | ||
5 | config REGMAP | 5 | config REGMAP |
6 | default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_MMIO || REGMAP_IRQ) | 6 | default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ) |
7 | select LZO_COMPRESS | 7 | select LZO_COMPRESS |
8 | select LZO_DECOMPRESS | 8 | select LZO_DECOMPRESS |
9 | select IRQ_DOMAIN if REGMAP_IRQ | 9 | select IRQ_DOMAIN if REGMAP_IRQ |
10 | bool | 10 | bool |
11 | 11 | ||
12 | config REGMAP_AC97 | ||
13 | tristate | ||
14 | |||
12 | config REGMAP_I2C | 15 | config REGMAP_I2C |
13 | tristate | 16 | tristate |
14 | depends on I2C | 17 | depends on I2C |
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile index a7c670b4123a..0a533653ef3b 100644 --- a/drivers/base/regmap/Makefile +++ b/drivers/base/regmap/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | obj-$(CONFIG_REGMAP) += regmap.o regcache.o | 1 | obj-$(CONFIG_REGMAP) += regmap.o regcache.o |
2 | obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o regcache-flat.o | 2 | obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o regcache-flat.o |
3 | obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o | 3 | obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o |
4 | obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o | ||
4 | obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o | 5 | obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o |
5 | obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o | 6 | obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o |
6 | obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o | 7 | obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o |
diff --git a/drivers/base/regmap/regcache-flat.c b/drivers/base/regmap/regcache-flat.c index d9762e41959b..0246f44ded74 100644 --- a/drivers/base/regmap/regcache-flat.c +++ b/drivers/base/regmap/regcache-flat.c | |||
@@ -10,9 +10,9 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/device.h> | 13 | #include <linux/device.h> |
15 | #include <linux/seq_file.h> | 14 | #include <linux/seq_file.h> |
15 | #include <linux/slab.h> | ||
16 | 16 | ||
17 | #include "internal.h" | 17 | #include "internal.h" |
18 | 18 | ||
diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regcache-lzo.c index e210a6d1406a..2d53f6f138e1 100644 --- a/drivers/base/regmap/regcache-lzo.c +++ b/drivers/base/regmap/regcache-lzo.c | |||
@@ -10,9 +10,9 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/device.h> | 13 | #include <linux/device.h> |
15 | #include <linux/lzo.h> | 14 | #include <linux/lzo.h> |
15 | #include <linux/slab.h> | ||
16 | 16 | ||
17 | #include "internal.h" | 17 | #include "internal.h" |
18 | 18 | ||
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index f3e8fe0cc650..d453a2c98ad0 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c | |||
@@ -10,11 +10,11 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/debugfs.h> | 13 | #include <linux/debugfs.h> |
14 | #include <linux/device.h> | ||
16 | #include <linux/rbtree.h> | 15 | #include <linux/rbtree.h> |
17 | #include <linux/seq_file.h> | 16 | #include <linux/seq_file.h> |
17 | #include <linux/slab.h> | ||
18 | 18 | ||
19 | #include "internal.h" | 19 | #include "internal.h" |
20 | 20 | ||
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index f1280dc356d0..f373c35f9e1d 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c | |||
@@ -10,12 +10,12 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/export.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <trace/events/regmap.h> | ||
17 | #include <linux/bsearch.h> | 13 | #include <linux/bsearch.h> |
14 | #include <linux/device.h> | ||
15 | #include <linux/export.h> | ||
16 | #include <linux/slab.h> | ||
18 | #include <linux/sort.h> | 17 | #include <linux/sort.h> |
18 | #include <trace/events/regmap.h> | ||
19 | 19 | ||
20 | #include "internal.h" | 20 | #include "internal.h" |
21 | 21 | ||
@@ -36,6 +36,23 @@ static int regcache_hw_init(struct regmap *map) | |||
36 | if (!map->num_reg_defaults_raw) | 36 | if (!map->num_reg_defaults_raw) |
37 | return -EINVAL; | 37 | return -EINVAL; |
38 | 38 | ||
39 | /* calculate the size of reg_defaults */ | ||
40 | for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) | ||
41 | if (!regmap_volatile(map, i * map->reg_stride)) | ||
42 | count++; | ||
43 | |||
44 | /* all registers are volatile, so just bypass */ | ||
45 | if (!count) { | ||
46 | map->cache_bypass = true; | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | map->num_reg_defaults = count; | ||
51 | map->reg_defaults = kmalloc_array(count, sizeof(struct reg_default), | ||
52 | GFP_KERNEL); | ||
53 | if (!map->reg_defaults) | ||
54 | return -ENOMEM; | ||
55 | |||
39 | if (!map->reg_defaults_raw) { | 56 | if (!map->reg_defaults_raw) { |
40 | u32 cache_bypass = map->cache_bypass; | 57 | u32 cache_bypass = map->cache_bypass; |
41 | dev_warn(map->dev, "No cache defaults, reading back from HW\n"); | 58 | dev_warn(map->dev, "No cache defaults, reading back from HW\n"); |
@@ -43,40 +60,25 @@ static int regcache_hw_init(struct regmap *map) | |||
43 | /* Bypass the cache access till data read from HW*/ | 60 | /* Bypass the cache access till data read from HW*/ |
44 | map->cache_bypass = 1; | 61 | map->cache_bypass = 1; |
45 | tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL); | 62 | tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL); |
46 | if (!tmp_buf) | 63 | if (!tmp_buf) { |
47 | return -EINVAL; | 64 | ret = -ENOMEM; |
65 | goto err_free; | ||
66 | } | ||
48 | ret = regmap_raw_read(map, 0, tmp_buf, | 67 | ret = regmap_raw_read(map, 0, tmp_buf, |
49 | map->num_reg_defaults_raw); | 68 | map->num_reg_defaults_raw); |
50 | map->cache_bypass = cache_bypass; | 69 | map->cache_bypass = cache_bypass; |
51 | if (ret < 0) { | 70 | if (ret < 0) |
52 | kfree(tmp_buf); | 71 | goto err_cache_free; |
53 | return ret; | 72 | |
54 | } | ||
55 | map->reg_defaults_raw = tmp_buf; | 73 | map->reg_defaults_raw = tmp_buf; |
56 | map->cache_free = 1; | 74 | map->cache_free = 1; |
57 | } | 75 | } |
58 | 76 | ||
59 | /* calculate the size of reg_defaults */ | ||
60 | for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) { | ||
61 | val = regcache_get_val(map, map->reg_defaults_raw, i); | ||
62 | if (regmap_volatile(map, i * map->reg_stride)) | ||
63 | continue; | ||
64 | count++; | ||
65 | } | ||
66 | |||
67 | map->reg_defaults = kmalloc(count * sizeof(struct reg_default), | ||
68 | GFP_KERNEL); | ||
69 | if (!map->reg_defaults) { | ||
70 | ret = -ENOMEM; | ||
71 | goto err_free; | ||
72 | } | ||
73 | |||
74 | /* fill the reg_defaults */ | 77 | /* fill the reg_defaults */ |
75 | map->num_reg_defaults = count; | ||
76 | for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { | 78 | for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { |
77 | val = regcache_get_val(map, map->reg_defaults_raw, i); | ||
78 | if (regmap_volatile(map, i * map->reg_stride)) | 79 | if (regmap_volatile(map, i * map->reg_stride)) |
79 | continue; | 80 | continue; |
81 | val = regcache_get_val(map, map->reg_defaults_raw, i); | ||
80 | map->reg_defaults[j].reg = i * map->reg_stride; | 82 | map->reg_defaults[j].reg = i * map->reg_stride; |
81 | map->reg_defaults[j].def = val; | 83 | map->reg_defaults[j].def = val; |
82 | j++; | 84 | j++; |
@@ -84,9 +86,10 @@ static int regcache_hw_init(struct regmap *map) | |||
84 | 86 | ||
85 | return 0; | 87 | return 0; |
86 | 88 | ||
89 | err_cache_free: | ||
90 | kfree(tmp_buf); | ||
87 | err_free: | 91 | err_free: |
88 | if (map->cache_free) | 92 | kfree(map->reg_defaults); |
89 | kfree(map->reg_defaults_raw); | ||
90 | 93 | ||
91 | return ret; | 94 | return ret; |
92 | } | 95 | } |
@@ -150,6 +153,8 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) | |||
150 | ret = regcache_hw_init(map); | 153 | ret = regcache_hw_init(map); |
151 | if (ret < 0) | 154 | if (ret < 0) |
152 | return ret; | 155 | return ret; |
156 | if (map->cache_bypass) | ||
157 | return 0; | ||
153 | } | 158 | } |
154 | 159 | ||
155 | if (!map->max_register) | 160 | if (!map->max_register) |
diff --git a/drivers/base/regmap/regmap-ac97.c b/drivers/base/regmap/regmap-ac97.c new file mode 100644 index 000000000000..e4c45d2299c1 --- /dev/null +++ b/drivers/base/regmap/regmap-ac97.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * Register map access API - AC'97 support | ||
3 | * | ||
4 | * Copyright 2013 Linaro Ltd. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/clk.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/regmap.h> | ||
25 | #include <linux/slab.h> | ||
26 | |||
27 | #include <sound/ac97_codec.h> | ||
28 | |||
29 | bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg) | ||
30 | { | ||
31 | switch (reg) { | ||
32 | case AC97_RESET: | ||
33 | case AC97_POWERDOWN: | ||
34 | case AC97_INT_PAGING: | ||
35 | case AC97_EXTENDED_ID: | ||
36 | case AC97_EXTENDED_STATUS: | ||
37 | case AC97_EXTENDED_MID: | ||
38 | case AC97_EXTENDED_MSTATUS: | ||
39 | case AC97_GPIO_STATUS: | ||
40 | case AC97_MISC_AFE: | ||
41 | case AC97_VENDOR_ID1: | ||
42 | case AC97_VENDOR_ID2: | ||
43 | case AC97_CODEC_CLASS_REV: | ||
44 | case AC97_PCI_SVID: | ||
45 | case AC97_PCI_SID: | ||
46 | case AC97_FUNC_SELECT: | ||
47 | case AC97_FUNC_INFO: | ||
48 | case AC97_SENSE_INFO: | ||
49 | return true; | ||
50 | default: | ||
51 | return false; | ||
52 | } | ||
53 | } | ||
54 | EXPORT_SYMBOL_GPL(regmap_ac97_default_volatile); | ||
55 | |||
56 | static int regmap_ac97_reg_read(void *context, unsigned int reg, | ||
57 | unsigned int *val) | ||
58 | { | ||
59 | struct snd_ac97 *ac97 = context; | ||
60 | |||
61 | *val = ac97->bus->ops->read(ac97, reg); | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int regmap_ac97_reg_write(void *context, unsigned int reg, | ||
67 | unsigned int val) | ||
68 | { | ||
69 | struct snd_ac97 *ac97 = context; | ||
70 | |||
71 | ac97->bus->ops->write(ac97, reg, val); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static const struct regmap_bus ac97_regmap_bus = { | ||
77 | .reg_write = regmap_ac97_reg_write, | ||
78 | .reg_read = regmap_ac97_reg_read, | ||
79 | }; | ||
80 | |||
81 | /** | ||
82 | * regmap_init_ac97(): Initialise AC'97 register map | ||
83 | * | ||
84 | * @ac97: Device that will be interacted with | ||
85 | * @config: Configuration for register map | ||
86 | * | ||
87 | * The return value will be an ERR_PTR() on error or a valid pointer to | ||
88 | * a struct regmap. | ||
89 | */ | ||
90 | struct regmap *regmap_init_ac97(struct snd_ac97 *ac97, | ||
91 | const struct regmap_config *config) | ||
92 | { | ||
93 | return regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config); | ||
94 | } | ||
95 | EXPORT_SYMBOL_GPL(regmap_init_ac97); | ||
96 | |||
97 | /** | ||
98 | * devm_regmap_init_ac97(): Initialise AC'97 register map | ||
99 | * | ||
100 | * @ac97: Device that will be interacted with | ||
101 | * @config: Configuration for register map | ||
102 | * | ||
103 | * The return value will be an ERR_PTR() on error or a valid pointer | ||
104 | * to a struct regmap. The regmap will be automatically freed by the | ||
105 | * device management code. | ||
106 | */ | ||
107 | struct regmap *devm_regmap_init_ac97(struct snd_ac97 *ac97, | ||
108 | const struct regmap_config *config) | ||
109 | { | ||
110 | return devm_regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config); | ||
111 | } | ||
112 | EXPORT_SYMBOL_GPL(devm_regmap_init_ac97); | ||
113 | |||
114 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index b7797fb12e12..7bb13af8e214 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/clk-provider.h> | 23 | #include <linux/clk-provider.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/mfd/samsung/s2mps11.h> | 25 | #include <linux/mfd/samsung/s2mps11.h> |
26 | #include <linux/mfd/samsung/s2mps13.h> | ||
26 | #include <linux/mfd/samsung/s2mps14.h> | 27 | #include <linux/mfd/samsung/s2mps14.h> |
27 | #include <linux/mfd/samsung/s5m8767.h> | 28 | #include <linux/mfd/samsung/s5m8767.h> |
28 | #include <linux/mfd/samsung/core.h> | 29 | #include <linux/mfd/samsung/core.h> |
@@ -120,6 +121,24 @@ static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = { | |||
120 | }, | 121 | }, |
121 | }; | 122 | }; |
122 | 123 | ||
124 | static struct clk_init_data s2mps13_clks_init[S2MPS11_CLKS_NUM] = { | ||
125 | [S2MPS11_CLK_AP] = { | ||
126 | .name = "s2mps13_ap", | ||
127 | .ops = &s2mps11_clk_ops, | ||
128 | .flags = CLK_IS_ROOT, | ||
129 | }, | ||
130 | [S2MPS11_CLK_CP] = { | ||
131 | .name = "s2mps13_cp", | ||
132 | .ops = &s2mps11_clk_ops, | ||
133 | .flags = CLK_IS_ROOT, | ||
134 | }, | ||
135 | [S2MPS11_CLK_BT] = { | ||
136 | .name = "s2mps13_bt", | ||
137 | .ops = &s2mps11_clk_ops, | ||
138 | .flags = CLK_IS_ROOT, | ||
139 | }, | ||
140 | }; | ||
141 | |||
123 | static struct clk_init_data s2mps14_clks_init[S2MPS11_CLKS_NUM] = { | 142 | static struct clk_init_data s2mps14_clks_init[S2MPS11_CLKS_NUM] = { |
124 | [S2MPS11_CLK_AP] = { | 143 | [S2MPS11_CLK_AP] = { |
125 | .name = "s2mps14_ap", | 144 | .name = "s2mps14_ap", |
@@ -184,6 +203,10 @@ static int s2mps11_clk_probe(struct platform_device *pdev) | |||
184 | s2mps11_reg = S2MPS11_REG_RTC_CTRL; | 203 | s2mps11_reg = S2MPS11_REG_RTC_CTRL; |
185 | clks_init = s2mps11_clks_init; | 204 | clks_init = s2mps11_clks_init; |
186 | break; | 205 | break; |
206 | case S2MPS13X: | ||
207 | s2mps11_reg = S2MPS13_REG_RTCCTRL; | ||
208 | clks_init = s2mps13_clks_init; | ||
209 | break; | ||
187 | case S2MPS14X: | 210 | case S2MPS14X: |
188 | s2mps11_reg = S2MPS14_REG_RTCCTRL; | 211 | s2mps11_reg = S2MPS14_REG_RTCCTRL; |
189 | clks_init = s2mps14_clks_init; | 212 | clks_init = s2mps14_clks_init; |
@@ -279,6 +302,7 @@ static int s2mps11_clk_remove(struct platform_device *pdev) | |||
279 | 302 | ||
280 | static const struct platform_device_id s2mps11_clk_id[] = { | 303 | static const struct platform_device_id s2mps11_clk_id[] = { |
281 | { "s2mps11-clk", S2MPS11X}, | 304 | { "s2mps11-clk", S2MPS11X}, |
305 | { "s2mps13-clk", S2MPS13X}, | ||
282 | { "s2mps14-clk", S2MPS14X}, | 306 | { "s2mps14-clk", S2MPS14X}, |
283 | { "s5m8767-clk", S5M8767X}, | 307 | { "s5m8767-clk", S5M8767X}, |
284 | { }, | 308 | { }, |
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 7072c2892d63..49c265255a07 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig | |||
@@ -61,14 +61,14 @@ config EDAC_DECODE_MCE | |||
61 | has been initialized. | 61 | has been initialized. |
62 | 62 | ||
63 | config EDAC_MCE_INJ | 63 | config EDAC_MCE_INJ |
64 | tristate "Simple MCE injection interface over /sysfs" | 64 | tristate "Simple MCE injection interface" |
65 | depends on EDAC_DECODE_MCE | 65 | depends on EDAC_DECODE_MCE && DEBUG_FS |
66 | default n | 66 | default n |
67 | help | 67 | help |
68 | This is a simple interface to inject MCEs over /sysfs and test | 68 | This is a simple debugfs interface to inject MCEs and test different |
69 | the MCE decoding code in EDAC. | 69 | aspects of the MCE handling code. |
70 | 70 | ||
71 | This is currently AMD-only. | 71 | WARNING: Do not even assume this interface is staying stable! |
72 | 72 | ||
73 | config EDAC_MM_EDAC | 73 | config EDAC_MM_EDAC |
74 | tristate "Main Memory EDAC (Error Detection And Correction) reporting" | 74 | tristate "Main Memory EDAC (Error Detection And Correction) reporting" |
@@ -105,11 +105,11 @@ config EDAC_GHES | |||
105 | In doubt, say 'Y'. | 105 | In doubt, say 'Y'. |
106 | 106 | ||
107 | config EDAC_AMD64 | 107 | config EDAC_AMD64 |
108 | tristate "AMD64 (Opteron, Athlon64) K8, F10h" | 108 | tristate "AMD64 (Opteron, Athlon64)" |
109 | depends on EDAC_MM_EDAC && AMD_NB && X86_64 && EDAC_DECODE_MCE | 109 | depends on EDAC_MM_EDAC && AMD_NB && EDAC_DECODE_MCE |
110 | help | 110 | help |
111 | Support for error detection and correction of DRAM ECC errors on | 111 | Support for error detection and correction of DRAM ECC errors on |
112 | the AMD64 families of memory controllers (K8 and F10h) | 112 | the AMD64 families (>= K8) of memory controllers. |
113 | 113 | ||
114 | config EDAC_AMD64_ERROR_INJECTION | 114 | config EDAC_AMD64_ERROR_INJECTION |
115 | bool "Sysfs HW Error injection facilities" | 115 | bool "Sysfs HW Error injection facilities" |
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index 359aa499b200..d40c69a04df7 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile | |||
@@ -9,7 +9,7 @@ | |||
9 | obj-$(CONFIG_EDAC) := edac_stub.o | 9 | obj-$(CONFIG_EDAC) := edac_stub.o |
10 | obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o | 10 | obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o |
11 | 11 | ||
12 | edac_core-y := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o | 12 | edac_core-y := edac_mc.o edac_device.o edac_mc_sysfs.o |
13 | edac_core-y += edac_module.o edac_device_sysfs.o | 13 | edac_core-y += edac_module.o edac_device_sysfs.o |
14 | 14 | ||
15 | ifdef CONFIG_PCI | 15 | ifdef CONFIG_PCI |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index bbd65149cdb2..17638d7cf5c2 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -692,9 +692,19 @@ static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan) | |||
692 | { | 692 | { |
693 | edac_dbg(1, "F2x%d90 (DRAM Cfg Low): 0x%08x\n", chan, dclr); | 693 | edac_dbg(1, "F2x%d90 (DRAM Cfg Low): 0x%08x\n", chan, dclr); |
694 | 694 | ||
695 | edac_dbg(1, " DIMM type: %sbuffered; all DIMMs support ECC: %s\n", | 695 | if (pvt->dram_type == MEM_LRDDR3) { |
696 | (dclr & BIT(16)) ? "un" : "", | 696 | u32 dcsm = pvt->csels[chan].csmasks[0]; |
697 | (dclr & BIT(19)) ? "yes" : "no"); | 697 | /* |
698 | * It's assumed all LRDIMMs in a DCT are going to be of | ||
699 | * same 'type' until proven otherwise. So, use a cs | ||
700 | * value of '0' here to get dcsm value. | ||
701 | */ | ||
702 | edac_dbg(1, " LRDIMM %dx rank multiply\n", (dcsm & 0x3)); | ||
703 | } | ||
704 | |||
705 | edac_dbg(1, "All DIMMs support ECC:%s\n", | ||
706 | (dclr & BIT(19)) ? "yes" : "no"); | ||
707 | |||
698 | 708 | ||
699 | edac_dbg(1, " PAR/ERR parity: %s\n", | 709 | edac_dbg(1, " PAR/ERR parity: %s\n", |
700 | (dclr & BIT(8)) ? "enabled" : "disabled"); | 710 | (dclr & BIT(8)) ? "enabled" : "disabled"); |
@@ -756,7 +766,7 @@ static void prep_chip_selects(struct amd64_pvt *pvt) | |||
756 | if (pvt->fam == 0xf && pvt->ext_model < K8_REV_F) { | 766 | if (pvt->fam == 0xf && pvt->ext_model < K8_REV_F) { |
757 | pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 8; | 767 | pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 8; |
758 | pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 8; | 768 | pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 8; |
759 | } else if (pvt->fam == 0x15 && pvt->model >= 0x30) { | 769 | } else if (pvt->fam == 0x15 && pvt->model == 0x30) { |
760 | pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 4; | 770 | pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 4; |
761 | pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 2; | 771 | pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 2; |
762 | } else { | 772 | } else { |
@@ -813,25 +823,63 @@ static void read_dct_base_mask(struct amd64_pvt *pvt) | |||
813 | } | 823 | } |
814 | } | 824 | } |
815 | 825 | ||
816 | static enum mem_type determine_memory_type(struct amd64_pvt *pvt, int cs) | 826 | static void determine_memory_type(struct amd64_pvt *pvt) |
817 | { | 827 | { |
818 | enum mem_type type; | 828 | u32 dram_ctrl, dcsm; |
819 | 829 | ||
820 | /* F15h supports only DDR3 */ | 830 | switch (pvt->fam) { |
821 | if (pvt->fam >= 0x15) | 831 | case 0xf: |
822 | type = (pvt->dclr0 & BIT(16)) ? MEM_DDR3 : MEM_RDDR3; | 832 | if (pvt->ext_model >= K8_REV_F) |
823 | else if (pvt->fam == 0x10 || pvt->ext_model >= K8_REV_F) { | 833 | goto ddr3; |
834 | |||
835 | pvt->dram_type = (pvt->dclr0 & BIT(18)) ? MEM_DDR : MEM_RDDR; | ||
836 | return; | ||
837 | |||
838 | case 0x10: | ||
824 | if (pvt->dchr0 & DDR3_MODE) | 839 | if (pvt->dchr0 & DDR3_MODE) |
825 | type = (pvt->dclr0 & BIT(16)) ? MEM_DDR3 : MEM_RDDR3; | 840 | goto ddr3; |
841 | |||
842 | pvt->dram_type = (pvt->dclr0 & BIT(16)) ? MEM_DDR2 : MEM_RDDR2; | ||
843 | return; | ||
844 | |||
845 | case 0x15: | ||
846 | if (pvt->model < 0x60) | ||
847 | goto ddr3; | ||
848 | |||
849 | /* | ||
850 | * Model 0x60h needs special handling: | ||
851 | * | ||
852 | * We use a Chip Select value of '0' to obtain dcsm. | ||
853 | * Theoretically, it is possible to populate LRDIMMs of different | ||
854 | * 'Rank' value on a DCT. But this is not the common case. So, | ||
855 | * it's reasonable to assume all DIMMs are going to be of same | ||
856 | * 'type' until proven otherwise. | ||
857 | */ | ||
858 | amd64_read_dct_pci_cfg(pvt, 0, DRAM_CONTROL, &dram_ctrl); | ||
859 | dcsm = pvt->csels[0].csmasks[0]; | ||
860 | |||
861 | if (((dram_ctrl >> 8) & 0x7) == 0x2) | ||
862 | pvt->dram_type = MEM_DDR4; | ||
863 | else if (pvt->dclr0 & BIT(16)) | ||
864 | pvt->dram_type = MEM_DDR3; | ||
865 | else if (dcsm & 0x3) | ||
866 | pvt->dram_type = MEM_LRDDR3; | ||
826 | else | 867 | else |
827 | type = (pvt->dclr0 & BIT(16)) ? MEM_DDR2 : MEM_RDDR2; | 868 | pvt->dram_type = MEM_RDDR3; |
828 | } else { | ||
829 | type = (pvt->dclr0 & BIT(18)) ? MEM_DDR : MEM_RDDR; | ||
830 | } | ||
831 | 869 | ||
832 | amd64_info("CS%d: %s\n", cs, edac_mem_types[type]); | 870 | return; |
833 | 871 | ||
834 | return type; | 872 | case 0x16: |
873 | goto ddr3; | ||
874 | |||
875 | default: | ||
876 | WARN(1, KERN_ERR "%s: Family??? 0x%x\n", __func__, pvt->fam); | ||
877 | pvt->dram_type = MEM_EMPTY; | ||
878 | } | ||
879 | return; | ||
880 | |||
881 | ddr3: | ||
882 | pvt->dram_type = (pvt->dclr0 & BIT(16)) ? MEM_DDR3 : MEM_RDDR3; | ||
835 | } | 883 | } |
836 | 884 | ||
837 | /* Get the number of DCT channels the memory controller is using. */ | 885 | /* Get the number of DCT channels the memory controller is using. */ |
@@ -958,8 +1006,12 @@ static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) | |||
958 | if (WARN_ON(!nb)) | 1006 | if (WARN_ON(!nb)) |
959 | return; | 1007 | return; |
960 | 1008 | ||
961 | pci_func = (pvt->model == 0x30) ? PCI_DEVICE_ID_AMD_15H_M30H_NB_F1 | 1009 | if (pvt->model == 0x60) |
962 | : PCI_DEVICE_ID_AMD_15H_NB_F1; | 1010 | pci_func = PCI_DEVICE_ID_AMD_15H_M60H_NB_F1; |
1011 | else if (pvt->model == 0x30) | ||
1012 | pci_func = PCI_DEVICE_ID_AMD_15H_M30H_NB_F1; | ||
1013 | else | ||
1014 | pci_func = PCI_DEVICE_ID_AMD_15H_NB_F1; | ||
963 | 1015 | ||
964 | f1 = pci_get_related_function(nb->misc->vendor, pci_func, nb->misc); | 1016 | f1 = pci_get_related_function(nb->misc->vendor, pci_func, nb->misc); |
965 | if (WARN_ON(!f1)) | 1017 | if (WARN_ON(!f1)) |
@@ -1049,7 +1101,7 @@ static int ddr2_cs_size(unsigned i, bool dct_width) | |||
1049 | } | 1101 | } |
1050 | 1102 | ||
1051 | static int k8_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, | 1103 | static int k8_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, |
1052 | unsigned cs_mode) | 1104 | unsigned cs_mode, int cs_mask_nr) |
1053 | { | 1105 | { |
1054 | u32 dclr = dct ? pvt->dclr1 : pvt->dclr0; | 1106 | u32 dclr = dct ? pvt->dclr1 : pvt->dclr0; |
1055 | 1107 | ||
@@ -1167,8 +1219,43 @@ static int ddr3_cs_size(unsigned i, bool dct_width) | |||
1167 | return cs_size; | 1219 | return cs_size; |
1168 | } | 1220 | } |
1169 | 1221 | ||
1222 | static int ddr3_lrdimm_cs_size(unsigned i, unsigned rank_multiply) | ||
1223 | { | ||
1224 | unsigned shift = 0; | ||
1225 | int cs_size = 0; | ||
1226 | |||
1227 | if (i < 4 || i == 6) | ||
1228 | cs_size = -1; | ||
1229 | else if (i == 12) | ||
1230 | shift = 7; | ||
1231 | else if (!(i & 0x1)) | ||
1232 | shift = i >> 1; | ||
1233 | else | ||
1234 | shift = (i + 1) >> 1; | ||
1235 | |||
1236 | if (cs_size != -1) | ||
1237 | cs_size = rank_multiply * (128 << shift); | ||
1238 | |||
1239 | return cs_size; | ||
1240 | } | ||
1241 | |||
1242 | static int ddr4_cs_size(unsigned i) | ||
1243 | { | ||
1244 | int cs_size = 0; | ||
1245 | |||
1246 | if (i == 0) | ||
1247 | cs_size = -1; | ||
1248 | else if (i == 1) | ||
1249 | cs_size = 1024; | ||
1250 | else | ||
1251 | /* Min cs_size = 1G */ | ||
1252 | cs_size = 1024 * (1 << (i >> 1)); | ||
1253 | |||
1254 | return cs_size; | ||
1255 | } | ||
1256 | |||
1170 | static int f10_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, | 1257 | static int f10_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, |
1171 | unsigned cs_mode) | 1258 | unsigned cs_mode, int cs_mask_nr) |
1172 | { | 1259 | { |
1173 | u32 dclr = dct ? pvt->dclr1 : pvt->dclr0; | 1260 | u32 dclr = dct ? pvt->dclr1 : pvt->dclr0; |
1174 | 1261 | ||
@@ -1184,18 +1271,49 @@ static int f10_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, | |||
1184 | * F15h supports only 64bit DCT interfaces | 1271 | * F15h supports only 64bit DCT interfaces |
1185 | */ | 1272 | */ |
1186 | static int f15_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, | 1273 | static int f15_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, |
1187 | unsigned cs_mode) | 1274 | unsigned cs_mode, int cs_mask_nr) |
1188 | { | 1275 | { |
1189 | WARN_ON(cs_mode > 12); | 1276 | WARN_ON(cs_mode > 12); |
1190 | 1277 | ||
1191 | return ddr3_cs_size(cs_mode, false); | 1278 | return ddr3_cs_size(cs_mode, false); |
1192 | } | 1279 | } |
1193 | 1280 | ||
1281 | /* F15h M60h supports DDR4 mapping as well.. */ | ||
1282 | static int f15_m60h_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, | ||
1283 | unsigned cs_mode, int cs_mask_nr) | ||
1284 | { | ||
1285 | int cs_size; | ||
1286 | u32 dcsm = pvt->csels[dct].csmasks[cs_mask_nr]; | ||
1287 | |||
1288 | WARN_ON(cs_mode > 12); | ||
1289 | |||
1290 | if (pvt->dram_type == MEM_DDR4) { | ||
1291 | if (cs_mode > 9) | ||
1292 | return -1; | ||
1293 | |||
1294 | cs_size = ddr4_cs_size(cs_mode); | ||
1295 | } else if (pvt->dram_type == MEM_LRDDR3) { | ||
1296 | unsigned rank_multiply = dcsm & 0xf; | ||
1297 | |||
1298 | if (rank_multiply == 3) | ||
1299 | rank_multiply = 4; | ||
1300 | cs_size = ddr3_lrdimm_cs_size(cs_mode, rank_multiply); | ||
1301 | } else { | ||
1302 | /* Minimum cs size is 512mb for F15hM60h*/ | ||
1303 | if (cs_mode == 0x1) | ||
1304 | return -1; | ||
1305 | |||
1306 | cs_size = ddr3_cs_size(cs_mode, false); | ||
1307 | } | ||
1308 | |||
1309 | return cs_size; | ||
1310 | } | ||
1311 | |||
1194 | /* | 1312 | /* |
1195 | * F16h and F15h model 30h have only limited cs_modes. | 1313 | * F16h and F15h model 30h have only limited cs_modes. |
1196 | */ | 1314 | */ |
1197 | static int f16_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, | 1315 | static int f16_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, |
1198 | unsigned cs_mode) | 1316 | unsigned cs_mode, int cs_mask_nr) |
1199 | { | 1317 | { |
1200 | WARN_ON(cs_mode > 12); | 1318 | WARN_ON(cs_mode > 12); |
1201 | 1319 | ||
@@ -1757,13 +1875,20 @@ static void debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl) | |||
1757 | 1875 | ||
1758 | size0 = 0; | 1876 | size0 = 0; |
1759 | if (dcsb[dimm*2] & DCSB_CS_ENABLE) | 1877 | if (dcsb[dimm*2] & DCSB_CS_ENABLE) |
1878 | /* For f15m60h, need multiplier for LRDIMM cs_size | ||
1879 | * calculation. We pass 'dimm' value to the dbam_to_cs | ||
1880 | * mapper so we can find the multiplier from the | ||
1881 | * corresponding DCSM. | ||
1882 | */ | ||
1760 | size0 = pvt->ops->dbam_to_cs(pvt, ctrl, | 1883 | size0 = pvt->ops->dbam_to_cs(pvt, ctrl, |
1761 | DBAM_DIMM(dimm, dbam)); | 1884 | DBAM_DIMM(dimm, dbam), |
1885 | dimm); | ||
1762 | 1886 | ||
1763 | size1 = 0; | 1887 | size1 = 0; |
1764 | if (dcsb[dimm*2 + 1] & DCSB_CS_ENABLE) | 1888 | if (dcsb[dimm*2 + 1] & DCSB_CS_ENABLE) |
1765 | size1 = pvt->ops->dbam_to_cs(pvt, ctrl, | 1889 | size1 = pvt->ops->dbam_to_cs(pvt, ctrl, |
1766 | DBAM_DIMM(dimm, dbam)); | 1890 | DBAM_DIMM(dimm, dbam), |
1891 | dimm); | ||
1767 | 1892 | ||
1768 | amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n", | 1893 | amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n", |
1769 | dimm * 2, size0, | 1894 | dimm * 2, size0, |
@@ -1812,6 +1937,16 @@ static struct amd64_family_type family_types[] = { | |||
1812 | .dbam_to_cs = f16_dbam_to_chip_select, | 1937 | .dbam_to_cs = f16_dbam_to_chip_select, |
1813 | } | 1938 | } |
1814 | }, | 1939 | }, |
1940 | [F15_M60H_CPUS] = { | ||
1941 | .ctl_name = "F15h_M60h", | ||
1942 | .f1_id = PCI_DEVICE_ID_AMD_15H_M60H_NB_F1, | ||
1943 | .f3_id = PCI_DEVICE_ID_AMD_15H_M60H_NB_F3, | ||
1944 | .ops = { | ||
1945 | .early_channel_count = f1x_early_channel_count, | ||
1946 | .map_sysaddr_to_csrow = f1x_map_sysaddr_to_csrow, | ||
1947 | .dbam_to_cs = f15_m60h_dbam_to_chip_select, | ||
1948 | } | ||
1949 | }, | ||
1815 | [F16_CPUS] = { | 1950 | [F16_CPUS] = { |
1816 | .ctl_name = "F16h", | 1951 | .ctl_name = "F16h", |
1817 | .f1_id = PCI_DEVICE_ID_AMD_16H_NB_F1, | 1952 | .f1_id = PCI_DEVICE_ID_AMD_16H_NB_F1, |
@@ -2175,6 +2310,8 @@ static void read_mc_regs(struct amd64_pvt *pvt) | |||
2175 | } | 2310 | } |
2176 | 2311 | ||
2177 | pvt->ecc_sym_sz = 4; | 2312 | pvt->ecc_sym_sz = 4; |
2313 | determine_memory_type(pvt); | ||
2314 | edac_dbg(1, " DIMM type: %s\n", edac_mem_types[pvt->dram_type]); | ||
2178 | 2315 | ||
2179 | if (pvt->fam >= 0x10) { | 2316 | if (pvt->fam >= 0x10) { |
2180 | amd64_read_pci_cfg(pvt->F3, EXT_NB_MCA_CFG, &tmp); | 2317 | amd64_read_pci_cfg(pvt->F3, EXT_NB_MCA_CFG, &tmp); |
@@ -2238,7 +2375,8 @@ static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr) | |||
2238 | */ | 2375 | */ |
2239 | cs_mode = DBAM_DIMM(csrow_nr / 2, dbam); | 2376 | cs_mode = DBAM_DIMM(csrow_nr / 2, dbam); |
2240 | 2377 | ||
2241 | nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode) << (20 - PAGE_SHIFT); | 2378 | nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode, (csrow_nr / 2)) |
2379 | << (20 - PAGE_SHIFT); | ||
2242 | 2380 | ||
2243 | edac_dbg(0, "csrow: %d, channel: %d, DBAM idx: %d\n", | 2381 | edac_dbg(0, "csrow: %d, channel: %d, DBAM idx: %d\n", |
2244 | csrow_nr, dct, cs_mode); | 2382 | csrow_nr, dct, cs_mode); |
@@ -2257,7 +2395,6 @@ static int init_csrows(struct mem_ctl_info *mci) | |||
2257 | struct csrow_info *csrow; | 2395 | struct csrow_info *csrow; |
2258 | struct dimm_info *dimm; | 2396 | struct dimm_info *dimm; |
2259 | enum edac_type edac_mode; | 2397 | enum edac_type edac_mode; |
2260 | enum mem_type mtype; | ||
2261 | int i, j, empty = 1; | 2398 | int i, j, empty = 1; |
2262 | int nr_pages = 0; | 2399 | int nr_pages = 0; |
2263 | u32 val; | 2400 | u32 val; |
@@ -2302,8 +2439,6 @@ static int init_csrows(struct mem_ctl_info *mci) | |||
2302 | nr_pages += row_dct1_pages; | 2439 | nr_pages += row_dct1_pages; |
2303 | } | 2440 | } |
2304 | 2441 | ||
2305 | mtype = determine_memory_type(pvt, i); | ||
2306 | |||
2307 | edac_dbg(1, "Total csrow%d pages: %u\n", i, nr_pages); | 2442 | edac_dbg(1, "Total csrow%d pages: %u\n", i, nr_pages); |
2308 | 2443 | ||
2309 | /* | 2444 | /* |
@@ -2317,7 +2452,7 @@ static int init_csrows(struct mem_ctl_info *mci) | |||
2317 | 2452 | ||
2318 | for (j = 0; j < pvt->channel_count; j++) { | 2453 | for (j = 0; j < pvt->channel_count; j++) { |
2319 | dimm = csrow->channels[j]->dimm; | 2454 | dimm = csrow->channels[j]->dimm; |
2320 | dimm->mtype = mtype; | 2455 | dimm->mtype = pvt->dram_type; |
2321 | dimm->edac_mode = edac_mode; | 2456 | dimm->edac_mode = edac_mode; |
2322 | } | 2457 | } |
2323 | } | 2458 | } |
@@ -2604,6 +2739,10 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt) | |||
2604 | fam_type = &family_types[F15_M30H_CPUS]; | 2739 | fam_type = &family_types[F15_M30H_CPUS]; |
2605 | pvt->ops = &family_types[F15_M30H_CPUS].ops; | 2740 | pvt->ops = &family_types[F15_M30H_CPUS].ops; |
2606 | break; | 2741 | break; |
2742 | } else if (pvt->model == 0x60) { | ||
2743 | fam_type = &family_types[F15_M60H_CPUS]; | ||
2744 | pvt->ops = &family_types[F15_M60H_CPUS].ops; | ||
2745 | break; | ||
2607 | } | 2746 | } |
2608 | 2747 | ||
2609 | fam_type = &family_types[F15_CPUS]; | 2748 | fam_type = &family_types[F15_CPUS]; |
@@ -2828,55 +2967,13 @@ static void remove_one_instance(struct pci_dev *pdev) | |||
2828 | * inquiry this table to see if this driver is for a given device found. | 2967 | * inquiry this table to see if this driver is for a given device found. |
2829 | */ | 2968 | */ |
2830 | static const struct pci_device_id amd64_pci_table[] = { | 2969 | static const struct pci_device_id amd64_pci_table[] = { |
2831 | { | 2970 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_K8_NB_MEMCTL) }, |
2832 | .vendor = PCI_VENDOR_ID_AMD, | 2971 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_DRAM) }, |
2833 | .device = PCI_DEVICE_ID_AMD_K8_NB_MEMCTL, | 2972 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F2) }, |
2834 | .subvendor = PCI_ANY_ID, | 2973 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F2) }, |
2835 | .subdevice = PCI_ANY_ID, | 2974 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F2) }, |
2836 | .class = 0, | 2975 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F2) }, |
2837 | .class_mask = 0, | 2976 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F2) }, |
2838 | }, | ||
2839 | { | ||
2840 | .vendor = PCI_VENDOR_ID_AMD, | ||
2841 | .device = PCI_DEVICE_ID_AMD_10H_NB_DRAM, | ||
2842 | .subvendor = PCI_ANY_ID, | ||
2843 | .subdevice = PCI_ANY_ID, | ||
2844 | .class = 0, | ||
2845 | .class_mask = 0, | ||
2846 | }, | ||
2847 | { | ||
2848 | .vendor = PCI_VENDOR_ID_AMD, | ||
2849 | .device = PCI_DEVICE_ID_AMD_15H_NB_F2, | ||
2850 | .subvendor = PCI_ANY_ID, | ||
2851 | .subdevice = PCI_ANY_ID, | ||
2852 | .class = 0, | ||
2853 | .class_mask = 0, | ||
2854 | }, | ||
2855 | { | ||
2856 | .vendor = PCI_VENDOR_ID_AMD, | ||
2857 | .device = PCI_DEVICE_ID_AMD_15H_M30H_NB_F2, | ||
2858 | .subvendor = PCI_ANY_ID, | ||
2859 | .subdevice = PCI_ANY_ID, | ||
2860 | .class = 0, | ||
2861 | .class_mask = 0, | ||
2862 | }, | ||
2863 | { | ||
2864 | .vendor = PCI_VENDOR_ID_AMD, | ||
2865 | .device = PCI_DEVICE_ID_AMD_16H_NB_F2, | ||
2866 | .subvendor = PCI_ANY_ID, | ||
2867 | .subdevice = PCI_ANY_ID, | ||
2868 | .class = 0, | ||
2869 | .class_mask = 0, | ||
2870 | }, | ||
2871 | { | ||
2872 | .vendor = PCI_VENDOR_ID_AMD, | ||
2873 | .device = PCI_DEVICE_ID_AMD_16H_M30H_NB_F2, | ||
2874 | .subvendor = PCI_ANY_ID, | ||
2875 | .subdevice = PCI_ANY_ID, | ||
2876 | .class = 0, | ||
2877 | .class_mask = 0, | ||
2878 | }, | ||
2879 | |||
2880 | {0, } | 2977 | {0, } |
2881 | }; | 2978 | }; |
2882 | MODULE_DEVICE_TABLE(pci, amd64_pci_table); | 2979 | MODULE_DEVICE_TABLE(pci, amd64_pci_table); |
@@ -2938,6 +3035,11 @@ static int __init amd64_edac_init(void) | |||
2938 | goto err_no_instances; | 3035 | goto err_no_instances; |
2939 | 3036 | ||
2940 | setup_pci_device(); | 3037 | setup_pci_device(); |
3038 | |||
3039 | #ifdef CONFIG_X86_32 | ||
3040 | amd64_err("%s on 32-bit is unsupported. USE AT YOUR OWN RISK!\n", EDAC_MOD_STR); | ||
3041 | #endif | ||
3042 | |||
2941 | return 0; | 3043 | return 0; |
2942 | 3044 | ||
2943 | err_no_instances: | 3045 | err_no_instances: |
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index 55fb5941c6d4..d8468c667925 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h | |||
@@ -162,10 +162,12 @@ | |||
162 | /* | 162 | /* |
163 | * PCI-defined configuration space registers | 163 | * PCI-defined configuration space registers |
164 | */ | 164 | */ |
165 | #define PCI_DEVICE_ID_AMD_15H_M30H_NB_F1 0x141b | ||
166 | #define PCI_DEVICE_ID_AMD_15H_M30H_NB_F2 0x141c | ||
167 | #define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601 | 165 | #define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601 |
168 | #define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602 | 166 | #define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602 |
167 | #define PCI_DEVICE_ID_AMD_15H_M30H_NB_F1 0x141b | ||
168 | #define PCI_DEVICE_ID_AMD_15H_M30H_NB_F2 0x141c | ||
169 | #define PCI_DEVICE_ID_AMD_15H_M60H_NB_F1 0x1571 | ||
170 | #define PCI_DEVICE_ID_AMD_15H_M60H_NB_F2 0x1572 | ||
169 | #define PCI_DEVICE_ID_AMD_16H_NB_F1 0x1531 | 171 | #define PCI_DEVICE_ID_AMD_16H_NB_F1 0x1531 |
170 | #define PCI_DEVICE_ID_AMD_16H_NB_F2 0x1532 | 172 | #define PCI_DEVICE_ID_AMD_16H_NB_F2 0x1532 |
171 | #define PCI_DEVICE_ID_AMD_16H_M30H_NB_F1 0x1581 | 173 | #define PCI_DEVICE_ID_AMD_16H_M30H_NB_F1 0x1581 |
@@ -221,6 +223,8 @@ | |||
221 | 223 | ||
222 | #define csrow_enabled(i, dct, pvt) ((pvt)->csels[(dct)].csbases[(i)] & DCSB_CS_ENABLE) | 224 | #define csrow_enabled(i, dct, pvt) ((pvt)->csels[(dct)].csbases[(i)] & DCSB_CS_ENABLE) |
223 | 225 | ||
226 | #define DRAM_CONTROL 0x78 | ||
227 | |||
224 | #define DBAM0 0x80 | 228 | #define DBAM0 0x80 |
225 | #define DBAM1 0x180 | 229 | #define DBAM1 0x180 |
226 | 230 | ||
@@ -301,6 +305,7 @@ enum amd_families { | |||
301 | F10_CPUS, | 305 | F10_CPUS, |
302 | F15_CPUS, | 306 | F15_CPUS, |
303 | F15_M30H_CPUS, | 307 | F15_M30H_CPUS, |
308 | F15_M60H_CPUS, | ||
304 | F16_CPUS, | 309 | F16_CPUS, |
305 | F16_M30H_CPUS, | 310 | F16_M30H_CPUS, |
306 | NUM_FAMILIES, | 311 | NUM_FAMILIES, |
@@ -379,6 +384,9 @@ struct amd64_pvt { | |||
379 | 384 | ||
380 | /* place to store error injection parameters prior to issue */ | 385 | /* place to store error injection parameters prior to issue */ |
381 | struct error_injection injection; | 386 | struct error_injection injection; |
387 | |||
388 | /* cache the dram_type */ | ||
389 | enum mem_type dram_type; | ||
382 | }; | 390 | }; |
383 | 391 | ||
384 | enum err_codes { | 392 | enum err_codes { |
@@ -480,7 +488,8 @@ struct low_ops { | |||
480 | int (*early_channel_count) (struct amd64_pvt *pvt); | 488 | int (*early_channel_count) (struct amd64_pvt *pvt); |
481 | void (*map_sysaddr_to_csrow) (struct mem_ctl_info *mci, u64 sys_addr, | 489 | void (*map_sysaddr_to_csrow) (struct mem_ctl_info *mci, u64 sys_addr, |
482 | struct err_info *); | 490 | struct err_info *); |
483 | int (*dbam_to_cs) (struct amd64_pvt *pvt, u8 dct, unsigned cs_mode); | 491 | int (*dbam_to_cs) (struct amd64_pvt *pvt, u8 dct, |
492 | unsigned cs_mode, int cs_mask_nr); | ||
484 | }; | 493 | }; |
485 | 494 | ||
486 | struct amd64_family_type { | 495 | struct amd64_family_type { |
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index c3893b0ddb18..1747906f10ce 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -125,27 +125,27 @@ static void edac_mc_dump_mci(struct mem_ctl_info *mci) | |||
125 | 125 | ||
126 | #endif /* CONFIG_EDAC_DEBUG */ | 126 | #endif /* CONFIG_EDAC_DEBUG */ |
127 | 127 | ||
128 | /* | ||
129 | * keep those in sync with the enum mem_type | ||
130 | */ | ||
131 | const char * const edac_mem_types[] = { | 128 | const char * const edac_mem_types[] = { |
132 | "Empty csrow", | 129 | [MEM_EMPTY] = "Empty csrow", |
133 | "Reserved csrow type", | 130 | [MEM_RESERVED] = "Reserved csrow type", |
134 | "Unknown csrow type", | 131 | [MEM_UNKNOWN] = "Unknown csrow type", |
135 | "Fast page mode RAM", | 132 | [MEM_FPM] = "Fast page mode RAM", |
136 | "Extended data out RAM", | 133 | [MEM_EDO] = "Extended data out RAM", |
137 | "Burst Extended data out RAM", | 134 | [MEM_BEDO] = "Burst Extended data out RAM", |
138 | "Single data rate SDRAM", | 135 | [MEM_SDR] = "Single data rate SDRAM", |
139 | "Registered single data rate SDRAM", | 136 | [MEM_RDR] = "Registered single data rate SDRAM", |
140 | "Double data rate SDRAM", | 137 | [MEM_DDR] = "Double data rate SDRAM", |
141 | "Registered Double data rate SDRAM", | 138 | [MEM_RDDR] = "Registered Double data rate SDRAM", |
142 | "Rambus DRAM", | 139 | [MEM_RMBS] = "Rambus DRAM", |
143 | "Unbuffered DDR2 RAM", | 140 | [MEM_DDR2] = "Unbuffered DDR2 RAM", |
144 | "Fully buffered DDR2", | 141 | [MEM_FB_DDR2] = "Fully buffered DDR2", |
145 | "Registered DDR2 RAM", | 142 | [MEM_RDDR2] = "Registered DDR2 RAM", |
146 | "Rambus XDR", | 143 | [MEM_XDR] = "Rambus XDR", |
147 | "Unbuffered DDR3 RAM", | 144 | [MEM_DDR3] = "Unbuffered DDR3 RAM", |
148 | "Registered DDR3 RAM", | 145 | [MEM_RDDR3] = "Registered DDR3 RAM", |
146 | [MEM_LRDDR3] = "Load-Reduced DDR3 RAM", | ||
147 | [MEM_DDR4] = "Unbuffered DDR4 RAM", | ||
148 | [MEM_RDDR4] = "Registered DDR4 RAM", | ||
149 | }; | 149 | }; |
150 | EXPORT_SYMBOL_GPL(edac_mem_types); | 150 | EXPORT_SYMBOL_GPL(edac_mem_types); |
151 | 151 | ||
diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index e8658e451762..24d877f6e577 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c | |||
@@ -14,9 +14,6 @@ | |||
14 | #include "edac_core.h" | 14 | #include "edac_core.h" |
15 | #include "edac_module.h" | 15 | #include "edac_module.h" |
16 | 16 | ||
17 | /* Turn off this whole feature if PCI is not configured */ | ||
18 | #ifdef CONFIG_PCI | ||
19 | |||
20 | #define EDAC_PCI_SYMLINK "device" | 17 | #define EDAC_PCI_SYMLINK "device" |
21 | 18 | ||
22 | /* data variables exported via sysfs */ | 19 | /* data variables exported via sysfs */ |
@@ -761,5 +758,3 @@ MODULE_PARM_DESC(check_pci_errors, | |||
761 | module_param(edac_pci_panic_on_pe, int, 0644); | 758 | module_param(edac_pci_panic_on_pe, int, 0644); |
762 | MODULE_PARM_DESC(edac_pci_panic_on_pe, | 759 | MODULE_PARM_DESC(edac_pci_panic_on_pe, |
763 | "Panic on PCI Bus Parity error: 0=off 1=on"); | 760 | "Panic on PCI Bus Parity error: 0=off 1=on"); |
764 | |||
765 | #endif /* CONFIG_PCI */ | ||
diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c index 8399b4e16fe0..b24681998740 100644 --- a/drivers/edac/ghes_edac.c +++ b/drivers/edac/ghes_edac.c | |||
@@ -413,8 +413,8 @@ void ghes_edac_report_mem_error(struct ghes *ghes, int sev, | |||
413 | 413 | ||
414 | /* Generate the trace event */ | 414 | /* Generate the trace event */ |
415 | grain_bits = fls_long(e->grain); | 415 | grain_bits = fls_long(e->grain); |
416 | sprintf(pvt->detail_location, "APEI location: %s %s", | 416 | snprintf(pvt->detail_location, sizeof(pvt->detail_location), |
417 | e->location, e->other_detail); | 417 | "APEI location: %s %s", e->location, e->other_detail); |
418 | trace_mc_event(type, e->msg, e->label, e->error_count, | 418 | trace_mc_event(type, e->msg, e->label, e->error_count, |
419 | mci->mc_idx, e->top_layer, e->mid_layer, e->low_layer, | 419 | mci->mc_idx, e->top_layer, e->mid_layer, e->low_layer, |
420 | PAGES_TO_MiB(e->page_frame_number) | e->offset_in_page, | 420 | PAGES_TO_MiB(e->page_frame_number) | e->offset_in_page, |
diff --git a/drivers/edac/i3000_edac.c b/drivers/edac/i3000_edac.c index cd28b968e5c7..5cb36a6022cc 100644 --- a/drivers/edac/i3000_edac.c +++ b/drivers/edac/i3000_edac.c | |||
@@ -542,8 +542,7 @@ fail1: | |||
542 | pci_unregister_driver(&i3000_driver); | 542 | pci_unregister_driver(&i3000_driver); |
543 | 543 | ||
544 | fail0: | 544 | fail0: |
545 | if (mci_pdev) | 545 | pci_dev_put(mci_pdev); |
546 | pci_dev_put(mci_pdev); | ||
547 | 546 | ||
548 | return pci_rc; | 547 | return pci_rc; |
549 | } | 548 | } |
diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c index aa98b136f5d0..4ad062b0ef26 100644 --- a/drivers/edac/i3200_edac.c +++ b/drivers/edac/i3200_edac.c | |||
@@ -523,8 +523,7 @@ fail1: | |||
523 | pci_unregister_driver(&i3200_driver); | 523 | pci_unregister_driver(&i3200_driver); |
524 | 524 | ||
525 | fail0: | 525 | fail0: |
526 | if (mci_pdev) | 526 | pci_dev_put(mci_pdev); |
527 | pci_dev_put(mci_pdev); | ||
528 | 527 | ||
529 | return pci_rc; | 528 | return pci_rc; |
530 | } | 529 | } |
diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c index d730e276d1a8..b4705d9366bf 100644 --- a/drivers/edac/i82443bxgx_edac.c +++ b/drivers/edac/i82443bxgx_edac.c | |||
@@ -458,8 +458,7 @@ static void __exit i82443bxgx_edacmc_exit(void) | |||
458 | if (!i82443bxgx_registered) | 458 | if (!i82443bxgx_registered) |
459 | i82443bxgx_edacmc_remove_one(mci_pdev); | 459 | i82443bxgx_edacmc_remove_one(mci_pdev); |
460 | 460 | ||
461 | if (mci_pdev) | 461 | pci_dev_put(mci_pdev); |
462 | pci_dev_put(mci_pdev); | ||
463 | } | 462 | } |
464 | 463 | ||
465 | module_init(i82443bxgx_edacmc_init); | 464 | module_init(i82443bxgx_edacmc_init); |
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c index f78c1c54dbd5..58586d59bf8e 100644 --- a/drivers/edac/mce_amd.c +++ b/drivers/edac/mce_amd.c | |||
@@ -138,6 +138,15 @@ static const char * const mc5_mce_desc[] = { | |||
138 | "Retire status queue" | 138 | "Retire status queue" |
139 | }; | 139 | }; |
140 | 140 | ||
141 | static const char * const mc6_mce_desc[] = { | ||
142 | "Hardware Assertion", | ||
143 | "Free List", | ||
144 | "Physical Register File", | ||
145 | "Retire Queue", | ||
146 | "Scheduler table", | ||
147 | "Status Register File", | ||
148 | }; | ||
149 | |||
141 | static bool f12h_mc0_mce(u16 ec, u8 xec) | 150 | static bool f12h_mc0_mce(u16 ec, u8 xec) |
142 | { | 151 | { |
143 | bool ret = false; | 152 | bool ret = false; |
@@ -432,8 +441,8 @@ static bool k8_mc2_mce(u16 ec, u8 xec) | |||
432 | pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec)); | 441 | pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec)); |
433 | else if (xec == 0x0) { | 442 | else if (xec == 0x0) { |
434 | if (TLB_ERROR(ec)) | 443 | if (TLB_ERROR(ec)) |
435 | pr_cont(": %s error in a Page Descriptor Cache or " | 444 | pr_cont("%s error in a Page Descriptor Cache or Guest TLB.\n", |
436 | "Guest TLB.\n", TT_MSG(ec)); | 445 | TT_MSG(ec)); |
437 | else if (BUS_ERROR(ec)) | 446 | else if (BUS_ERROR(ec)) |
438 | pr_cont(": %s/ECC error in data read from NB: %s.\n", | 447 | pr_cont(": %s/ECC error in data read from NB: %s.\n", |
439 | R4_MSG(ec), PP_MSG(ec)); | 448 | R4_MSG(ec), PP_MSG(ec)); |
@@ -672,38 +681,10 @@ static void decode_mc6_mce(struct mce *m) | |||
672 | 681 | ||
673 | pr_emerg(HW_ERR "MC6 Error: "); | 682 | pr_emerg(HW_ERR "MC6 Error: "); |
674 | 683 | ||
675 | switch (xec) { | 684 | if (xec > 0x5) |
676 | case 0x0: | ||
677 | pr_cont("Hardware Assertion"); | ||
678 | break; | ||
679 | |||
680 | case 0x1: | ||
681 | pr_cont("Free List"); | ||
682 | break; | ||
683 | |||
684 | case 0x2: | ||
685 | pr_cont("Physical Register File"); | ||
686 | break; | ||
687 | |||
688 | case 0x3: | ||
689 | pr_cont("Retire Queue"); | ||
690 | break; | ||
691 | |||
692 | case 0x4: | ||
693 | pr_cont("Scheduler table"); | ||
694 | break; | ||
695 | |||
696 | case 0x5: | ||
697 | pr_cont("Status Register File"); | ||
698 | break; | ||
699 | |||
700 | default: | ||
701 | goto wrong_mc6_mce; | 685 | goto wrong_mc6_mce; |
702 | break; | ||
703 | } | ||
704 | |||
705 | pr_cont(" parity error.\n"); | ||
706 | 686 | ||
687 | pr_cont("%s parity error.\n", mc6_mce_desc[xec]); | ||
707 | return; | 688 | return; |
708 | 689 | ||
709 | wrong_mc6_mce: | 690 | wrong_mc6_mce: |
@@ -800,7 +781,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) | |||
800 | pr_cont("]: 0x%016llx\n", m->status); | 781 | pr_cont("]: 0x%016llx\n", m->status); |
801 | 782 | ||
802 | if (m->status & MCI_STATUS_ADDRV) | 783 | if (m->status & MCI_STATUS_ADDRV) |
803 | pr_emerg(HW_ERR "MC%d_ADDR: 0x%016llx\n", m->bank, m->addr); | 784 | pr_emerg(HW_ERR "MC%d Error Address: 0x%016llx\n", m->bank, m->addr); |
804 | 785 | ||
805 | if (!fam_ops) | 786 | if (!fam_ops) |
806 | goto err_code; | 787 | goto err_code; |
diff --git a/drivers/edac/mce_amd_inj.c b/drivers/edac/mce_amd_inj.c index 5e46a9fea31b..0bd91a802c67 100644 --- a/drivers/edac/mce_amd_inj.c +++ b/drivers/edac/mce_amd_inj.c | |||
@@ -1,173 +1,262 @@ | |||
1 | /* | 1 | /* |
2 | * A simple MCE injection facility for testing the MCE decoding code. This | 2 | * A simple MCE injection facility for testing different aspects of the RAS |
3 | * driver should be built as module so that it can be loaded on production | 3 | * code. This driver should be built as module so that it can be loaded |
4 | * kernels for testing purposes. | 4 | * on production kernels for testing purposes. |
5 | * | 5 | * |
6 | * This file may be distributed under the terms of the GNU General Public | 6 | * This file may be distributed under the terms of the GNU General Public |
7 | * License version 2. | 7 | * License version 2. |
8 | * | 8 | * |
9 | * Copyright (c) 2010: Borislav Petkov <bp@alien8.de> | 9 | * Copyright (c) 2010-14: Borislav Petkov <bp@alien8.de> |
10 | * Advanced Micro Devices Inc. | 10 | * Advanced Micro Devices Inc. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/kobject.h> | 13 | #include <linux/kobject.h> |
14 | #include <linux/debugfs.h> | ||
14 | #include <linux/device.h> | 15 | #include <linux/device.h> |
15 | #include <linux/edac.h> | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/cpu.h> | ||
17 | #include <asm/mce.h> | 18 | #include <asm/mce.h> |
18 | 19 | ||
19 | #include "mce_amd.h" | 20 | #include "mce_amd.h" |
20 | 21 | ||
21 | struct edac_mce_attr { | ||
22 | struct attribute attr; | ||
23 | ssize_t (*show) (struct kobject *kobj, struct edac_mce_attr *attr, char *buf); | ||
24 | ssize_t (*store)(struct kobject *kobj, struct edac_mce_attr *attr, | ||
25 | const char *buf, size_t count); | ||
26 | }; | ||
27 | |||
28 | #define EDAC_MCE_ATTR(_name, _mode, _show, _store) \ | ||
29 | static struct edac_mce_attr mce_attr_##_name = __ATTR(_name, _mode, _show, _store) | ||
30 | |||
31 | static struct kobject *mce_kobj; | ||
32 | |||
33 | /* | 22 | /* |
34 | * Collect all the MCi_XXX settings | 23 | * Collect all the MCi_XXX settings |
35 | */ | 24 | */ |
36 | static struct mce i_mce; | 25 | static struct mce i_mce; |
26 | static struct dentry *dfs_inj; | ||
37 | 27 | ||
38 | #define MCE_INJECT_STORE(reg) \ | 28 | #define MCE_INJECT_SET(reg) \ |
39 | static ssize_t edac_inject_##reg##_store(struct kobject *kobj, \ | 29 | static int inj_##reg##_set(void *data, u64 val) \ |
40 | struct edac_mce_attr *attr, \ | ||
41 | const char *data, size_t count)\ | ||
42 | { \ | 30 | { \ |
43 | int ret = 0; \ | 31 | struct mce *m = (struct mce *)data; \ |
44 | unsigned long value; \ | ||
45 | \ | ||
46 | ret = kstrtoul(data, 16, &value); \ | ||
47 | if (ret < 0) \ | ||
48 | printk(KERN_ERR "Error writing MCE " #reg " field.\n"); \ | ||
49 | \ | 32 | \ |
50 | i_mce.reg = value; \ | 33 | m->reg = val; \ |
51 | \ | 34 | return 0; \ |
52 | return count; \ | ||
53 | } | 35 | } |
54 | 36 | ||
55 | MCE_INJECT_STORE(status); | 37 | MCE_INJECT_SET(status); |
56 | MCE_INJECT_STORE(misc); | 38 | MCE_INJECT_SET(misc); |
57 | MCE_INJECT_STORE(addr); | 39 | MCE_INJECT_SET(addr); |
58 | 40 | ||
59 | #define MCE_INJECT_SHOW(reg) \ | 41 | #define MCE_INJECT_GET(reg) \ |
60 | static ssize_t edac_inject_##reg##_show(struct kobject *kobj, \ | 42 | static int inj_##reg##_get(void *data, u64 *val) \ |
61 | struct edac_mce_attr *attr, \ | ||
62 | char *buf) \ | ||
63 | { \ | 43 | { \ |
64 | return sprintf(buf, "0x%016llx\n", i_mce.reg); \ | 44 | struct mce *m = (struct mce *)data; \ |
45 | \ | ||
46 | *val = m->reg; \ | ||
47 | return 0; \ | ||
65 | } | 48 | } |
66 | 49 | ||
67 | MCE_INJECT_SHOW(status); | 50 | MCE_INJECT_GET(status); |
68 | MCE_INJECT_SHOW(misc); | 51 | MCE_INJECT_GET(misc); |
69 | MCE_INJECT_SHOW(addr); | 52 | MCE_INJECT_GET(addr); |
70 | 53 | ||
71 | EDAC_MCE_ATTR(status, 0644, edac_inject_status_show, edac_inject_status_store); | 54 | DEFINE_SIMPLE_ATTRIBUTE(status_fops, inj_status_get, inj_status_set, "%llx\n"); |
72 | EDAC_MCE_ATTR(misc, 0644, edac_inject_misc_show, edac_inject_misc_store); | 55 | DEFINE_SIMPLE_ATTRIBUTE(misc_fops, inj_misc_get, inj_misc_set, "%llx\n"); |
73 | EDAC_MCE_ATTR(addr, 0644, edac_inject_addr_show, edac_inject_addr_store); | 56 | DEFINE_SIMPLE_ATTRIBUTE(addr_fops, inj_addr_get, inj_addr_set, "%llx\n"); |
74 | 57 | ||
75 | /* | 58 | /* |
76 | * This denotes into which bank we're injecting and triggers | 59 | * Caller needs to be make sure this cpu doesn't disappear |
77 | * the injection, at the same time. | 60 | * from under us, i.e.: get_cpu/put_cpu. |
78 | */ | 61 | */ |
79 | static ssize_t edac_inject_bank_store(struct kobject *kobj, | 62 | static int toggle_hw_mce_inject(unsigned int cpu, bool enable) |
80 | struct edac_mce_attr *attr, | ||
81 | const char *data, size_t count) | ||
82 | { | 63 | { |
83 | int ret = 0; | 64 | u32 l, h; |
84 | unsigned long value; | 65 | int err; |
85 | 66 | ||
86 | ret = kstrtoul(data, 10, &value); | 67 | err = rdmsr_on_cpu(cpu, MSR_K7_HWCR, &l, &h); |
87 | if (ret < 0) { | 68 | if (err) { |
88 | printk(KERN_ERR "Invalid bank value!\n"); | 69 | pr_err("%s: error reading HWCR\n", __func__); |
89 | return -EINVAL; | 70 | return err; |
90 | } | 71 | } |
91 | 72 | ||
92 | if (value > 5) | 73 | enable ? (l |= BIT(18)) : (l &= ~BIT(18)); |
93 | if (boot_cpu_data.x86 != 0x15 || value > 6) { | ||
94 | printk(KERN_ERR "Non-existent MCE bank: %lu\n", value); | ||
95 | return -EINVAL; | ||
96 | } | ||
97 | 74 | ||
98 | i_mce.bank = value; | 75 | err = wrmsr_on_cpu(cpu, MSR_K7_HWCR, l, h); |
76 | if (err) | ||
77 | pr_err("%s: error writing HWCR\n", __func__); | ||
99 | 78 | ||
100 | amd_decode_mce(NULL, 0, &i_mce); | 79 | return err; |
80 | } | ||
101 | 81 | ||
102 | return count; | 82 | static int flags_get(void *data, u64 *val) |
83 | { | ||
84 | struct mce *m = (struct mce *)data; | ||
85 | |||
86 | *val = m->inject_flags; | ||
87 | |||
88 | return 0; | ||
103 | } | 89 | } |
104 | 90 | ||
105 | static ssize_t edac_inject_bank_show(struct kobject *kobj, | 91 | static int flags_set(void *data, u64 val) |
106 | struct edac_mce_attr *attr, char *buf) | ||
107 | { | 92 | { |
108 | return sprintf(buf, "%d\n", i_mce.bank); | 93 | struct mce *m = (struct mce *)data; |
94 | |||
95 | m->inject_flags = (u8)val; | ||
96 | return 0; | ||
109 | } | 97 | } |
110 | 98 | ||
111 | EDAC_MCE_ATTR(bank, 0644, edac_inject_bank_show, edac_inject_bank_store); | 99 | DEFINE_SIMPLE_ATTRIBUTE(flags_fops, flags_get, flags_set, "%llu\n"); |
112 | 100 | ||
113 | static struct edac_mce_attr *sysfs_attrs[] = { &mce_attr_status, &mce_attr_misc, | 101 | /* |
114 | &mce_attr_addr, &mce_attr_bank | 102 | * On which CPU to inject? |
115 | }; | 103 | */ |
104 | MCE_INJECT_GET(extcpu); | ||
116 | 105 | ||
117 | static int __init edac_init_mce_inject(void) | 106 | static int inj_extcpu_set(void *data, u64 val) |
118 | { | 107 | { |
119 | struct bus_type *edac_subsys = NULL; | 108 | struct mce *m = (struct mce *)data; |
120 | int i, err = 0; | ||
121 | 109 | ||
122 | edac_subsys = edac_get_sysfs_subsys(); | 110 | if (val >= nr_cpu_ids || !cpu_online(val)) { |
123 | if (!edac_subsys) | 111 | pr_err("%s: Invalid CPU: %llu\n", __func__, val); |
124 | return -EINVAL; | 112 | return -EINVAL; |
113 | } | ||
114 | m->extcpu = val; | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | DEFINE_SIMPLE_ATTRIBUTE(extcpu_fops, inj_extcpu_get, inj_extcpu_set, "%llu\n"); | ||
125 | 119 | ||
126 | mce_kobj = kobject_create_and_add("mce", &edac_subsys->dev_root->kobj); | 120 | static void trigger_mce(void *info) |
127 | if (!mce_kobj) { | 121 | { |
128 | printk(KERN_ERR "Error creating a mce kset.\n"); | 122 | asm volatile("int $18"); |
129 | err = -ENOMEM; | 123 | } |
130 | goto err_mce_kobj; | 124 | |
125 | static void do_inject(void) | ||
126 | { | ||
127 | u64 mcg_status = 0; | ||
128 | unsigned int cpu = i_mce.extcpu; | ||
129 | u8 b = i_mce.bank; | ||
130 | |||
131 | if (!(i_mce.inject_flags & MCJ_EXCEPTION)) { | ||
132 | amd_decode_mce(NULL, 0, &i_mce); | ||
133 | return; | ||
131 | } | 134 | } |
132 | 135 | ||
133 | for (i = 0; i < ARRAY_SIZE(sysfs_attrs); i++) { | 136 | get_online_cpus(); |
134 | err = sysfs_create_file(mce_kobj, &sysfs_attrs[i]->attr); | 137 | if (!cpu_online(cpu)) |
135 | if (err) { | 138 | goto err; |
136 | printk(KERN_ERR "Error creating %s in sysfs.\n", | 139 | |
137 | sysfs_attrs[i]->attr.name); | 140 | /* prep MCE global settings for the injection */ |
138 | goto err_sysfs_create; | 141 | mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV; |
142 | |||
143 | if (!(i_mce.status & MCI_STATUS_PCC)) | ||
144 | mcg_status |= MCG_STATUS_RIPV; | ||
145 | |||
146 | toggle_hw_mce_inject(cpu, true); | ||
147 | |||
148 | wrmsr_on_cpu(cpu, MSR_IA32_MCG_STATUS, | ||
149 | (u32)mcg_status, (u32)(mcg_status >> 32)); | ||
150 | |||
151 | wrmsr_on_cpu(cpu, MSR_IA32_MCx_STATUS(b), | ||
152 | (u32)i_mce.status, (u32)(i_mce.status >> 32)); | ||
153 | |||
154 | wrmsr_on_cpu(cpu, MSR_IA32_MCx_ADDR(b), | ||
155 | (u32)i_mce.addr, (u32)(i_mce.addr >> 32)); | ||
156 | |||
157 | wrmsr_on_cpu(cpu, MSR_IA32_MCx_MISC(b), | ||
158 | (u32)i_mce.misc, (u32)(i_mce.misc >> 32)); | ||
159 | |||
160 | toggle_hw_mce_inject(cpu, false); | ||
161 | |||
162 | smp_call_function_single(cpu, trigger_mce, NULL, 0); | ||
163 | |||
164 | err: | ||
165 | put_online_cpus(); | ||
166 | |||
167 | } | ||
168 | |||
169 | /* | ||
170 | * This denotes into which bank we're injecting and triggers | ||
171 | * the injection, at the same time. | ||
172 | */ | ||
173 | static int inj_bank_set(void *data, u64 val) | ||
174 | { | ||
175 | struct mce *m = (struct mce *)data; | ||
176 | |||
177 | if (val > 5) { | ||
178 | if (boot_cpu_data.x86 != 0x15 || val > 6) { | ||
179 | pr_err("Non-existent MCE bank: %llu\n", val); | ||
180 | return -EINVAL; | ||
139 | } | 181 | } |
140 | } | 182 | } |
141 | return 0; | ||
142 | 183 | ||
143 | err_sysfs_create: | 184 | m->bank = val; |
144 | while (--i >= 0) | 185 | do_inject(); |
145 | sysfs_remove_file(mce_kobj, &sysfs_attrs[i]->attr); | ||
146 | 186 | ||
147 | kobject_del(mce_kobj); | 187 | return 0; |
188 | } | ||
148 | 189 | ||
149 | err_mce_kobj: | 190 | static int inj_bank_get(void *data, u64 *val) |
150 | edac_put_sysfs_subsys(); | 191 | { |
192 | struct mce *m = (struct mce *)data; | ||
151 | 193 | ||
152 | return err; | 194 | *val = m->bank; |
195 | return 0; | ||
153 | } | 196 | } |
154 | 197 | ||
155 | static void __exit edac_exit_mce_inject(void) | 198 | DEFINE_SIMPLE_ATTRIBUTE(bank_fops, inj_bank_get, inj_bank_set, "%llu\n"); |
199 | |||
200 | struct dfs_node { | ||
201 | char *name; | ||
202 | struct dentry *d; | ||
203 | const struct file_operations *fops; | ||
204 | } dfs_fls[] = { | ||
205 | { .name = "status", .fops = &status_fops }, | ||
206 | { .name = "misc", .fops = &misc_fops }, | ||
207 | { .name = "addr", .fops = &addr_fops }, | ||
208 | { .name = "bank", .fops = &bank_fops }, | ||
209 | { .name = "flags", .fops = &flags_fops }, | ||
210 | { .name = "cpu", .fops = &extcpu_fops }, | ||
211 | }; | ||
212 | |||
213 | static int __init init_mce_inject(void) | ||
156 | { | 214 | { |
157 | int i; | 215 | int i; |
158 | 216 | ||
159 | for (i = 0; i < ARRAY_SIZE(sysfs_attrs); i++) | 217 | dfs_inj = debugfs_create_dir("mce-inject", NULL); |
160 | sysfs_remove_file(mce_kobj, &sysfs_attrs[i]->attr); | 218 | if (!dfs_inj) |
219 | return -EINVAL; | ||
220 | |||
221 | for (i = 0; i < ARRAY_SIZE(dfs_fls); i++) { | ||
222 | dfs_fls[i].d = debugfs_create_file(dfs_fls[i].name, | ||
223 | S_IRUSR | S_IWUSR, | ||
224 | dfs_inj, | ||
225 | &i_mce, | ||
226 | dfs_fls[i].fops); | ||
227 | |||
228 | if (!dfs_fls[i].d) | ||
229 | goto err_dfs_add; | ||
230 | } | ||
231 | |||
232 | return 0; | ||
233 | |||
234 | err_dfs_add: | ||
235 | while (--i >= 0) | ||
236 | debugfs_remove(dfs_fls[i].d); | ||
161 | 237 | ||
162 | kobject_del(mce_kobj); | 238 | debugfs_remove(dfs_inj); |
239 | dfs_inj = NULL; | ||
163 | 240 | ||
164 | edac_put_sysfs_subsys(); | 241 | return -ENOMEM; |
165 | } | 242 | } |
166 | 243 | ||
167 | module_init(edac_init_mce_inject); | 244 | static void __exit exit_mce_inject(void) |
168 | module_exit(edac_exit_mce_inject); | 245 | { |
246 | int i; | ||
247 | |||
248 | for (i = 0; i < ARRAY_SIZE(dfs_fls); i++) | ||
249 | debugfs_remove(dfs_fls[i].d); | ||
250 | |||
251 | memset(&dfs_fls, 0, sizeof(dfs_fls)); | ||
252 | |||
253 | debugfs_remove(dfs_inj); | ||
254 | dfs_inj = NULL; | ||
255 | } | ||
256 | module_init(init_mce_inject); | ||
257 | module_exit(exit_mce_inject); | ||
169 | 258 | ||
170 | MODULE_LICENSE("GPL"); | 259 | MODULE_LICENSE("GPL"); |
171 | MODULE_AUTHOR("Borislav Petkov <bp@alien8.de>"); | 260 | MODULE_AUTHOR("Borislav Petkov <bp@alien8.de>"); |
172 | MODULE_AUTHOR("AMD Inc."); | 261 | MODULE_AUTHOR("AMD Inc."); |
173 | MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding"); | 262 | MODULE_DESCRIPTION("MCE injection facility for RAS testing"); |
diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c index 542fad70e360..6366e880f978 100644 --- a/drivers/edac/mv64x60_edac.c +++ b/drivers/edac/mv64x60_edac.c | |||
@@ -178,7 +178,7 @@ static int mv64x60_pci_err_probe(struct platform_device *pdev) | |||
178 | res = devm_request_irq(&pdev->dev, | 178 | res = devm_request_irq(&pdev->dev, |
179 | pdata->irq, | 179 | pdata->irq, |
180 | mv64x60_pci_isr, | 180 | mv64x60_pci_isr, |
181 | IRQF_DISABLED, | 181 | 0, |
182 | "[EDAC] PCI err", | 182 | "[EDAC] PCI err", |
183 | pci); | 183 | pci); |
184 | if (res < 0) { | 184 | if (res < 0) { |
@@ -345,7 +345,7 @@ static int mv64x60_sram_err_probe(struct platform_device *pdev) | |||
345 | res = devm_request_irq(&pdev->dev, | 345 | res = devm_request_irq(&pdev->dev, |
346 | pdata->irq, | 346 | pdata->irq, |
347 | mv64x60_sram_isr, | 347 | mv64x60_sram_isr, |
348 | IRQF_DISABLED, | 348 | 0, |
349 | "[EDAC] SRAM err", | 349 | "[EDAC] SRAM err", |
350 | edac_dev); | 350 | edac_dev); |
351 | if (res < 0) { | 351 | if (res < 0) { |
@@ -540,7 +540,7 @@ static int mv64x60_cpu_err_probe(struct platform_device *pdev) | |||
540 | res = devm_request_irq(&pdev->dev, | 540 | res = devm_request_irq(&pdev->dev, |
541 | pdata->irq, | 541 | pdata->irq, |
542 | mv64x60_cpu_isr, | 542 | mv64x60_cpu_isr, |
543 | IRQF_DISABLED, | 543 | 0, |
544 | "[EDAC] CPU err", | 544 | "[EDAC] CPU err", |
545 | edac_dev); | 545 | edac_dev); |
546 | if (res < 0) { | 546 | if (res < 0) { |
@@ -800,7 +800,7 @@ static int mv64x60_mc_err_probe(struct platform_device *pdev) | |||
800 | res = devm_request_irq(&pdev->dev, | 800 | res = devm_request_irq(&pdev->dev, |
801 | pdata->irq, | 801 | pdata->irq, |
802 | mv64x60_mc_isr, | 802 | mv64x60_mc_isr, |
803 | IRQF_DISABLED, | 803 | 0, |
804 | "[EDAC] MC err", | 804 | "[EDAC] MC err", |
805 | mci); | 805 | mci); |
806 | if (res < 0) { | 806 | if (res < 0) { |
diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c index 0f04d5ead521..41593539cec4 100644 --- a/drivers/edac/ppc4xx_edac.c +++ b/drivers/edac/ppc4xx_edac.c | |||
@@ -1120,7 +1120,7 @@ static int ppc4xx_edac_register_irq(struct platform_device *op, | |||
1120 | 1120 | ||
1121 | status = request_irq(ded_irq, | 1121 | status = request_irq(ded_irq, |
1122 | ppc4xx_edac_isr, | 1122 | ppc4xx_edac_isr, |
1123 | IRQF_DISABLED, | 1123 | 0, |
1124 | "[EDAC] MC ECCDED", | 1124 | "[EDAC] MC ECCDED", |
1125 | mci); | 1125 | mci); |
1126 | 1126 | ||
@@ -1134,7 +1134,7 @@ static int ppc4xx_edac_register_irq(struct platform_device *op, | |||
1134 | 1134 | ||
1135 | status = request_irq(sec_irq, | 1135 | status = request_irq(sec_irq, |
1136 | ppc4xx_edac_isr, | 1136 | ppc4xx_edac_isr, |
1137 | IRQF_DISABLED, | 1137 | 0, |
1138 | "[EDAC] MC ECCSEC", | 1138 | "[EDAC] MC ECCSEC", |
1139 | mci); | 1139 | mci); |
1140 | 1140 | ||
diff --git a/drivers/edac/x38_edac.c b/drivers/edac/x38_edac.c index e644b52c287c..7c5cdc62f31c 100644 --- a/drivers/edac/x38_edac.c +++ b/drivers/edac/x38_edac.c | |||
@@ -500,8 +500,7 @@ fail1: | |||
500 | pci_unregister_driver(&x38_driver); | 500 | pci_unregister_driver(&x38_driver); |
501 | 501 | ||
502 | fail0: | 502 | fail0: |
503 | if (mci_pdev) | 503 | pci_dev_put(mci_pdev); |
504 | pci_dev_put(mci_pdev); | ||
505 | 504 | ||
506 | return pci_rc; | 505 | return pci_rc; |
507 | } | 506 | } |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 0959ca9b6b27..23dfd5f59b39 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -905,4 +905,16 @@ config GPIO_VIPERBOARD | |||
905 | River Tech's viperboard.h for detailed meaning | 905 | River Tech's viperboard.h for detailed meaning |
906 | of the module parameters. | 906 | of the module parameters. |
907 | 907 | ||
908 | config GPIO_DLN2 | ||
909 | tristate "Diolan DLN2 GPIO support" | ||
910 | depends on MFD_DLN2 | ||
911 | select GPIOLIB_IRQCHIP | ||
912 | |||
913 | help | ||
914 | Select this option to enable GPIO driver for the Diolan DLN2 | ||
915 | board. | ||
916 | |||
917 | This driver can also be built as a module. If so, the module | ||
918 | will be called gpio-dln2. | ||
919 | |||
908 | endif | 920 | endif |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index e5d346cf3b6e..e60677b8ccb4 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -26,6 +26,7 @@ obj-$(CONFIG_GPIO_CRYSTAL_COVE) += gpio-crystalcove.o | |||
26 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o | 26 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o |
27 | obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o | 27 | obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o |
28 | obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o | 28 | obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o |
29 | obj-$(CONFIG_GPIO_DLN2) += gpio-dln2.o | ||
29 | obj-$(CONFIG_GPIO_DWAPB) += gpio-dwapb.o | 30 | obj-$(CONFIG_GPIO_DWAPB) += gpio-dwapb.o |
30 | obj-$(CONFIG_GPIO_EM) += gpio-em.o | 31 | obj-$(CONFIG_GPIO_EM) += gpio-em.o |
31 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | 32 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o |
diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c new file mode 100644 index 000000000000..978b51eae2ec --- /dev/null +++ b/drivers/gpio/gpio-dln2.c | |||
@@ -0,0 +1,553 @@ | |||
1 | /* | ||
2 | * Driver for the Diolan DLN-2 USB-GPIO adapter | ||
3 | * | ||
4 | * Copyright (c) 2014 Intel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/irqdomain.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/irqchip/chained_irq.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/gpio/driver.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/mfd/dln2.h> | ||
22 | |||
23 | #define DLN2_GPIO_ID 0x01 | ||
24 | |||
25 | #define DLN2_GPIO_GET_PIN_COUNT DLN2_CMD(0x01, DLN2_GPIO_ID) | ||
26 | #define DLN2_GPIO_SET_DEBOUNCE DLN2_CMD(0x04, DLN2_GPIO_ID) | ||
27 | #define DLN2_GPIO_GET_DEBOUNCE DLN2_CMD(0x05, DLN2_GPIO_ID) | ||
28 | #define DLN2_GPIO_PORT_GET_VAL DLN2_CMD(0x06, DLN2_GPIO_ID) | ||
29 | #define DLN2_GPIO_PIN_GET_VAL DLN2_CMD(0x0B, DLN2_GPIO_ID) | ||
30 | #define DLN2_GPIO_PIN_SET_OUT_VAL DLN2_CMD(0x0C, DLN2_GPIO_ID) | ||
31 | #define DLN2_GPIO_PIN_GET_OUT_VAL DLN2_CMD(0x0D, DLN2_GPIO_ID) | ||
32 | #define DLN2_GPIO_CONDITION_MET_EV DLN2_CMD(0x0F, DLN2_GPIO_ID) | ||
33 | #define DLN2_GPIO_PIN_ENABLE DLN2_CMD(0x10, DLN2_GPIO_ID) | ||
34 | #define DLN2_GPIO_PIN_DISABLE DLN2_CMD(0x11, DLN2_GPIO_ID) | ||
35 | #define DLN2_GPIO_PIN_SET_DIRECTION DLN2_CMD(0x13, DLN2_GPIO_ID) | ||
36 | #define DLN2_GPIO_PIN_GET_DIRECTION DLN2_CMD(0x14, DLN2_GPIO_ID) | ||
37 | #define DLN2_GPIO_PIN_SET_EVENT_CFG DLN2_CMD(0x1E, DLN2_GPIO_ID) | ||
38 | #define DLN2_GPIO_PIN_GET_EVENT_CFG DLN2_CMD(0x1F, DLN2_GPIO_ID) | ||
39 | |||
40 | #define DLN2_GPIO_EVENT_NONE 0 | ||
41 | #define DLN2_GPIO_EVENT_CHANGE 1 | ||
42 | #define DLN2_GPIO_EVENT_LVL_HIGH 2 | ||
43 | #define DLN2_GPIO_EVENT_LVL_LOW 3 | ||
44 | #define DLN2_GPIO_EVENT_CHANGE_RISING 0x11 | ||
45 | #define DLN2_GPIO_EVENT_CHANGE_FALLING 0x21 | ||
46 | #define DLN2_GPIO_EVENT_MASK 0x0F | ||
47 | |||
48 | #define DLN2_GPIO_MAX_PINS 32 | ||
49 | |||
50 | struct dln2_irq_work { | ||
51 | struct work_struct work; | ||
52 | struct dln2_gpio *dln2; | ||
53 | int pin; | ||
54 | int type; | ||
55 | }; | ||
56 | |||
57 | struct dln2_gpio { | ||
58 | struct platform_device *pdev; | ||
59 | struct gpio_chip gpio; | ||
60 | |||
61 | /* | ||
62 | * Cache pin direction to save us one transfer, since the hardware has | ||
63 | * separate commands to read the in and out values. | ||
64 | */ | ||
65 | DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS); | ||
66 | |||
67 | DECLARE_BITMAP(irqs_masked, DLN2_GPIO_MAX_PINS); | ||
68 | DECLARE_BITMAP(irqs_enabled, DLN2_GPIO_MAX_PINS); | ||
69 | DECLARE_BITMAP(irqs_pending, DLN2_GPIO_MAX_PINS); | ||
70 | struct dln2_irq_work *irq_work; | ||
71 | }; | ||
72 | |||
73 | struct dln2_gpio_pin { | ||
74 | __le16 pin; | ||
75 | }; | ||
76 | |||
77 | struct dln2_gpio_pin_val { | ||
78 | __le16 pin __packed; | ||
79 | u8 value; | ||
80 | }; | ||
81 | |||
82 | static int dln2_gpio_get_pin_count(struct platform_device *pdev) | ||
83 | { | ||
84 | int ret; | ||
85 | __le16 count; | ||
86 | int len = sizeof(count); | ||
87 | |||
88 | ret = dln2_transfer_rx(pdev, DLN2_GPIO_GET_PIN_COUNT, &count, &len); | ||
89 | if (ret < 0) | ||
90 | return ret; | ||
91 | if (len < sizeof(count)) | ||
92 | return -EPROTO; | ||
93 | |||
94 | return le16_to_cpu(count); | ||
95 | } | ||
96 | |||
97 | static int dln2_gpio_pin_cmd(struct dln2_gpio *dln2, int cmd, unsigned pin) | ||
98 | { | ||
99 | struct dln2_gpio_pin req = { | ||
100 | .pin = cpu_to_le16(pin), | ||
101 | }; | ||
102 | |||
103 | return dln2_transfer_tx(dln2->pdev, cmd, &req, sizeof(req)); | ||
104 | } | ||
105 | |||
106 | static int dln2_gpio_pin_val(struct dln2_gpio *dln2, int cmd, unsigned int pin) | ||
107 | { | ||
108 | int ret; | ||
109 | struct dln2_gpio_pin req = { | ||
110 | .pin = cpu_to_le16(pin), | ||
111 | }; | ||
112 | struct dln2_gpio_pin_val rsp; | ||
113 | int len = sizeof(rsp); | ||
114 | |||
115 | ret = dln2_transfer(dln2->pdev, cmd, &req, sizeof(req), &rsp, &len); | ||
116 | if (ret < 0) | ||
117 | return ret; | ||
118 | if (len < sizeof(rsp) || req.pin != rsp.pin) | ||
119 | return -EPROTO; | ||
120 | |||
121 | return rsp.value; | ||
122 | } | ||
123 | |||
124 | static int dln2_gpio_pin_get_in_val(struct dln2_gpio *dln2, unsigned int pin) | ||
125 | { | ||
126 | int ret; | ||
127 | |||
128 | ret = dln2_gpio_pin_val(dln2, DLN2_GPIO_PIN_GET_VAL, pin); | ||
129 | if (ret < 0) | ||
130 | return ret; | ||
131 | return !!ret; | ||
132 | } | ||
133 | |||
134 | static int dln2_gpio_pin_get_out_val(struct dln2_gpio *dln2, unsigned int pin) | ||
135 | { | ||
136 | int ret; | ||
137 | |||
138 | ret = dln2_gpio_pin_val(dln2, DLN2_GPIO_PIN_GET_OUT_VAL, pin); | ||
139 | if (ret < 0) | ||
140 | return ret; | ||
141 | return !!ret; | ||
142 | } | ||
143 | |||
144 | static void dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2, | ||
145 | unsigned int pin, int value) | ||
146 | { | ||
147 | struct dln2_gpio_pin_val req = { | ||
148 | .pin = cpu_to_le16(pin), | ||
149 | .value = value, | ||
150 | }; | ||
151 | |||
152 | dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req, | ||
153 | sizeof(req)); | ||
154 | } | ||
155 | |||
156 | #define DLN2_GPIO_DIRECTION_IN 0 | ||
157 | #define DLN2_GPIO_DIRECTION_OUT 1 | ||
158 | |||
159 | static int dln2_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
160 | { | ||
161 | struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio); | ||
162 | struct dln2_gpio_pin req = { | ||
163 | .pin = cpu_to_le16(offset), | ||
164 | }; | ||
165 | struct dln2_gpio_pin_val rsp; | ||
166 | int len = sizeof(rsp); | ||
167 | int ret; | ||
168 | |||
169 | ret = dln2_gpio_pin_cmd(dln2, DLN2_GPIO_PIN_ENABLE, offset); | ||
170 | if (ret < 0) | ||
171 | return ret; | ||
172 | |||
173 | /* cache the pin direction */ | ||
174 | ret = dln2_transfer(dln2->pdev, DLN2_GPIO_PIN_GET_DIRECTION, | ||
175 | &req, sizeof(req), &rsp, &len); | ||
176 | if (ret < 0) | ||
177 | return ret; | ||
178 | if (len < sizeof(rsp) || req.pin != rsp.pin) { | ||
179 | ret = -EPROTO; | ||
180 | goto out_disable; | ||
181 | } | ||
182 | |||
183 | switch (rsp.value) { | ||
184 | case DLN2_GPIO_DIRECTION_IN: | ||
185 | clear_bit(offset, dln2->output_enabled); | ||
186 | return 0; | ||
187 | case DLN2_GPIO_DIRECTION_OUT: | ||
188 | set_bit(offset, dln2->output_enabled); | ||
189 | return 0; | ||
190 | default: | ||
191 | ret = -EPROTO; | ||
192 | goto out_disable; | ||
193 | } | ||
194 | |||
195 | out_disable: | ||
196 | dln2_gpio_pin_cmd(dln2, DLN2_GPIO_PIN_DISABLE, offset); | ||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | static void dln2_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
201 | { | ||
202 | struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio); | ||
203 | |||
204 | dln2_gpio_pin_cmd(dln2, DLN2_GPIO_PIN_DISABLE, offset); | ||
205 | } | ||
206 | |||
207 | static int dln2_gpio_get_direction(struct gpio_chip *chip, unsigned offset) | ||
208 | { | ||
209 | struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio); | ||
210 | |||
211 | if (test_bit(offset, dln2->output_enabled)) | ||
212 | return GPIOF_DIR_OUT; | ||
213 | |||
214 | return GPIOF_DIR_IN; | ||
215 | } | ||
216 | |||
217 | static int dln2_gpio_get(struct gpio_chip *chip, unsigned int offset) | ||
218 | { | ||
219 | struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio); | ||
220 | int dir; | ||
221 | |||
222 | dir = dln2_gpio_get_direction(chip, offset); | ||
223 | if (dir < 0) | ||
224 | return dir; | ||
225 | |||
226 | if (dir == GPIOF_DIR_IN) | ||
227 | return dln2_gpio_pin_get_in_val(dln2, offset); | ||
228 | |||
229 | return dln2_gpio_pin_get_out_val(dln2, offset); | ||
230 | } | ||
231 | |||
232 | static void dln2_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
233 | { | ||
234 | struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio); | ||
235 | |||
236 | dln2_gpio_pin_set_out_val(dln2, offset, value); | ||
237 | } | ||
238 | |||
239 | static int dln2_gpio_set_direction(struct gpio_chip *chip, unsigned offset, | ||
240 | unsigned dir) | ||
241 | { | ||
242 | struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio); | ||
243 | struct dln2_gpio_pin_val req = { | ||
244 | .pin = cpu_to_le16(offset), | ||
245 | .value = dir, | ||
246 | }; | ||
247 | int ret; | ||
248 | |||
249 | ret = dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_DIRECTION, | ||
250 | &req, sizeof(req)); | ||
251 | if (ret < 0) | ||
252 | return ret; | ||
253 | |||
254 | if (dir == DLN2_GPIO_DIRECTION_OUT) | ||
255 | set_bit(offset, dln2->output_enabled); | ||
256 | else | ||
257 | clear_bit(offset, dln2->output_enabled); | ||
258 | |||
259 | return ret; | ||
260 | } | ||
261 | |||
262 | static int dln2_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
263 | { | ||
264 | return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_IN); | ||
265 | } | ||
266 | |||
267 | static int dln2_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
268 | int value) | ||
269 | { | ||
270 | return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_OUT); | ||
271 | } | ||
272 | |||
273 | static int dln2_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, | ||
274 | unsigned debounce) | ||
275 | { | ||
276 | struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio); | ||
277 | __le32 duration = cpu_to_le32(debounce); | ||
278 | |||
279 | return dln2_transfer_tx(dln2->pdev, DLN2_GPIO_SET_DEBOUNCE, | ||
280 | &duration, sizeof(duration)); | ||
281 | } | ||
282 | |||
283 | static int dln2_gpio_set_event_cfg(struct dln2_gpio *dln2, unsigned pin, | ||
284 | unsigned type, unsigned period) | ||
285 | { | ||
286 | struct { | ||
287 | __le16 pin; | ||
288 | u8 type; | ||
289 | __le16 period; | ||
290 | } __packed req = { | ||
291 | .pin = cpu_to_le16(pin), | ||
292 | .type = type, | ||
293 | .period = cpu_to_le16(period), | ||
294 | }; | ||
295 | |||
296 | return dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_EVENT_CFG, | ||
297 | &req, sizeof(req)); | ||
298 | } | ||
299 | |||
300 | static void dln2_irq_work(struct work_struct *w) | ||
301 | { | ||
302 | struct dln2_irq_work *iw = container_of(w, struct dln2_irq_work, work); | ||
303 | struct dln2_gpio *dln2 = iw->dln2; | ||
304 | u8 type = iw->type & DLN2_GPIO_EVENT_MASK; | ||
305 | |||
306 | if (test_bit(iw->pin, dln2->irqs_enabled)) | ||
307 | dln2_gpio_set_event_cfg(dln2, iw->pin, type, 0); | ||
308 | else | ||
309 | dln2_gpio_set_event_cfg(dln2, iw->pin, DLN2_GPIO_EVENT_NONE, 0); | ||
310 | } | ||
311 | |||
312 | static void dln2_irq_enable(struct irq_data *irqd) | ||
313 | { | ||
314 | struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); | ||
315 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); | ||
316 | int pin = irqd_to_hwirq(irqd); | ||
317 | |||
318 | set_bit(pin, dln2->irqs_enabled); | ||
319 | schedule_work(&dln2->irq_work[pin].work); | ||
320 | } | ||
321 | |||
322 | static void dln2_irq_disable(struct irq_data *irqd) | ||
323 | { | ||
324 | struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); | ||
325 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); | ||
326 | int pin = irqd_to_hwirq(irqd); | ||
327 | |||
328 | clear_bit(pin, dln2->irqs_enabled); | ||
329 | schedule_work(&dln2->irq_work[pin].work); | ||
330 | } | ||
331 | |||
332 | static void dln2_irq_mask(struct irq_data *irqd) | ||
333 | { | ||
334 | struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); | ||
335 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); | ||
336 | int pin = irqd_to_hwirq(irqd); | ||
337 | |||
338 | set_bit(pin, dln2->irqs_masked); | ||
339 | } | ||
340 | |||
341 | static void dln2_irq_unmask(struct irq_data *irqd) | ||
342 | { | ||
343 | struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); | ||
344 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); | ||
345 | struct device *dev = dln2->gpio.dev; | ||
346 | int pin = irqd_to_hwirq(irqd); | ||
347 | |||
348 | if (test_and_clear_bit(pin, dln2->irqs_pending)) { | ||
349 | int irq; | ||
350 | |||
351 | irq = irq_find_mapping(dln2->gpio.irqdomain, pin); | ||
352 | if (!irq) { | ||
353 | dev_err(dev, "pin %d not mapped to IRQ\n", pin); | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | generic_handle_irq(irq); | ||
358 | } | ||
359 | } | ||
360 | |||
361 | static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) | ||
362 | { | ||
363 | struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); | ||
364 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); | ||
365 | int pin = irqd_to_hwirq(irqd); | ||
366 | |||
367 | switch (type) { | ||
368 | case IRQ_TYPE_LEVEL_HIGH: | ||
369 | dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_HIGH; | ||
370 | break; | ||
371 | case IRQ_TYPE_LEVEL_LOW: | ||
372 | dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_LOW; | ||
373 | break; | ||
374 | case IRQ_TYPE_EDGE_BOTH: | ||
375 | dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE; | ||
376 | break; | ||
377 | case IRQ_TYPE_EDGE_RISING: | ||
378 | dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_RISING; | ||
379 | break; | ||
380 | case IRQ_TYPE_EDGE_FALLING: | ||
381 | dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_FALLING; | ||
382 | break; | ||
383 | default: | ||
384 | return -EINVAL; | ||
385 | } | ||
386 | |||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | static struct irq_chip dln2_gpio_irqchip = { | ||
391 | .name = "dln2-irq", | ||
392 | .irq_enable = dln2_irq_enable, | ||
393 | .irq_disable = dln2_irq_disable, | ||
394 | .irq_mask = dln2_irq_mask, | ||
395 | .irq_unmask = dln2_irq_unmask, | ||
396 | .irq_set_type = dln2_irq_set_type, | ||
397 | }; | ||
398 | |||
399 | static void dln2_gpio_event(struct platform_device *pdev, u16 echo, | ||
400 | const void *data, int len) | ||
401 | { | ||
402 | int pin, irq; | ||
403 | const struct { | ||
404 | __le16 count; | ||
405 | __u8 type; | ||
406 | __le16 pin; | ||
407 | __u8 value; | ||
408 | } __packed *event = data; | ||
409 | struct dln2_gpio *dln2 = platform_get_drvdata(pdev); | ||
410 | |||
411 | if (len < sizeof(*event)) { | ||
412 | dev_err(dln2->gpio.dev, "short event message\n"); | ||
413 | return; | ||
414 | } | ||
415 | |||
416 | pin = le16_to_cpu(event->pin); | ||
417 | if (pin >= dln2->gpio.ngpio) { | ||
418 | dev_err(dln2->gpio.dev, "out of bounds pin %d\n", pin); | ||
419 | return; | ||
420 | } | ||
421 | |||
422 | irq = irq_find_mapping(dln2->gpio.irqdomain, pin); | ||
423 | if (!irq) { | ||
424 | dev_err(dln2->gpio.dev, "pin %d not mapped to IRQ\n", pin); | ||
425 | return; | ||
426 | } | ||
427 | |||
428 | if (!test_bit(pin, dln2->irqs_enabled)) | ||
429 | return; | ||
430 | if (test_bit(pin, dln2->irqs_masked)) { | ||
431 | set_bit(pin, dln2->irqs_pending); | ||
432 | return; | ||
433 | } | ||
434 | |||
435 | switch (dln2->irq_work[pin].type) { | ||
436 | case DLN2_GPIO_EVENT_CHANGE_RISING: | ||
437 | if (event->value) | ||
438 | generic_handle_irq(irq); | ||
439 | break; | ||
440 | case DLN2_GPIO_EVENT_CHANGE_FALLING: | ||
441 | if (!event->value) | ||
442 | generic_handle_irq(irq); | ||
443 | break; | ||
444 | default: | ||
445 | generic_handle_irq(irq); | ||
446 | } | ||
447 | } | ||
448 | |||
449 | static int dln2_gpio_probe(struct platform_device *pdev) | ||
450 | { | ||
451 | struct dln2_gpio *dln2; | ||
452 | struct device *dev = &pdev->dev; | ||
453 | int pins; | ||
454 | int i, ret; | ||
455 | |||
456 | pins = dln2_gpio_get_pin_count(pdev); | ||
457 | if (pins < 0) { | ||
458 | dev_err(dev, "failed to get pin count: %d\n", pins); | ||
459 | return pins; | ||
460 | } | ||
461 | if (pins > DLN2_GPIO_MAX_PINS) { | ||
462 | pins = DLN2_GPIO_MAX_PINS; | ||
463 | dev_warn(dev, "clamping pins to %d\n", DLN2_GPIO_MAX_PINS); | ||
464 | } | ||
465 | |||
466 | dln2 = devm_kzalloc(&pdev->dev, sizeof(*dln2), GFP_KERNEL); | ||
467 | if (!dln2) | ||
468 | return -ENOMEM; | ||
469 | |||
470 | dln2->irq_work = devm_kcalloc(&pdev->dev, pins, | ||
471 | sizeof(struct dln2_irq_work), GFP_KERNEL); | ||
472 | if (!dln2->irq_work) | ||
473 | return -ENOMEM; | ||
474 | for (i = 0; i < pins; i++) { | ||
475 | INIT_WORK(&dln2->irq_work[i].work, dln2_irq_work); | ||
476 | dln2->irq_work[i].pin = i; | ||
477 | dln2->irq_work[i].dln2 = dln2; | ||
478 | } | ||
479 | |||
480 | dln2->pdev = pdev; | ||
481 | |||
482 | dln2->gpio.label = "dln2"; | ||
483 | dln2->gpio.dev = dev; | ||
484 | dln2->gpio.owner = THIS_MODULE; | ||
485 | dln2->gpio.base = -1; | ||
486 | dln2->gpio.ngpio = pins; | ||
487 | dln2->gpio.exported = true; | ||
488 | dln2->gpio.can_sleep = true; | ||
489 | dln2->gpio.irq_not_threaded = true; | ||
490 | dln2->gpio.set = dln2_gpio_set; | ||
491 | dln2->gpio.get = dln2_gpio_get; | ||
492 | dln2->gpio.request = dln2_gpio_request; | ||
493 | dln2->gpio.free = dln2_gpio_free; | ||
494 | dln2->gpio.get_direction = dln2_gpio_get_direction; | ||
495 | dln2->gpio.direction_input = dln2_gpio_direction_input; | ||
496 | dln2->gpio.direction_output = dln2_gpio_direction_output; | ||
497 | dln2->gpio.set_debounce = dln2_gpio_set_debounce; | ||
498 | |||
499 | platform_set_drvdata(pdev, dln2); | ||
500 | |||
501 | ret = gpiochip_add(&dln2->gpio); | ||
502 | if (ret < 0) { | ||
503 | dev_err(dev, "failed to add gpio chip: %d\n", ret); | ||
504 | goto out; | ||
505 | } | ||
506 | |||
507 | ret = gpiochip_irqchip_add(&dln2->gpio, &dln2_gpio_irqchip, 0, | ||
508 | handle_simple_irq, IRQ_TYPE_NONE); | ||
509 | if (ret < 0) { | ||
510 | dev_err(dev, "failed to add irq chip: %d\n", ret); | ||
511 | goto out_gpiochip_remove; | ||
512 | } | ||
513 | |||
514 | ret = dln2_register_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV, | ||
515 | dln2_gpio_event); | ||
516 | if (ret) { | ||
517 | dev_err(dev, "failed to register event cb: %d\n", ret); | ||
518 | goto out_gpiochip_remove; | ||
519 | } | ||
520 | |||
521 | return 0; | ||
522 | |||
523 | out_gpiochip_remove: | ||
524 | gpiochip_remove(&dln2->gpio); | ||
525 | out: | ||
526 | return ret; | ||
527 | } | ||
528 | |||
529 | static int dln2_gpio_remove(struct platform_device *pdev) | ||
530 | { | ||
531 | struct dln2_gpio *dln2 = platform_get_drvdata(pdev); | ||
532 | int i; | ||
533 | |||
534 | dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV); | ||
535 | for (i = 0; i < dln2->gpio.ngpio; i++) | ||
536 | flush_work(&dln2->irq_work[i].work); | ||
537 | gpiochip_remove(&dln2->gpio); | ||
538 | |||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | static struct platform_driver dln2_gpio_driver = { | ||
543 | .driver.name = "dln2-gpio", | ||
544 | .probe = dln2_gpio_probe, | ||
545 | .remove = dln2_gpio_remove, | ||
546 | }; | ||
547 | |||
548 | module_platform_driver(dln2_gpio_driver); | ||
549 | |||
550 | MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com"); | ||
551 | MODULE_DESCRIPTION("Driver for the Diolan DLN2 GPIO interface"); | ||
552 | MODULE_LICENSE("GPL v2"); | ||
553 | MODULE_ALIAS("platform:dln2-gpio"); | ||
diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index ae0f6466eb09..abdcf58935f5 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c | |||
@@ -262,7 +262,7 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) | |||
262 | tc3589x_gpio->chip = template_chip; | 262 | tc3589x_gpio->chip = template_chip; |
263 | tc3589x_gpio->chip.ngpio = tc3589x->num_gpio; | 263 | tc3589x_gpio->chip.ngpio = tc3589x->num_gpio; |
264 | tc3589x_gpio->chip.dev = &pdev->dev; | 264 | tc3589x_gpio->chip.dev = &pdev->dev; |
265 | tc3589x_gpio->chip.base = (pdata) ? pdata->gpio_base : -1; | 265 | tc3589x_gpio->chip.base = -1; |
266 | 266 | ||
267 | #ifdef CONFIG_OF_GPIO | 267 | #ifdef CONFIG_OF_GPIO |
268 | tc3589x_gpio->chip.of_node = np; | 268 | tc3589x_gpio->chip.of_node = np; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8bcdb981d540..9cb5c95d5898 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4325,7 +4325,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) | |||
4325 | ironlake_fdi_disable(crtc); | 4325 | ironlake_fdi_disable(crtc); |
4326 | 4326 | ||
4327 | ironlake_disable_pch_transcoder(dev_priv, pipe); | 4327 | ironlake_disable_pch_transcoder(dev_priv, pipe); |
4328 | intel_set_pch_fifo_underrun_reporting(dev, pipe, true); | ||
4329 | 4328 | ||
4330 | if (HAS_PCH_CPT(dev)) { | 4329 | if (HAS_PCH_CPT(dev)) { |
4331 | /* disable TRANS_DP_CTL */ | 4330 | /* disable TRANS_DP_CTL */ |
@@ -4389,7 +4388,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) | |||
4389 | 4388 | ||
4390 | if (intel_crtc->config.has_pch_encoder) { | 4389 | if (intel_crtc->config.has_pch_encoder) { |
4391 | lpt_disable_pch_transcoder(dev_priv); | 4390 | lpt_disable_pch_transcoder(dev_priv); |
4392 | intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true); | ||
4393 | intel_ddi_fdi_disable(crtc); | 4391 | intel_ddi_fdi_disable(crtc); |
4394 | } | 4392 | } |
4395 | 4393 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index a6bd1422e38f..c0bbf2172446 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -899,6 +899,17 @@ void intel_lvds_init(struct drm_device *dev) | |||
899 | int pipe; | 899 | int pipe; |
900 | u8 pin; | 900 | u8 pin; |
901 | 901 | ||
902 | /* | ||
903 | * Unlock registers and just leave them unlocked. Do this before | ||
904 | * checking quirk lists to avoid bogus WARNINGs. | ||
905 | */ | ||
906 | if (HAS_PCH_SPLIT(dev)) { | ||
907 | I915_WRITE(PCH_PP_CONTROL, | ||
908 | I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
909 | } else { | ||
910 | I915_WRITE(PP_CONTROL, | ||
911 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
912 | } | ||
902 | if (!intel_lvds_supported(dev)) | 913 | if (!intel_lvds_supported(dev)) |
903 | return; | 914 | return; |
904 | 915 | ||
@@ -1097,17 +1108,6 @@ out: | |||
1097 | lvds_encoder->a3_power = I915_READ(lvds_encoder->reg) & | 1108 | lvds_encoder->a3_power = I915_READ(lvds_encoder->reg) & |
1098 | LVDS_A3_POWER_MASK; | 1109 | LVDS_A3_POWER_MASK; |
1099 | 1110 | ||
1100 | /* | ||
1101 | * Unlock registers and just | ||
1102 | * leave them unlocked | ||
1103 | */ | ||
1104 | if (HAS_PCH_SPLIT(dev)) { | ||
1105 | I915_WRITE(PCH_PP_CONTROL, | ||
1106 | I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
1107 | } else { | ||
1108 | I915_WRITE(PP_CONTROL, | ||
1109 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
1110 | } | ||
1111 | lvds_connector->lid_notifier.notifier_call = intel_lid_notify; | 1111 | lvds_connector->lid_notifier.notifier_call = intel_lid_notify; |
1112 | if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) { | 1112 | if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) { |
1113 | DRM_DEBUG_KMS("lid notifier registration failed\n"); | 1113 | DRM_DEBUG_KMS("lid notifier registration failed\n"); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index cd05677ad4b7..72a40f95d048 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c | |||
@@ -218,7 +218,6 @@ nvc0_identify(struct nouveau_device *device) | |||
218 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; | 218 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; |
219 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 219 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
220 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 220 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
221 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; | ||
222 | device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; | 221 | device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; |
223 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; | 222 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; |
224 | break; | 223 | break; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c index 5ae6a43893b5..1931057f9962 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c | |||
@@ -551,8 +551,8 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) | |||
551 | } | 551 | } |
552 | 552 | ||
553 | if (status & 0x40000000) { | 553 | if (status & 0x40000000) { |
554 | nouveau_fifo_uevent(&priv->base); | ||
555 | nv_wr32(priv, 0x002100, 0x40000000); | 554 | nv_wr32(priv, 0x002100, 0x40000000); |
555 | nouveau_fifo_uevent(&priv->base); | ||
556 | status &= ~0x40000000; | 556 | status &= ~0x40000000; |
557 | } | 557 | } |
558 | } | 558 | } |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index 1fe1f8fbda0c..074d434c3077 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c | |||
@@ -740,6 +740,8 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn) | |||
740 | u32 inte = nv_rd32(priv, 0x002628); | 740 | u32 inte = nv_rd32(priv, 0x002628); |
741 | u32 unkn; | 741 | u32 unkn; |
742 | 742 | ||
743 | nv_wr32(priv, 0x0025a8 + (engn * 0x04), intr); | ||
744 | |||
743 | for (unkn = 0; unkn < 8; unkn++) { | 745 | for (unkn = 0; unkn < 8; unkn++) { |
744 | u32 ints = (intr >> (unkn * 0x04)) & inte; | 746 | u32 ints = (intr >> (unkn * 0x04)) & inte; |
745 | if (ints & 0x1) { | 747 | if (ints & 0x1) { |
@@ -751,8 +753,6 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn) | |||
751 | nv_mask(priv, 0x002628, ints, 0); | 753 | nv_mask(priv, 0x002628, ints, 0); |
752 | } | 754 | } |
753 | } | 755 | } |
754 | |||
755 | nv_wr32(priv, 0x0025a8 + (engn * 0x04), intr); | ||
756 | } | 756 | } |
757 | 757 | ||
758 | static void | 758 | static void |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index d2f0fd39c145..f8734eb74eaa 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | |||
@@ -952,8 +952,8 @@ nve0_fifo_intr(struct nouveau_subdev *subdev) | |||
952 | } | 952 | } |
953 | 953 | ||
954 | if (stat & 0x80000000) { | 954 | if (stat & 0x80000000) { |
955 | nve0_fifo_intr_engine(priv); | ||
956 | nv_wr32(priv, 0x002100, 0x80000000); | 955 | nv_wr32(priv, 0x002100, 0x80000000); |
956 | nve0_fifo_intr_engine(priv); | ||
957 | stat &= ~0x80000000; | 957 | stat &= ~0x80000000; |
958 | } | 958 | } |
959 | 959 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 57238076049f..62b97c4eef8d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -629,7 +629,6 @@ int nouveau_pmops_suspend(struct device *dev) | |||
629 | 629 | ||
630 | pci_save_state(pdev); | 630 | pci_save_state(pdev); |
631 | pci_disable_device(pdev); | 631 | pci_disable_device(pdev); |
632 | pci_ignore_hotplug(pdev); | ||
633 | pci_set_power_state(pdev, PCI_D3hot); | 632 | pci_set_power_state(pdev, PCI_D3hot); |
634 | return 0; | 633 | return 0; |
635 | } | 634 | } |
@@ -933,6 +932,7 @@ static int nouveau_pmops_runtime_suspend(struct device *dev) | |||
933 | ret = nouveau_do_suspend(drm_dev, true); | 932 | ret = nouveau_do_suspend(drm_dev, true); |
934 | pci_save_state(pdev); | 933 | pci_save_state(pdev); |
935 | pci_disable_device(pdev); | 934 | pci_disable_device(pdev); |
935 | pci_ignore_hotplug(pdev); | ||
936 | pci_set_power_state(pdev, PCI_D3cold); | 936 | pci_set_power_state(pdev, PCI_D3cold); |
937 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; | 937 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; |
938 | return ret; | 938 | return ret; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 515cd9aebb99..f32a434724e3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -52,20 +52,24 @@ nouveau_fctx(struct nouveau_fence *fence) | |||
52 | return container_of(fence->base.lock, struct nouveau_fence_chan, lock); | 52 | return container_of(fence->base.lock, struct nouveau_fence_chan, lock); |
53 | } | 53 | } |
54 | 54 | ||
55 | static void | 55 | static int |
56 | nouveau_fence_signal(struct nouveau_fence *fence) | 56 | nouveau_fence_signal(struct nouveau_fence *fence) |
57 | { | 57 | { |
58 | int drop = 0; | ||
59 | |||
58 | fence_signal_locked(&fence->base); | 60 | fence_signal_locked(&fence->base); |
59 | list_del(&fence->head); | 61 | list_del(&fence->head); |
62 | rcu_assign_pointer(fence->channel, NULL); | ||
60 | 63 | ||
61 | if (test_bit(FENCE_FLAG_USER_BITS, &fence->base.flags)) { | 64 | if (test_bit(FENCE_FLAG_USER_BITS, &fence->base.flags)) { |
62 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); | 65 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); |
63 | 66 | ||
64 | if (!--fctx->notify_ref) | 67 | if (!--fctx->notify_ref) |
65 | nvif_notify_put(&fctx->notify); | 68 | drop = 1; |
66 | } | 69 | } |
67 | 70 | ||
68 | fence_put(&fence->base); | 71 | fence_put(&fence->base); |
72 | return drop; | ||
69 | } | 73 | } |
70 | 74 | ||
71 | static struct nouveau_fence * | 75 | static struct nouveau_fence * |
@@ -88,16 +92,23 @@ nouveau_fence_context_del(struct nouveau_fence_chan *fctx) | |||
88 | { | 92 | { |
89 | struct nouveau_fence *fence; | 93 | struct nouveau_fence *fence; |
90 | 94 | ||
91 | nvif_notify_fini(&fctx->notify); | ||
92 | |||
93 | spin_lock_irq(&fctx->lock); | 95 | spin_lock_irq(&fctx->lock); |
94 | while (!list_empty(&fctx->pending)) { | 96 | while (!list_empty(&fctx->pending)) { |
95 | fence = list_entry(fctx->pending.next, typeof(*fence), head); | 97 | fence = list_entry(fctx->pending.next, typeof(*fence), head); |
96 | 98 | ||
97 | nouveau_fence_signal(fence); | 99 | if (nouveau_fence_signal(fence)) |
98 | fence->channel = NULL; | 100 | nvif_notify_put(&fctx->notify); |
99 | } | 101 | } |
100 | spin_unlock_irq(&fctx->lock); | 102 | spin_unlock_irq(&fctx->lock); |
103 | |||
104 | nvif_notify_fini(&fctx->notify); | ||
105 | fctx->dead = 1; | ||
106 | |||
107 | /* | ||
108 | * Ensure that all accesses to fence->channel complete before freeing | ||
109 | * the channel. | ||
110 | */ | ||
111 | synchronize_rcu(); | ||
101 | } | 112 | } |
102 | 113 | ||
103 | static void | 114 | static void |
@@ -112,21 +123,23 @@ nouveau_fence_context_free(struct nouveau_fence_chan *fctx) | |||
112 | kref_put(&fctx->fence_ref, nouveau_fence_context_put); | 123 | kref_put(&fctx->fence_ref, nouveau_fence_context_put); |
113 | } | 124 | } |
114 | 125 | ||
115 | static void | 126 | static int |
116 | nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx) | 127 | nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx) |
117 | { | 128 | { |
118 | struct nouveau_fence *fence; | 129 | struct nouveau_fence *fence; |
119 | 130 | int drop = 0; | |
120 | u32 seq = fctx->read(chan); | 131 | u32 seq = fctx->read(chan); |
121 | 132 | ||
122 | while (!list_empty(&fctx->pending)) { | 133 | while (!list_empty(&fctx->pending)) { |
123 | fence = list_entry(fctx->pending.next, typeof(*fence), head); | 134 | fence = list_entry(fctx->pending.next, typeof(*fence), head); |
124 | 135 | ||
125 | if ((int)(seq - fence->base.seqno) < 0) | 136 | if ((int)(seq - fence->base.seqno) < 0) |
126 | return; | 137 | break; |
127 | 138 | ||
128 | nouveau_fence_signal(fence); | 139 | drop |= nouveau_fence_signal(fence); |
129 | } | 140 | } |
141 | |||
142 | return drop; | ||
130 | } | 143 | } |
131 | 144 | ||
132 | static int | 145 | static int |
@@ -135,18 +148,21 @@ nouveau_fence_wait_uevent_handler(struct nvif_notify *notify) | |||
135 | struct nouveau_fence_chan *fctx = | 148 | struct nouveau_fence_chan *fctx = |
136 | container_of(notify, typeof(*fctx), notify); | 149 | container_of(notify, typeof(*fctx), notify); |
137 | unsigned long flags; | 150 | unsigned long flags; |
151 | int ret = NVIF_NOTIFY_KEEP; | ||
138 | 152 | ||
139 | spin_lock_irqsave(&fctx->lock, flags); | 153 | spin_lock_irqsave(&fctx->lock, flags); |
140 | if (!list_empty(&fctx->pending)) { | 154 | if (!list_empty(&fctx->pending)) { |
141 | struct nouveau_fence *fence; | 155 | struct nouveau_fence *fence; |
156 | struct nouveau_channel *chan; | ||
142 | 157 | ||
143 | fence = list_entry(fctx->pending.next, typeof(*fence), head); | 158 | fence = list_entry(fctx->pending.next, typeof(*fence), head); |
144 | nouveau_fence_update(fence->channel, fctx); | 159 | chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock)); |
160 | if (nouveau_fence_update(fence->channel, fctx)) | ||
161 | ret = NVIF_NOTIFY_DROP; | ||
145 | } | 162 | } |
146 | spin_unlock_irqrestore(&fctx->lock, flags); | 163 | spin_unlock_irqrestore(&fctx->lock, flags); |
147 | 164 | ||
148 | /* Always return keep here. NVIF refcount is handled with nouveau_fence_update */ | 165 | return ret; |
149 | return NVIF_NOTIFY_KEEP; | ||
150 | } | 166 | } |
151 | 167 | ||
152 | void | 168 | void |
@@ -262,7 +278,10 @@ nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan) | |||
262 | if (!ret) { | 278 | if (!ret) { |
263 | fence_get(&fence->base); | 279 | fence_get(&fence->base); |
264 | spin_lock_irq(&fctx->lock); | 280 | spin_lock_irq(&fctx->lock); |
265 | nouveau_fence_update(chan, fctx); | 281 | |
282 | if (nouveau_fence_update(chan, fctx)) | ||
283 | nvif_notify_put(&fctx->notify); | ||
284 | |||
266 | list_add_tail(&fence->head, &fctx->pending); | 285 | list_add_tail(&fence->head, &fctx->pending); |
267 | spin_unlock_irq(&fctx->lock); | 286 | spin_unlock_irq(&fctx->lock); |
268 | } | 287 | } |
@@ -276,13 +295,16 @@ nouveau_fence_done(struct nouveau_fence *fence) | |||
276 | if (fence->base.ops == &nouveau_fence_ops_legacy || | 295 | if (fence->base.ops == &nouveau_fence_ops_legacy || |
277 | fence->base.ops == &nouveau_fence_ops_uevent) { | 296 | fence->base.ops == &nouveau_fence_ops_uevent) { |
278 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); | 297 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); |
298 | struct nouveau_channel *chan; | ||
279 | unsigned long flags; | 299 | unsigned long flags; |
280 | 300 | ||
281 | if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->base.flags)) | 301 | if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->base.flags)) |
282 | return true; | 302 | return true; |
283 | 303 | ||
284 | spin_lock_irqsave(&fctx->lock, flags); | 304 | spin_lock_irqsave(&fctx->lock, flags); |
285 | nouveau_fence_update(fence->channel, fctx); | 305 | chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock)); |
306 | if (chan && nouveau_fence_update(chan, fctx)) | ||
307 | nvif_notify_put(&fctx->notify); | ||
286 | spin_unlock_irqrestore(&fctx->lock, flags); | 308 | spin_unlock_irqrestore(&fctx->lock, flags); |
287 | } | 309 | } |
288 | return fence_is_signaled(&fence->base); | 310 | return fence_is_signaled(&fence->base); |
@@ -387,12 +409,18 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool e | |||
387 | 409 | ||
388 | if (fence && (!exclusive || !fobj || !fobj->shared_count)) { | 410 | if (fence && (!exclusive || !fobj || !fobj->shared_count)) { |
389 | struct nouveau_channel *prev = NULL; | 411 | struct nouveau_channel *prev = NULL; |
412 | bool must_wait = true; | ||
390 | 413 | ||
391 | f = nouveau_local_fence(fence, chan->drm); | 414 | f = nouveau_local_fence(fence, chan->drm); |
392 | if (f) | 415 | if (f) { |
393 | prev = f->channel; | 416 | rcu_read_lock(); |
417 | prev = rcu_dereference(f->channel); | ||
418 | if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0)) | ||
419 | must_wait = false; | ||
420 | rcu_read_unlock(); | ||
421 | } | ||
394 | 422 | ||
395 | if (!prev || (prev != chan && (ret = fctx->sync(f, prev, chan)))) | 423 | if (must_wait) |
396 | ret = fence_wait(fence, intr); | 424 | ret = fence_wait(fence, intr); |
397 | 425 | ||
398 | return ret; | 426 | return ret; |
@@ -403,19 +431,22 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool e | |||
403 | 431 | ||
404 | for (i = 0; i < fobj->shared_count && !ret; ++i) { | 432 | for (i = 0; i < fobj->shared_count && !ret; ++i) { |
405 | struct nouveau_channel *prev = NULL; | 433 | struct nouveau_channel *prev = NULL; |
434 | bool must_wait = true; | ||
406 | 435 | ||
407 | fence = rcu_dereference_protected(fobj->shared[i], | 436 | fence = rcu_dereference_protected(fobj->shared[i], |
408 | reservation_object_held(resv)); | 437 | reservation_object_held(resv)); |
409 | 438 | ||
410 | f = nouveau_local_fence(fence, chan->drm); | 439 | f = nouveau_local_fence(fence, chan->drm); |
411 | if (f) | 440 | if (f) { |
412 | prev = f->channel; | 441 | rcu_read_lock(); |
442 | prev = rcu_dereference(f->channel); | ||
443 | if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0)) | ||
444 | must_wait = false; | ||
445 | rcu_read_unlock(); | ||
446 | } | ||
413 | 447 | ||
414 | if (!prev || (prev != chan && (ret = fctx->sync(f, prev, chan)))) | 448 | if (must_wait) |
415 | ret = fence_wait(fence, intr); | 449 | ret = fence_wait(fence, intr); |
416 | |||
417 | if (ret) | ||
418 | break; | ||
419 | } | 450 | } |
420 | 451 | ||
421 | return ret; | 452 | return ret; |
@@ -463,7 +494,7 @@ static const char *nouveau_fence_get_timeline_name(struct fence *f) | |||
463 | struct nouveau_fence *fence = from_fence(f); | 494 | struct nouveau_fence *fence = from_fence(f); |
464 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); | 495 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); |
465 | 496 | ||
466 | return fence->channel ? fctx->name : "dead channel"; | 497 | return !fctx->dead ? fctx->name : "dead channel"; |
467 | } | 498 | } |
468 | 499 | ||
469 | /* | 500 | /* |
@@ -476,9 +507,16 @@ static bool nouveau_fence_is_signaled(struct fence *f) | |||
476 | { | 507 | { |
477 | struct nouveau_fence *fence = from_fence(f); | 508 | struct nouveau_fence *fence = from_fence(f); |
478 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); | 509 | struct nouveau_fence_chan *fctx = nouveau_fctx(fence); |
479 | struct nouveau_channel *chan = fence->channel; | 510 | struct nouveau_channel *chan; |
511 | bool ret = false; | ||
512 | |||
513 | rcu_read_lock(); | ||
514 | chan = rcu_dereference(fence->channel); | ||
515 | if (chan) | ||
516 | ret = (int)(fctx->read(chan) - fence->base.seqno) >= 0; | ||
517 | rcu_read_unlock(); | ||
480 | 518 | ||
481 | return (int)(fctx->read(chan) - fence->base.seqno) >= 0; | 519 | return ret; |
482 | } | 520 | } |
483 | 521 | ||
484 | static bool nouveau_fence_no_signaling(struct fence *f) | 522 | static bool nouveau_fence_no_signaling(struct fence *f) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index 943b0b17b1fc..96e461c6f68f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h | |||
@@ -14,7 +14,7 @@ struct nouveau_fence { | |||
14 | 14 | ||
15 | bool sysmem; | 15 | bool sysmem; |
16 | 16 | ||
17 | struct nouveau_channel *channel; | 17 | struct nouveau_channel __rcu *channel; |
18 | unsigned long timeout; | 18 | unsigned long timeout; |
19 | }; | 19 | }; |
20 | 20 | ||
@@ -47,7 +47,7 @@ struct nouveau_fence_chan { | |||
47 | char name[32]; | 47 | char name[32]; |
48 | 48 | ||
49 | struct nvif_notify notify; | 49 | struct nvif_notify notify; |
50 | int notify_ref; | 50 | int notify_ref, dead; |
51 | }; | 51 | }; |
52 | 52 | ||
53 | struct nouveau_fence_priv { | 53 | struct nouveau_fence_priv { |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index a3e7aed7e680..6f377de099f9 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -251,22 +251,19 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority | |||
251 | 251 | ||
252 | static int radeon_cs_sync_rings(struct radeon_cs_parser *p) | 252 | static int radeon_cs_sync_rings(struct radeon_cs_parser *p) |
253 | { | 253 | { |
254 | int i, r = 0; | 254 | struct radeon_cs_reloc *reloc; |
255 | int r; | ||
255 | 256 | ||
256 | for (i = 0; i < p->nrelocs; i++) { | 257 | list_for_each_entry(reloc, &p->validated, tv.head) { |
257 | struct reservation_object *resv; | 258 | struct reservation_object *resv; |
258 | 259 | ||
259 | if (!p->relocs[i].robj) | 260 | resv = reloc->robj->tbo.resv; |
260 | continue; | ||
261 | |||
262 | resv = p->relocs[i].robj->tbo.resv; | ||
263 | r = radeon_semaphore_sync_resv(p->rdev, p->ib.semaphore, resv, | 261 | r = radeon_semaphore_sync_resv(p->rdev, p->ib.semaphore, resv, |
264 | p->relocs[i].tv.shared); | 262 | reloc->tv.shared); |
265 | |||
266 | if (r) | 263 | if (r) |
267 | break; | 264 | return r; |
268 | } | 265 | } |
269 | return r; | 266 | return 0; |
270 | } | 267 | } |
271 | 268 | ||
272 | /* XXX: note that this is called from the legacy UMS CS ioctl as well */ | 269 | /* XXX: note that this is called from the legacy UMS CS ioctl as well */ |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 8309b11e674d..03586763ee86 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -795,6 +795,8 @@ int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, | |||
795 | 795 | ||
796 | /* Get associated drm_crtc: */ | 796 | /* Get associated drm_crtc: */ |
797 | drmcrtc = &rdev->mode_info.crtcs[crtc]->base; | 797 | drmcrtc = &rdev->mode_info.crtcs[crtc]->base; |
798 | if (!drmcrtc) | ||
799 | return -EINVAL; | ||
798 | 800 | ||
799 | /* Helper routine in DRM core does all the work: */ | 801 | /* Helper routine in DRM core does all the work: */ |
800 | return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, | 802 | return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 99a960a4f302..4c0d786d5c7a 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -213,6 +213,13 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
213 | if (!(rdev->flags & RADEON_IS_PCIE)) | 213 | if (!(rdev->flags & RADEON_IS_PCIE)) |
214 | bo->flags &= ~(RADEON_GEM_GTT_WC | RADEON_GEM_GTT_UC); | 214 | bo->flags &= ~(RADEON_GEM_GTT_WC | RADEON_GEM_GTT_UC); |
215 | 215 | ||
216 | #ifdef CONFIG_X86_32 | ||
217 | /* XXX: Write-combined CPU mappings of GTT seem broken on 32-bit | ||
218 | * See https://bugs.freedesktop.org/show_bug.cgi?id=84627 | ||
219 | */ | ||
220 | bo->flags &= ~RADEON_GEM_GTT_WC; | ||
221 | #endif | ||
222 | |||
216 | radeon_ttm_placement_from_domain(bo, domain); | 223 | radeon_ttm_placement_from_domain(bo, domain); |
217 | /* Kernel allocation are uninterruptible */ | 224 | /* Kernel allocation are uninterruptible */ |
218 | down_read(&rdev->pm.mclk_lock); | 225 | down_read(&rdev->pm.mclk_lock); |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index e6d8e18dae97..6a58b6c723aa 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
@@ -641,9 +641,6 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
641 | goto err_stop_hw; | 641 | goto err_stop_hw; |
642 | } | 642 | } |
643 | sd->hid_sensor_hub_client_devs[ | 643 | sd->hid_sensor_hub_client_devs[ |
644 | sd->hid_sensor_client_cnt].id = | ||
645 | PLATFORM_DEVID_AUTO; | ||
646 | sd->hid_sensor_hub_client_devs[ | ||
647 | sd->hid_sensor_client_cnt].name = name; | 644 | sd->hid_sensor_client_cnt].name = name; |
648 | sd->hid_sensor_hub_client_devs[ | 645 | sd->hid_sensor_hub_client_devs[ |
649 | sd->hid_sensor_client_cnt].platform_data = | 646 | sd->hid_sensor_client_cnt].platform_data = |
@@ -659,8 +656,9 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
659 | if (last_hsdev) | 656 | if (last_hsdev) |
660 | last_hsdev->end_collection_index = i; | 657 | last_hsdev->end_collection_index = i; |
661 | 658 | ||
662 | ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, | 659 | ret = mfd_add_hotplug_devices(&hdev->dev, |
663 | sd->hid_sensor_client_cnt, NULL, 0, NULL); | 660 | sd->hid_sensor_hub_client_devs, |
661 | sd->hid_sensor_client_cnt); | ||
664 | if (ret < 0) | 662 | if (ret < 0) |
665 | goto err_stop_hw; | 663 | goto err_stop_hw; |
666 | 664 | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 5286d7ce1f9e..6529c09c46f0 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -1028,11 +1028,11 @@ config SENSORS_LM93 | |||
1028 | will be called lm93. | 1028 | will be called lm93. |
1029 | 1029 | ||
1030 | config SENSORS_LM95234 | 1030 | config SENSORS_LM95234 |
1031 | tristate "National Semiconductor LM95234" | 1031 | tristate "National Semiconductor LM95234 and compatibles" |
1032 | depends on I2C | 1032 | depends on I2C |
1033 | help | 1033 | help |
1034 | If you say yes here you get support for the LM95234 temperature | 1034 | If you say yes here you get support for the LM95233 and LM95234 |
1035 | sensor. | 1035 | temperature sensor chips. |
1036 | 1036 | ||
1037 | This driver can also be built as a module. If so, the module | 1037 | This driver can also be built as a module. If so, the module |
1038 | will be called lm95234. | 1038 | will be called lm95234. |
@@ -1048,10 +1048,11 @@ config SENSORS_LM95241 | |||
1048 | will be called lm95241. | 1048 | will be called lm95241. |
1049 | 1049 | ||
1050 | config SENSORS_LM95245 | 1050 | config SENSORS_LM95245 |
1051 | tristate "National Semiconductor LM95245 sensor chip" | 1051 | tristate "National Semiconductor LM95245 and compatibles" |
1052 | depends on I2C | 1052 | depends on I2C |
1053 | help | 1053 | help |
1054 | If you say yes here you get support for LM95245 sensor chip. | 1054 | If you say yes here you get support for LM95235 and LM95245 |
1055 | temperature sensor chips. | ||
1055 | 1056 | ||
1056 | This driver can also be built as a module. If so, the module | 1057 | This driver can also be built as a module. If so, the module |
1057 | will be called lm95245. | 1058 | will be called lm95245. |
@@ -1117,12 +1118,23 @@ config SENSORS_NCT6775 | |||
1117 | help | 1118 | help |
1118 | If you say yes here you get support for the hardware monitoring | 1119 | If you say yes here you get support for the hardware monitoring |
1119 | functionality of the Nuvoton NCT6106D, NCT6775F, NCT6776F, NCT6779D, | 1120 | functionality of the Nuvoton NCT6106D, NCT6775F, NCT6776F, NCT6779D, |
1120 | NCT6791D and compatible Super-I/O chips. This driver replaces the | 1121 | NCT6791D, NCT6792D and compatible Super-I/O chips. This driver |
1121 | w83627ehf driver for NCT6775F and NCT6776F. | 1122 | replaces the w83627ehf driver for NCT6775F and NCT6776F. |
1122 | 1123 | ||
1123 | This driver can also be built as a module. If so, the module | 1124 | This driver can also be built as a module. If so, the module |
1124 | will be called nct6775. | 1125 | will be called nct6775. |
1125 | 1126 | ||
1127 | config SENSORS_NCT7802 | ||
1128 | tristate "Nuvoton NCT7802Y" | ||
1129 | depends on I2C | ||
1130 | select REGMAP_I2C | ||
1131 | help | ||
1132 | If you say yes here you get support for the Nuvoton NCT7802Y | ||
1133 | hardware monitoring chip. | ||
1134 | |||
1135 | This driver can also be built as a module. If so, the module | ||
1136 | will be called nct7802. | ||
1137 | |||
1126 | config SENSORS_PCF8591 | 1138 | config SENSORS_PCF8591 |
1127 | tristate "Philips PCF8591 ADC/DAC" | 1139 | tristate "Philips PCF8591 ADC/DAC" |
1128 | depends on I2C | 1140 | depends on I2C |
@@ -1454,7 +1466,7 @@ config SENSORS_TMP401 | |||
1454 | depends on I2C | 1466 | depends on I2C |
1455 | help | 1467 | help |
1456 | If you say yes here you get support for Texas Instruments TMP401, | 1468 | If you say yes here you get support for Texas Instruments TMP401, |
1457 | TMP411, TMP431, and TMP432 temperature sensor chips. | 1469 | TMP411, TMP431, TMP432 and TMP435 temperature sensor chips. |
1458 | 1470 | ||
1459 | This driver can also be built as a module. If so, the module | 1471 | This driver can also be built as a module. If so, the module |
1460 | will be called tmp401. | 1472 | will be called tmp401. |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index c90a7611efaa..67280643bcf0 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -118,6 +118,7 @@ obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o | |||
118 | obj-$(CONFIG_SENSORS_MENF21BMC_HWMON) += menf21bmc_hwmon.o | 118 | obj-$(CONFIG_SENSORS_MENF21BMC_HWMON) += menf21bmc_hwmon.o |
119 | obj-$(CONFIG_SENSORS_NCT6683) += nct6683.o | 119 | obj-$(CONFIG_SENSORS_NCT6683) += nct6683.o |
120 | obj-$(CONFIG_SENSORS_NCT6775) += nct6775.o | 120 | obj-$(CONFIG_SENSORS_NCT6775) += nct6775.o |
121 | obj-$(CONFIG_SENSORS_NCT7802) += nct7802.o | ||
121 | obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o | 122 | obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o |
122 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o | 123 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o |
123 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o | 124 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o |
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 4efa1734bdad..36abf814b8c7 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c | |||
@@ -79,7 +79,7 @@ static ssize_t show_fan_alarm(struct device *dev, | |||
79 | { | 79 | { |
80 | struct gpio_fan_data *fan_data = dev_get_drvdata(dev); | 80 | struct gpio_fan_data *fan_data = dev_get_drvdata(dev); |
81 | struct gpio_fan_alarm *alarm = fan_data->alarm; | 81 | struct gpio_fan_alarm *alarm = fan_data->alarm; |
82 | int value = gpio_get_value(alarm->gpio); | 82 | int value = gpio_get_value_cansleep(alarm->gpio); |
83 | 83 | ||
84 | if (alarm->active_low) | 84 | if (alarm->active_low) |
85 | value = !value; | 85 | value = !value; |
@@ -131,7 +131,7 @@ static void __set_fan_ctrl(struct gpio_fan_data *fan_data, int ctrl_val) | |||
131 | int i; | 131 | int i; |
132 | 132 | ||
133 | for (i = 0; i < fan_data->num_ctrl; i++) | 133 | for (i = 0; i < fan_data->num_ctrl; i++) |
134 | gpio_set_value(fan_data->ctrl[i], (ctrl_val >> i) & 1); | 134 | gpio_set_value_cansleep(fan_data->ctrl[i], (ctrl_val >> i) & 1); |
135 | } | 135 | } |
136 | 136 | ||
137 | static int __get_fan_ctrl(struct gpio_fan_data *fan_data) | 137 | static int __get_fan_ctrl(struct gpio_fan_data *fan_data) |
@@ -142,7 +142,7 @@ static int __get_fan_ctrl(struct gpio_fan_data *fan_data) | |||
142 | for (i = 0; i < fan_data->num_ctrl; i++) { | 142 | for (i = 0; i < fan_data->num_ctrl; i++) { |
143 | int value; | 143 | int value; |
144 | 144 | ||
145 | value = gpio_get_value(fan_data->ctrl[i]); | 145 | value = gpio_get_value_cansleep(fan_data->ctrl[i]); |
146 | ctrl_val |= (value << i); | 146 | ctrl_val |= (value << i); |
147 | } | 147 | } |
148 | return ctrl_val; | 148 | return ctrl_val; |
@@ -369,7 +369,8 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, | |||
369 | if (err) | 369 | if (err) |
370 | return err; | 370 | return err; |
371 | 371 | ||
372 | err = gpio_direction_output(ctrl[i], gpio_get_value(ctrl[i])); | 372 | err = gpio_direction_output(ctrl[i], |
373 | gpio_get_value_cansleep(ctrl[i])); | ||
373 | if (err) | 374 | if (err) |
374 | return err; | 375 | return err; |
375 | } | 376 | } |
@@ -549,6 +550,14 @@ static int gpio_fan_probe(struct platform_device *pdev) | |||
549 | return 0; | 550 | return 0; |
550 | } | 551 | } |
551 | 552 | ||
553 | static void gpio_fan_shutdown(struct platform_device *pdev) | ||
554 | { | ||
555 | struct gpio_fan_data *fan_data = dev_get_drvdata(&pdev->dev); | ||
556 | |||
557 | if (fan_data->ctrl) | ||
558 | set_fan_speed(fan_data, 0); | ||
559 | } | ||
560 | |||
552 | #ifdef CONFIG_PM_SLEEP | 561 | #ifdef CONFIG_PM_SLEEP |
553 | static int gpio_fan_suspend(struct device *dev) | 562 | static int gpio_fan_suspend(struct device *dev) |
554 | { | 563 | { |
@@ -580,6 +589,7 @@ static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume); | |||
580 | 589 | ||
581 | static struct platform_driver gpio_fan_driver = { | 590 | static struct platform_driver gpio_fan_driver = { |
582 | .probe = gpio_fan_probe, | 591 | .probe = gpio_fan_probe, |
592 | .shutdown = gpio_fan_shutdown, | ||
583 | .driver = { | 593 | .driver = { |
584 | .name = "gpio-fan", | 594 | .name = "gpio-fan", |
585 | .pm = GPIO_FAN_PM, | 595 | .pm = GPIO_FAN_PM, |
diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c index 6a30eeea94be..7c2c7be182f2 100644 --- a/drivers/hwmon/ibmpowernv.c +++ b/drivers/hwmon/ibmpowernv.c | |||
@@ -74,9 +74,6 @@ struct platform_data { | |||
74 | u32 sensors_count; /* Total count of sensors from each group */ | 74 | u32 sensors_count; /* Total count of sensors from each group */ |
75 | }; | 75 | }; |
76 | 76 | ||
77 | /* Platform device representing all the ibmpowernv sensors */ | ||
78 | static struct platform_device *pdevice; | ||
79 | |||
80 | static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr, | 77 | static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr, |
81 | char *buf) | 78 | char *buf) |
82 | { | 79 | { |
@@ -99,7 +96,7 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr, | |||
99 | return sprintf(buf, "%u\n", x); | 96 | return sprintf(buf, "%u\n", x); |
100 | } | 97 | } |
101 | 98 | ||
102 | static int __init get_sensor_index_attr(const char *name, u32 *index, | 99 | static int get_sensor_index_attr(const char *name, u32 *index, |
103 | char *attr) | 100 | char *attr) |
104 | { | 101 | { |
105 | char *hash_pos = strchr(name, '#'); | 102 | char *hash_pos = strchr(name, '#'); |
@@ -136,7 +133,7 @@ static int __init get_sensor_index_attr(const char *name, u32 *index, | |||
136 | * which need to be mapped as fan2_input, temp1_max respectively before | 133 | * which need to be mapped as fan2_input, temp1_max respectively before |
137 | * populating them inside hwmon device class. | 134 | * populating them inside hwmon device class. |
138 | */ | 135 | */ |
139 | static int __init create_hwmon_attr_name(struct device *dev, enum sensors type, | 136 | static int create_hwmon_attr_name(struct device *dev, enum sensors type, |
140 | const char *node_name, | 137 | const char *node_name, |
141 | char *hwmon_attr_name) | 138 | char *hwmon_attr_name) |
142 | { | 139 | { |
@@ -172,7 +169,7 @@ static int __init create_hwmon_attr_name(struct device *dev, enum sensors type, | |||
172 | return 0; | 169 | return 0; |
173 | } | 170 | } |
174 | 171 | ||
175 | static int __init populate_attr_groups(struct platform_device *pdev) | 172 | static int populate_attr_groups(struct platform_device *pdev) |
176 | { | 173 | { |
177 | struct platform_data *pdata = platform_get_drvdata(pdev); | 174 | struct platform_data *pdata = platform_get_drvdata(pdev); |
178 | const struct attribute_group **pgroups = pdata->attr_groups; | 175 | const struct attribute_group **pgroups = pdata->attr_groups; |
@@ -180,11 +177,6 @@ static int __init populate_attr_groups(struct platform_device *pdev) | |||
180 | enum sensors type; | 177 | enum sensors type; |
181 | 178 | ||
182 | opal = of_find_node_by_path("/ibm,opal/sensors"); | 179 | opal = of_find_node_by_path("/ibm,opal/sensors"); |
183 | if (!opal) { | ||
184 | dev_dbg(&pdev->dev, "Opal node 'sensors' not found\n"); | ||
185 | return -ENODEV; | ||
186 | } | ||
187 | |||
188 | for_each_child_of_node(opal, np) { | 180 | for_each_child_of_node(opal, np) { |
189 | if (np->name == NULL) | 181 | if (np->name == NULL) |
190 | continue; | 182 | continue; |
@@ -221,7 +213,7 @@ static int __init populate_attr_groups(struct platform_device *pdev) | |||
221 | * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max | 213 | * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max |
222 | * etc.. | 214 | * etc.. |
223 | */ | 215 | */ |
224 | static int __init create_device_attrs(struct platform_device *pdev) | 216 | static int create_device_attrs(struct platform_device *pdev) |
225 | { | 217 | { |
226 | struct platform_data *pdata = platform_get_drvdata(pdev); | 218 | struct platform_data *pdata = platform_get_drvdata(pdev); |
227 | const struct attribute_group **pgroups = pdata->attr_groups; | 219 | const struct attribute_group **pgroups = pdata->attr_groups; |
@@ -280,7 +272,7 @@ exit_put_node: | |||
280 | return err; | 272 | return err; |
281 | } | 273 | } |
282 | 274 | ||
283 | static int __init ibmpowernv_probe(struct platform_device *pdev) | 275 | static int ibmpowernv_probe(struct platform_device *pdev) |
284 | { | 276 | { |
285 | struct platform_data *pdata; | 277 | struct platform_data *pdata; |
286 | struct device *hwmon_dev; | 278 | struct device *hwmon_dev; |
@@ -309,57 +301,25 @@ static int __init ibmpowernv_probe(struct platform_device *pdev) | |||
309 | return PTR_ERR_OR_ZERO(hwmon_dev); | 301 | return PTR_ERR_OR_ZERO(hwmon_dev); |
310 | } | 302 | } |
311 | 303 | ||
312 | static struct platform_driver ibmpowernv_driver = { | 304 | static const struct platform_device_id opal_sensor_driver_ids[] = { |
313 | .driver = { | 305 | { |
314 | .owner = THIS_MODULE, | 306 | .name = "opal-sensor", |
315 | .name = DRVNAME, | ||
316 | }, | 307 | }, |
308 | { } | ||
317 | }; | 309 | }; |
310 | MODULE_DEVICE_TABLE(platform, opal_sensor_driver_ids); | ||
318 | 311 | ||
319 | static int __init ibmpowernv_init(void) | 312 | static struct platform_driver ibmpowernv_driver = { |
320 | { | 313 | .probe = ibmpowernv_probe, |
321 | int err; | 314 | .id_table = opal_sensor_driver_ids, |
322 | 315 | .driver = { | |
323 | pdevice = platform_device_alloc(DRVNAME, 0); | 316 | .owner = THIS_MODULE, |
324 | if (!pdevice) { | 317 | .name = DRVNAME, |
325 | pr_err("Device allocation failed\n"); | 318 | }, |
326 | err = -ENOMEM; | 319 | }; |
327 | goto exit; | ||
328 | } | ||
329 | |||
330 | err = platform_device_add(pdevice); | ||
331 | if (err) { | ||
332 | pr_err("Device addition failed (%d)\n", err); | ||
333 | goto exit_device_put; | ||
334 | } | ||
335 | |||
336 | err = platform_driver_probe(&ibmpowernv_driver, ibmpowernv_probe); | ||
337 | if (err) { | ||
338 | if (err != -ENODEV) | ||
339 | pr_err("Platform driver probe failed (%d)\n", err); | ||
340 | |||
341 | goto exit_device_del; | ||
342 | } | ||
343 | |||
344 | return 0; | ||
345 | |||
346 | exit_device_del: | ||
347 | platform_device_del(pdevice); | ||
348 | exit_device_put: | ||
349 | platform_device_put(pdevice); | ||
350 | exit: | ||
351 | return err; | ||
352 | } | ||
353 | 320 | ||
354 | static void __exit ibmpowernv_exit(void) | 321 | module_platform_driver(ibmpowernv_driver); |
355 | { | ||
356 | platform_driver_unregister(&ibmpowernv_driver); | ||
357 | platform_device_unregister(pdevice); | ||
358 | } | ||
359 | 322 | ||
360 | MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>"); | 323 | MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>"); |
361 | MODULE_DESCRIPTION("IBM POWERNV platform sensors"); | 324 | MODULE_DESCRIPTION("IBM POWERNV platform sensors"); |
362 | MODULE_LICENSE("GPL"); | 325 | MODULE_LICENSE("GPL"); |
363 | |||
364 | module_init(ibmpowernv_init); | ||
365 | module_exit(ibmpowernv_exit); | ||
diff --git a/drivers/hwmon/iio_hwmon.c b/drivers/hwmon/iio_hwmon.c index 14c82daab019..980175628563 100644 --- a/drivers/hwmon/iio_hwmon.c +++ b/drivers/hwmon/iio_hwmon.c | |||
@@ -63,7 +63,7 @@ static int iio_hwmon_probe(struct platform_device *pdev) | |||
63 | struct iio_hwmon_state *st; | 63 | struct iio_hwmon_state *st; |
64 | struct sensor_device_attribute *a; | 64 | struct sensor_device_attribute *a; |
65 | int ret, i; | 65 | int ret, i; |
66 | int in_i = 1, temp_i = 1, curr_i = 1; | 66 | int in_i = 1, temp_i = 1, curr_i = 1, humidity_i = 1; |
67 | enum iio_chan_type type; | 67 | enum iio_chan_type type; |
68 | struct iio_channel *channels; | 68 | struct iio_channel *channels; |
69 | const char *name = "iio_hwmon"; | 69 | const char *name = "iio_hwmon"; |
@@ -123,6 +123,11 @@ static int iio_hwmon_probe(struct platform_device *pdev) | |||
123 | "curr%d_input", | 123 | "curr%d_input", |
124 | curr_i++); | 124 | curr_i++); |
125 | break; | 125 | break; |
126 | case IIO_HUMIDITYRELATIVE: | ||
127 | a->dev_attr.attr.name = kasprintf(GFP_KERNEL, | ||
128 | "humidity%d_input", | ||
129 | humidity_i++); | ||
130 | break; | ||
126 | default: | 131 | default: |
127 | ret = -EINVAL; | 132 | ret = -EINVAL; |
128 | goto error_release_channels; | 133 | goto error_release_channels; |
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index bfd3f3eeabcd..e01feba909c3 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c | |||
@@ -223,6 +223,7 @@ static int ina2xx_probe(struct i2c_client *client, | |||
223 | struct device *hwmon_dev; | 223 | struct device *hwmon_dev; |
224 | long shunt = 10000; /* default shunt value 10mOhms */ | 224 | long shunt = 10000; /* default shunt value 10mOhms */ |
225 | u32 val; | 225 | u32 val; |
226 | int ret; | ||
226 | 227 | ||
227 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) | 228 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) |
228 | return -ENODEV; | 229 | return -ENODEV; |
@@ -247,12 +248,25 @@ static int ina2xx_probe(struct i2c_client *client, | |||
247 | data->config = &ina2xx_config[data->kind]; | 248 | data->config = &ina2xx_config[data->kind]; |
248 | 249 | ||
249 | /* device configuration */ | 250 | /* device configuration */ |
250 | i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, | 251 | ret = i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, |
251 | data->config->config_default); | 252 | data->config->config_default); |
252 | /* set current LSB to 1mA, shunt is in uOhms */ | 253 | if (ret < 0) { |
253 | /* (equation 13 in datasheet) */ | 254 | dev_err(dev, |
254 | i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, | 255 | "error writing to the config register: %d", ret); |
255 | data->config->calibration_factor / shunt); | 256 | return -ENODEV; |
257 | } | ||
258 | |||
259 | /* | ||
260 | * Set current LSB to 1mA, shunt is in uOhms | ||
261 | * (equation 13 in datasheet). | ||
262 | */ | ||
263 | ret = i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, | ||
264 | data->config->calibration_factor / shunt); | ||
265 | if (ret < 0) { | ||
266 | dev_err(dev, | ||
267 | "error writing to the calibration register: %d", ret); | ||
268 | return -ENODEV; | ||
269 | } | ||
256 | 270 | ||
257 | data->client = client; | 271 | data->client = client; |
258 | mutex_init(&data->update_lock); | 272 | mutex_init(&data->update_lock); |
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index d16dbb33a531..6753fd940c76 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -44,6 +44,7 @@ enum lm75_type { /* keep sorted in alphabetical order */ | |||
44 | g751, | 44 | g751, |
45 | lm75, | 45 | lm75, |
46 | lm75a, | 46 | lm75a, |
47 | lm75b, | ||
47 | max6625, | 48 | max6625, |
48 | max6626, | 49 | max6626, |
49 | mcp980x, | 50 | mcp980x, |
@@ -233,6 +234,10 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
233 | data->resolution = 9; | 234 | data->resolution = 9; |
234 | data->sample_time = HZ / 2; | 235 | data->sample_time = HZ / 2; |
235 | break; | 236 | break; |
237 | case lm75b: | ||
238 | data->resolution = 11; | ||
239 | data->sample_time = HZ / 4; | ||
240 | break; | ||
236 | case max6625: | 241 | case max6625: |
237 | data->resolution = 9; | 242 | data->resolution = 9; |
238 | data->sample_time = HZ / 4; | 243 | data->sample_time = HZ / 4; |
@@ -322,6 +327,7 @@ static const struct i2c_device_id lm75_ids[] = { | |||
322 | { "g751", g751, }, | 327 | { "g751", g751, }, |
323 | { "lm75", lm75, }, | 328 | { "lm75", lm75, }, |
324 | { "lm75a", lm75a, }, | 329 | { "lm75a", lm75a, }, |
330 | { "lm75b", lm75b, }, | ||
325 | { "max6625", max6625, }, | 331 | { "max6625", max6625, }, |
326 | { "max6626", max6626, }, | 332 | { "max6626", max6626, }, |
327 | { "mcp980x", mcp980x, }, | 333 | { "mcp980x", mcp980x, }, |
@@ -409,6 +415,12 @@ static int lm75_detect(struct i2c_client *new_client, | |||
409 | || i2c_smbus_read_byte_data(new_client, 7) != os) | 415 | || i2c_smbus_read_byte_data(new_client, 7) != os) |
410 | return -ENODEV; | 416 | return -ENODEV; |
411 | } | 417 | } |
418 | /* | ||
419 | * It is very unlikely that this is a LM75 if both | ||
420 | * hysteresis and temperature limit registers are 0. | ||
421 | */ | ||
422 | if (hyst == 0 && os == 0) | ||
423 | return -ENODEV; | ||
412 | 424 | ||
413 | /* Addresses cycling */ | 425 | /* Addresses cycling */ |
414 | for (i = 8; i <= 248; i += 40) { | 426 | for (i = 8; i <= 248; i += 40) { |
diff --git a/drivers/hwmon/lm95234.c b/drivers/hwmon/lm95234.c index 411202bdaf6b..8796de39ff9b 100644 --- a/drivers/hwmon/lm95234.c +++ b/drivers/hwmon/lm95234.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for Texas Instruments / National Semiconductor LM95234 | 2 | * Driver for Texas Instruments / National Semiconductor LM95234 |
3 | * | 3 | * |
4 | * Copyright (c) 2013 Guenter Roeck <linux@roeck-us.net> | 4 | * Copyright (c) 2013, 2014 Guenter Roeck <linux@roeck-us.net> |
5 | * | 5 | * |
6 | * Derived from lm95241.c | 6 | * Derived from lm95241.c |
7 | * Copyright (C) 2008, 2010 Davide Rizzo <elpa.rizzo@gmail.com> | 7 | * Copyright (C) 2008, 2010 Davide Rizzo <elpa.rizzo@gmail.com> |
@@ -30,7 +30,10 @@ | |||
30 | 30 | ||
31 | #define DRVNAME "lm95234" | 31 | #define DRVNAME "lm95234" |
32 | 32 | ||
33 | static const unsigned short normal_i2c[] = { 0x18, 0x4d, 0x4e, I2C_CLIENT_END }; | 33 | enum chips { lm95233, lm95234 }; |
34 | |||
35 | static const unsigned short normal_i2c[] = { | ||
36 | 0x18, 0x2a, 0x2b, 0x4d, 0x4e, I2C_CLIENT_END }; | ||
34 | 37 | ||
35 | /* LM95234 registers */ | 38 | /* LM95234 registers */ |
36 | #define LM95234_REG_MAN_ID 0xFE | 39 | #define LM95234_REG_MAN_ID 0xFE |
@@ -53,11 +56,13 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4d, 0x4e, I2C_CLIENT_END }; | |||
53 | #define LM95234_REG_TCRIT_HYST 0x5a | 56 | #define LM95234_REG_TCRIT_HYST 0x5a |
54 | 57 | ||
55 | #define NATSEMI_MAN_ID 0x01 | 58 | #define NATSEMI_MAN_ID 0x01 |
59 | #define LM95233_CHIP_ID 0x89 | ||
56 | #define LM95234_CHIP_ID 0x79 | 60 | #define LM95234_CHIP_ID 0x79 |
57 | 61 | ||
58 | /* Client data (each client gets its own) */ | 62 | /* Client data (each client gets its own) */ |
59 | struct lm95234_data { | 63 | struct lm95234_data { |
60 | struct i2c_client *client; | 64 | struct i2c_client *client; |
65 | const struct attribute_group *groups[3]; | ||
61 | struct mutex update_lock; | 66 | struct mutex update_lock; |
62 | unsigned long last_updated, interval; /* in jiffies */ | 67 | unsigned long last_updated, interval; /* in jiffies */ |
63 | bool valid; /* false until following fields are valid */ | 68 | bool valid; /* false until following fields are valid */ |
@@ -564,35 +569,23 @@ static SENSOR_DEVICE_ATTR(temp5_offset, S_IWUSR | S_IRUGO, show_offset, | |||
564 | static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, | 569 | static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, |
565 | set_interval); | 570 | set_interval); |
566 | 571 | ||
567 | static struct attribute *lm95234_attrs[] = { | 572 | static struct attribute *lm95234_common_attrs[] = { |
568 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 573 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
569 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 574 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
570 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 575 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
571 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
572 | &sensor_dev_attr_temp5_input.dev_attr.attr, | ||
573 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | 576 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
574 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | 577 | &sensor_dev_attr_temp3_fault.dev_attr.attr, |
575 | &sensor_dev_attr_temp4_fault.dev_attr.attr, | ||
576 | &sensor_dev_attr_temp5_fault.dev_attr.attr, | ||
577 | &sensor_dev_attr_temp2_type.dev_attr.attr, | 578 | &sensor_dev_attr_temp2_type.dev_attr.attr, |
578 | &sensor_dev_attr_temp3_type.dev_attr.attr, | 579 | &sensor_dev_attr_temp3_type.dev_attr.attr, |
579 | &sensor_dev_attr_temp4_type.dev_attr.attr, | ||
580 | &sensor_dev_attr_temp5_type.dev_attr.attr, | ||
581 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 580 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
582 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 581 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
583 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 582 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
584 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
585 | &sensor_dev_attr_temp5_max.dev_attr.attr, | ||
586 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | 583 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
587 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, | 584 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, |
588 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, | 585 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, |
589 | &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, | ||
590 | &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, | ||
591 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 586 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
592 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 587 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
593 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | 588 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, |
594 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, | ||
595 | &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, | ||
596 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | 589 | &sensor_dev_attr_temp2_crit.dev_attr.attr, |
597 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | 590 | &sensor_dev_attr_temp3_crit.dev_attr.attr, |
598 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, | 591 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, |
@@ -601,18 +594,44 @@ static struct attribute *lm95234_attrs[] = { | |||
601 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | 594 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, |
602 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | 595 | &sensor_dev_attr_temp2_offset.dev_attr.attr, |
603 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | 596 | &sensor_dev_attr_temp3_offset.dev_attr.attr, |
597 | &dev_attr_update_interval.attr, | ||
598 | NULL | ||
599 | }; | ||
600 | |||
601 | static const struct attribute_group lm95234_common_group = { | ||
602 | .attrs = lm95234_common_attrs, | ||
603 | }; | ||
604 | |||
605 | static struct attribute *lm95234_attrs[] = { | ||
606 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
607 | &sensor_dev_attr_temp5_input.dev_attr.attr, | ||
608 | &sensor_dev_attr_temp4_fault.dev_attr.attr, | ||
609 | &sensor_dev_attr_temp5_fault.dev_attr.attr, | ||
610 | &sensor_dev_attr_temp4_type.dev_attr.attr, | ||
611 | &sensor_dev_attr_temp5_type.dev_attr.attr, | ||
612 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
613 | &sensor_dev_attr_temp5_max.dev_attr.attr, | ||
614 | &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, | ||
615 | &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, | ||
616 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, | ||
617 | &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, | ||
604 | &sensor_dev_attr_temp4_offset.dev_attr.attr, | 618 | &sensor_dev_attr_temp4_offset.dev_attr.attr, |
605 | &sensor_dev_attr_temp5_offset.dev_attr.attr, | 619 | &sensor_dev_attr_temp5_offset.dev_attr.attr, |
606 | &dev_attr_update_interval.attr, | ||
607 | NULL | 620 | NULL |
608 | }; | 621 | }; |
609 | ATTRIBUTE_GROUPS(lm95234); | 622 | |
623 | static const struct attribute_group lm95234_group = { | ||
624 | .attrs = lm95234_attrs, | ||
625 | }; | ||
610 | 626 | ||
611 | static int lm95234_detect(struct i2c_client *client, | 627 | static int lm95234_detect(struct i2c_client *client, |
612 | struct i2c_board_info *info) | 628 | struct i2c_board_info *info) |
613 | { | 629 | { |
614 | struct i2c_adapter *adapter = client->adapter; | 630 | struct i2c_adapter *adapter = client->adapter; |
631 | int address = client->addr; | ||
632 | u8 config_mask, model_mask; | ||
615 | int mfg_id, chip_id, val; | 633 | int mfg_id, chip_id, val; |
634 | const char *name; | ||
616 | 635 | ||
617 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 636 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
618 | return -ENODEV; | 637 | return -ENODEV; |
@@ -622,15 +641,31 @@ static int lm95234_detect(struct i2c_client *client, | |||
622 | return -ENODEV; | 641 | return -ENODEV; |
623 | 642 | ||
624 | chip_id = i2c_smbus_read_byte_data(client, LM95234_REG_CHIP_ID); | 643 | chip_id = i2c_smbus_read_byte_data(client, LM95234_REG_CHIP_ID); |
625 | if (chip_id != LM95234_CHIP_ID) | 644 | switch (chip_id) { |
645 | case LM95233_CHIP_ID: | ||
646 | if (address != 0x18 && address != 0x2a && address != 0x2b) | ||
647 | return -ENODEV; | ||
648 | config_mask = 0xbf; | ||
649 | model_mask = 0xf9; | ||
650 | name = "lm95233"; | ||
651 | break; | ||
652 | case LM95234_CHIP_ID: | ||
653 | if (address != 0x18 && address != 0x4d && address != 0x4e) | ||
654 | return -ENODEV; | ||
655 | config_mask = 0xbc; | ||
656 | model_mask = 0xe1; | ||
657 | name = "lm95234"; | ||
658 | break; | ||
659 | default: | ||
626 | return -ENODEV; | 660 | return -ENODEV; |
661 | } | ||
627 | 662 | ||
628 | val = i2c_smbus_read_byte_data(client, LM95234_REG_STATUS); | 663 | val = i2c_smbus_read_byte_data(client, LM95234_REG_STATUS); |
629 | if (val & 0x30) | 664 | if (val & 0x30) |
630 | return -ENODEV; | 665 | return -ENODEV; |
631 | 666 | ||
632 | val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG); | 667 | val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG); |
633 | if (val & 0xbc) | 668 | if (val & config_mask) |
634 | return -ENODEV; | 669 | return -ENODEV; |
635 | 670 | ||
636 | val = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE); | 671 | val = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE); |
@@ -638,14 +673,14 @@ static int lm95234_detect(struct i2c_client *client, | |||
638 | return -ENODEV; | 673 | return -ENODEV; |
639 | 674 | ||
640 | val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); | 675 | val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); |
641 | if (val & 0xe1) | 676 | if (val & model_mask) |
642 | return -ENODEV; | 677 | return -ENODEV; |
643 | 678 | ||
644 | val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS); | 679 | val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS); |
645 | if (val & 0xe1) | 680 | if (val & model_mask) |
646 | return -ENODEV; | 681 | return -ENODEV; |
647 | 682 | ||
648 | strlcpy(info->type, "lm95234", I2C_NAME_SIZE); | 683 | strlcpy(info->type, name, I2C_NAME_SIZE); |
649 | return 0; | 684 | return 0; |
650 | } | 685 | } |
651 | 686 | ||
@@ -698,15 +733,19 @@ static int lm95234_probe(struct i2c_client *client, | |||
698 | if (err < 0) | 733 | if (err < 0) |
699 | return err; | 734 | return err; |
700 | 735 | ||
736 | data->groups[0] = &lm95234_common_group; | ||
737 | if (id->driver_data == lm95234) | ||
738 | data->groups[1] = &lm95234_group; | ||
739 | |||
701 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 740 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, |
702 | data, | 741 | data, data->groups); |
703 | lm95234_groups); | ||
704 | return PTR_ERR_OR_ZERO(hwmon_dev); | 742 | return PTR_ERR_OR_ZERO(hwmon_dev); |
705 | } | 743 | } |
706 | 744 | ||
707 | /* Driver data (common to all clients) */ | 745 | /* Driver data (common to all clients) */ |
708 | static const struct i2c_device_id lm95234_id[] = { | 746 | static const struct i2c_device_id lm95234_id[] = { |
709 | { "lm95234", 0 }, | 747 | { "lm95233", lm95233 }, |
748 | { "lm95234", lm95234 }, | ||
710 | { } | 749 | { } |
711 | }; | 750 | }; |
712 | MODULE_DEVICE_TABLE(i2c, lm95234_id); | 751 | MODULE_DEVICE_TABLE(i2c, lm95234_id); |
@@ -725,5 +764,5 @@ static struct i2c_driver lm95234_driver = { | |||
725 | module_i2c_driver(lm95234_driver); | 764 | module_i2c_driver(lm95234_driver); |
726 | 765 | ||
727 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); | 766 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); |
728 | MODULE_DESCRIPTION("LM95234 sensor driver"); | 767 | MODULE_DESCRIPTION("LM95233/LM95234 sensor driver"); |
729 | MODULE_LICENSE("GPL"); | 768 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hwmon/lm95245.c b/drivers/hwmon/lm95245.c index 0ae0dfdafdff..e7aef4561c83 100644 --- a/drivers/hwmon/lm95245.c +++ b/drivers/hwmon/lm95245.c | |||
@@ -1,10 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2011 Alexander Stein <alexander.stein@systec-electronic.com> | 2 | * Copyright (C) 2011 Alexander Stein <alexander.stein@systec-electronic.com> |
3 | * | 3 | * |
4 | * The LM95245 is a sensor chip made by National Semiconductors. | 4 | * The LM95245 is a sensor chip made by TI / National Semiconductor. |
5 | * It reports up to two temperatures (its own plus an external one). | 5 | * It reports up to two temperatures (its own plus an external one). |
6 | * Complete datasheet can be obtained from National's website at: | ||
7 | * http://www.national.com/ds.cgi/LM/LM95245.pdf | ||
8 | * | 6 | * |
9 | * This driver is based on lm95241.c | 7 | * This driver is based on lm95241.c |
10 | * | 8 | * |
@@ -34,8 +32,6 @@ | |||
34 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
35 | #include <linux/sysfs.h> | 33 | #include <linux/sysfs.h> |
36 | 34 | ||
37 | #define DEVNAME "lm95245" | ||
38 | |||
39 | static const unsigned short normal_i2c[] = { | 35 | static const unsigned short normal_i2c[] = { |
40 | 0x18, 0x19, 0x29, 0x4c, 0x4d, I2C_CLIENT_END }; | 36 | 0x18, 0x19, 0x29, 0x4c, 0x4d, I2C_CLIENT_END }; |
41 | 37 | ||
@@ -98,7 +94,8 @@ static const unsigned short normal_i2c[] = { | |||
98 | #define STATUS1_LOC 0x01 | 94 | #define STATUS1_LOC 0x01 |
99 | 95 | ||
100 | #define MANUFACTURER_ID 0x01 | 96 | #define MANUFACTURER_ID 0x01 |
101 | #define DEFAULT_REVISION 0xB3 | 97 | #define LM95235_REVISION 0xB1 |
98 | #define LM95245_REVISION 0xB3 | ||
102 | 99 | ||
103 | static const u8 lm95245_reg_address[] = { | 100 | static const u8 lm95245_reg_address[] = { |
104 | LM95245_REG_R_LOCAL_TEMPH_S, | 101 | LM95245_REG_R_LOCAL_TEMPH_S, |
@@ -427,17 +424,32 @@ static int lm95245_detect(struct i2c_client *new_client, | |||
427 | struct i2c_board_info *info) | 424 | struct i2c_board_info *info) |
428 | { | 425 | { |
429 | struct i2c_adapter *adapter = new_client->adapter; | 426 | struct i2c_adapter *adapter = new_client->adapter; |
427 | int address = new_client->addr; | ||
428 | const char *name; | ||
429 | int rev, id; | ||
430 | 430 | ||
431 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 431 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
432 | return -ENODEV; | 432 | return -ENODEV; |
433 | 433 | ||
434 | if (i2c_smbus_read_byte_data(new_client, LM95245_REG_R_MAN_ID) | 434 | id = i2c_smbus_read_byte_data(new_client, LM95245_REG_R_MAN_ID); |
435 | != MANUFACTURER_ID | 435 | if (id != MANUFACTURER_ID) |
436 | || i2c_smbus_read_byte_data(new_client, LM95245_REG_R_CHIP_ID) | ||
437 | != DEFAULT_REVISION) | ||
438 | return -ENODEV; | 436 | return -ENODEV; |
439 | 437 | ||
440 | strlcpy(info->type, DEVNAME, I2C_NAME_SIZE); | 438 | rev = i2c_smbus_read_byte_data(new_client, LM95245_REG_R_CHIP_ID); |
439 | switch (rev) { | ||
440 | case LM95235_REVISION: | ||
441 | if (address != 0x18 && address != 0x29 && address != 0x4c) | ||
442 | return -ENODEV; | ||
443 | name = "lm95235"; | ||
444 | break; | ||
445 | case LM95245_REVISION: | ||
446 | name = "lm95245"; | ||
447 | break; | ||
448 | default: | ||
449 | return -ENODEV; | ||
450 | } | ||
451 | |||
452 | strlcpy(info->type, name, I2C_NAME_SIZE); | ||
441 | return 0; | 453 | return 0; |
442 | } | 454 | } |
443 | 455 | ||
@@ -484,7 +496,8 @@ static int lm95245_probe(struct i2c_client *client, | |||
484 | 496 | ||
485 | /* Driver data (common to all clients) */ | 497 | /* Driver data (common to all clients) */ |
486 | static const struct i2c_device_id lm95245_id[] = { | 498 | static const struct i2c_device_id lm95245_id[] = { |
487 | { DEVNAME, 0 }, | 499 | { "lm95235", 0 }, |
500 | { "lm95245", 0 }, | ||
488 | { } | 501 | { } |
489 | }; | 502 | }; |
490 | MODULE_DEVICE_TABLE(i2c, lm95245_id); | 503 | MODULE_DEVICE_TABLE(i2c, lm95245_id); |
@@ -492,7 +505,7 @@ MODULE_DEVICE_TABLE(i2c, lm95245_id); | |||
492 | static struct i2c_driver lm95245_driver = { | 505 | static struct i2c_driver lm95245_driver = { |
493 | .class = I2C_CLASS_HWMON, | 506 | .class = I2C_CLASS_HWMON, |
494 | .driver = { | 507 | .driver = { |
495 | .name = DEVNAME, | 508 | .name = "lm95245", |
496 | }, | 509 | }, |
497 | .probe = lm95245_probe, | 510 | .probe = lm95245_probe, |
498 | .id_table = lm95245_id, | 511 | .id_table = lm95245_id, |
@@ -503,5 +516,5 @@ static struct i2c_driver lm95245_driver = { | |||
503 | module_i2c_driver(lm95245_driver); | 516 | module_i2c_driver(lm95245_driver); |
504 | 517 | ||
505 | MODULE_AUTHOR("Alexander Stein <alexander.stein@systec-electronic.com>"); | 518 | MODULE_AUTHOR("Alexander Stein <alexander.stein@systec-electronic.com>"); |
506 | MODULE_DESCRIPTION("LM95245 sensor driver"); | 519 | MODULE_DESCRIPTION("LM95235/LM95245 sensor driver"); |
507 | MODULE_LICENSE("GPL"); | 520 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 504cbddbdd90..dc0df57200cd 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c | |||
@@ -38,6 +38,7 @@ | |||
38 | * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3 | 38 | * nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3 |
39 | * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3 | 39 | * nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3 |
40 | * nct6791d 15 6 6 2+6 0xc800 0xc1 0x5ca3 | 40 | * nct6791d 15 6 6 2+6 0xc800 0xc1 0x5ca3 |
41 | * nct6792d 15 6 6 2+6 0xc910 0xc1 0x5ca3 | ||
41 | * | 42 | * |
42 | * #temp lists the number of monitored temperature sources (first value) plus | 43 | * #temp lists the number of monitored temperature sources (first value) plus |
43 | * the number of directly connectable temperature sensors (second value). | 44 | * the number of directly connectable temperature sensors (second value). |
@@ -61,7 +62,7 @@ | |||
61 | 62 | ||
62 | #define USE_ALTERNATE | 63 | #define USE_ALTERNATE |
63 | 64 | ||
64 | enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791 }; | 65 | enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792 }; |
65 | 66 | ||
66 | /* used to set data->name = nct6775_device_names[data->sio_kind] */ | 67 | /* used to set data->name = nct6775_device_names[data->sio_kind] */ |
67 | static const char * const nct6775_device_names[] = { | 68 | static const char * const nct6775_device_names[] = { |
@@ -70,6 +71,7 @@ static const char * const nct6775_device_names[] = { | |||
70 | "nct6776", | 71 | "nct6776", |
71 | "nct6779", | 72 | "nct6779", |
72 | "nct6791", | 73 | "nct6791", |
74 | "nct6792", | ||
73 | }; | 75 | }; |
74 | 76 | ||
75 | static unsigned short force_id; | 77 | static unsigned short force_id; |
@@ -100,6 +102,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal"); | |||
100 | #define SIO_NCT6776_ID 0xc330 | 102 | #define SIO_NCT6776_ID 0xc330 |
101 | #define SIO_NCT6779_ID 0xc560 | 103 | #define SIO_NCT6779_ID 0xc560 |
102 | #define SIO_NCT6791_ID 0xc800 | 104 | #define SIO_NCT6791_ID 0xc800 |
105 | #define SIO_NCT6792_ID 0xc910 | ||
103 | #define SIO_ID_MASK 0xFFF0 | 106 | #define SIO_ID_MASK 0xFFF0 |
104 | 107 | ||
105 | enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; | 108 | enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; |
@@ -529,6 +532,12 @@ static const s8 NCT6791_ALARM_BITS[] = { | |||
529 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ | 532 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ |
530 | 12, 9 }; /* intrusion0, intrusion1 */ | 533 | 12, 9 }; /* intrusion0, intrusion1 */ |
531 | 534 | ||
535 | /* NCT6792 specific data */ | ||
536 | |||
537 | static const u16 NCT6792_REG_TEMP_MON[] = { | ||
538 | 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d }; | ||
539 | static const u16 NCT6792_REG_BEEP[NUM_REG_BEEP] = { | ||
540 | 0xb2, 0xb3, 0xb4, 0xb5, 0xbf }; | ||
532 | 541 | ||
533 | /* NCT6102D/NCT6106D specific data */ | 542 | /* NCT6102D/NCT6106D specific data */ |
534 | 543 | ||
@@ -1043,13 +1052,14 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg) | |||
1043 | reg == 0x73 || reg == 0x75 || reg == 0x77; | 1052 | reg == 0x73 || reg == 0x75 || reg == 0x77; |
1044 | case nct6779: | 1053 | case nct6779: |
1045 | case nct6791: | 1054 | case nct6791: |
1055 | case nct6792: | ||
1046 | return reg == 0x150 || reg == 0x153 || reg == 0x155 || | 1056 | return reg == 0x150 || reg == 0x153 || reg == 0x155 || |
1047 | ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) || | 1057 | ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) || |
1048 | reg == 0x402 || | 1058 | reg == 0x402 || |
1049 | reg == 0x63a || reg == 0x63c || reg == 0x63e || | 1059 | reg == 0x63a || reg == 0x63c || reg == 0x63e || |
1050 | reg == 0x640 || reg == 0x642 || | 1060 | reg == 0x640 || reg == 0x642 || |
1051 | reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 || | 1061 | reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 || |
1052 | reg == 0x7b; | 1062 | reg == 0x7b || reg == 0x7d; |
1053 | } | 1063 | } |
1054 | return false; | 1064 | return false; |
1055 | } | 1065 | } |
@@ -1063,6 +1073,7 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg) | |||
1063 | static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg) | 1073 | static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg) |
1064 | { | 1074 | { |
1065 | u8 bank = reg >> 8; | 1075 | u8 bank = reg >> 8; |
1076 | |||
1066 | if (data->bank != bank) { | 1077 | if (data->bank != bank) { |
1067 | outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET); | 1078 | outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET); |
1068 | outb_p(bank, data->addr + DATA_REG_OFFSET); | 1079 | outb_p(bank, data->addr + DATA_REG_OFFSET); |
@@ -1300,6 +1311,7 @@ static void nct6775_update_pwm(struct device *dev) | |||
1300 | if (!data->target_speed_tolerance[i] || | 1311 | if (!data->target_speed_tolerance[i] || |
1301 | data->pwm_enable[i] == speed_cruise) { | 1312 | data->pwm_enable[i] == speed_cruise) { |
1302 | u8 t = fanmodecfg & 0x0f; | 1313 | u8 t = fanmodecfg & 0x0f; |
1314 | |||
1303 | if (data->REG_TOLERANCE_H) { | 1315 | if (data->REG_TOLERANCE_H) { |
1304 | t |= (nct6775_read_value(data, | 1316 | t |= (nct6775_read_value(data, |
1305 | data->REG_TOLERANCE_H[i]) & 0x70) >> 1; | 1317 | data->REG_TOLERANCE_H[i]) & 0x70) >> 1; |
@@ -1391,6 +1403,7 @@ static void nct6775_update_pwm_limits(struct device *dev) | |||
1391 | case nct6106: | 1403 | case nct6106: |
1392 | case nct6779: | 1404 | case nct6779: |
1393 | case nct6791: | 1405 | case nct6791: |
1406 | case nct6792: | ||
1394 | reg = nct6775_read_value(data, | 1407 | reg = nct6775_read_value(data, |
1395 | data->REG_CRITICAL_PWM_ENABLE[i]); | 1408 | data->REG_CRITICAL_PWM_ENABLE[i]); |
1396 | if (reg & data->CRITICAL_PWM_ENABLE_MASK) | 1409 | if (reg & data->CRITICAL_PWM_ENABLE_MASK) |
@@ -1473,6 +1486,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev) | |||
1473 | data->alarms = 0; | 1486 | data->alarms = 0; |
1474 | for (i = 0; i < NUM_REG_ALARM; i++) { | 1487 | for (i = 0; i < NUM_REG_ALARM; i++) { |
1475 | u8 alarm; | 1488 | u8 alarm; |
1489 | |||
1476 | if (!data->REG_ALARM[i]) | 1490 | if (!data->REG_ALARM[i]) |
1477 | continue; | 1491 | continue; |
1478 | alarm = nct6775_read_value(data, data->REG_ALARM[i]); | 1492 | alarm = nct6775_read_value(data, data->REG_ALARM[i]); |
@@ -1482,6 +1496,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev) | |||
1482 | data->beeps = 0; | 1496 | data->beeps = 0; |
1483 | for (i = 0; i < NUM_REG_BEEP; i++) { | 1497 | for (i = 0; i < NUM_REG_BEEP; i++) { |
1484 | u8 beep; | 1498 | u8 beep; |
1499 | |||
1485 | if (!data->REG_BEEP[i]) | 1500 | if (!data->REG_BEEP[i]) |
1486 | continue; | 1501 | continue; |
1487 | beep = nct6775_read_value(data, data->REG_BEEP[i]); | 1502 | beep = nct6775_read_value(data, data->REG_BEEP[i]); |
@@ -1504,8 +1519,9 @@ show_in_reg(struct device *dev, struct device_attribute *attr, char *buf) | |||
1504 | { | 1519 | { |
1505 | struct nct6775_data *data = nct6775_update_device(dev); | 1520 | struct nct6775_data *data = nct6775_update_device(dev); |
1506 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | 1521 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); |
1507 | int nr = sattr->nr; | ||
1508 | int index = sattr->index; | 1522 | int index = sattr->index; |
1523 | int nr = sattr->nr; | ||
1524 | |||
1509 | return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr)); | 1525 | return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr)); |
1510 | } | 1526 | } |
1511 | 1527 | ||
@@ -1515,10 +1531,12 @@ store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf, | |||
1515 | { | 1531 | { |
1516 | struct nct6775_data *data = dev_get_drvdata(dev); | 1532 | struct nct6775_data *data = dev_get_drvdata(dev); |
1517 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | 1533 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); |
1518 | int nr = sattr->nr; | ||
1519 | int index = sattr->index; | 1534 | int index = sattr->index; |
1535 | int nr = sattr->nr; | ||
1520 | unsigned long val; | 1536 | unsigned long val; |
1521 | int err = kstrtoul(buf, 10, &val); | 1537 | int err; |
1538 | |||
1539 | err = kstrtoul(buf, 10, &val); | ||
1522 | if (err < 0) | 1540 | if (err < 0) |
1523 | return err; | 1541 | return err; |
1524 | mutex_lock(&data->update_lock); | 1542 | mutex_lock(&data->update_lock); |
@@ -1535,6 +1553,7 @@ show_alarm(struct device *dev, struct device_attribute *attr, char *buf) | |||
1535 | struct nct6775_data *data = nct6775_update_device(dev); | 1553 | struct nct6775_data *data = nct6775_update_device(dev); |
1536 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | 1554 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); |
1537 | int nr = data->ALARM_BITS[sattr->index]; | 1555 | int nr = data->ALARM_BITS[sattr->index]; |
1556 | |||
1538 | return sprintf(buf, "%u\n", | 1557 | return sprintf(buf, "%u\n", |
1539 | (unsigned int)((data->alarms >> nr) & 0x01)); | 1558 | (unsigned int)((data->alarms >> nr) & 0x01)); |
1540 | } | 1559 | } |
@@ -1570,6 +1589,7 @@ show_temp_alarm(struct device *dev, struct device_attribute *attr, char *buf) | |||
1570 | nr = find_temp_source(data, sattr->index, data->num_temp_alarms); | 1589 | nr = find_temp_source(data, sattr->index, data->num_temp_alarms); |
1571 | if (nr >= 0) { | 1590 | if (nr >= 0) { |
1572 | int bit = data->ALARM_BITS[nr + TEMP_ALARM_BASE]; | 1591 | int bit = data->ALARM_BITS[nr + TEMP_ALARM_BASE]; |
1592 | |||
1573 | alarm = (data->alarms >> bit) & 0x01; | 1593 | alarm = (data->alarms >> bit) & 0x01; |
1574 | } | 1594 | } |
1575 | return sprintf(buf, "%u\n", alarm); | 1595 | return sprintf(buf, "%u\n", alarm); |
@@ -1595,8 +1615,9 @@ store_beep(struct device *dev, struct device_attribute *attr, const char *buf, | |||
1595 | int nr = data->BEEP_BITS[sattr->index]; | 1615 | int nr = data->BEEP_BITS[sattr->index]; |
1596 | int regindex = nr >> 3; | 1616 | int regindex = nr >> 3; |
1597 | unsigned long val; | 1617 | unsigned long val; |
1618 | int err; | ||
1598 | 1619 | ||
1599 | int err = kstrtoul(buf, 10, &val); | 1620 | err = kstrtoul(buf, 10, &val); |
1600 | if (err < 0) | 1621 | if (err < 0) |
1601 | return err; | 1622 | return err; |
1602 | if (val > 1) | 1623 | if (val > 1) |
@@ -1629,6 +1650,7 @@ show_temp_beep(struct device *dev, struct device_attribute *attr, char *buf) | |||
1629 | nr = find_temp_source(data, sattr->index, data->num_temp_beeps); | 1650 | nr = find_temp_source(data, sattr->index, data->num_temp_beeps); |
1630 | if (nr >= 0) { | 1651 | if (nr >= 0) { |
1631 | int bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE]; | 1652 | int bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE]; |
1653 | |||
1632 | beep = (data->beeps >> bit) & 0x01; | 1654 | beep = (data->beeps >> bit) & 0x01; |
1633 | } | 1655 | } |
1634 | return sprintf(buf, "%u\n", beep); | 1656 | return sprintf(buf, "%u\n", beep); |
@@ -1642,8 +1664,9 @@ store_temp_beep(struct device *dev, struct device_attribute *attr, | |||
1642 | struct nct6775_data *data = dev_get_drvdata(dev); | 1664 | struct nct6775_data *data = dev_get_drvdata(dev); |
1643 | int nr, bit, regindex; | 1665 | int nr, bit, regindex; |
1644 | unsigned long val; | 1666 | unsigned long val; |
1667 | int err; | ||
1645 | 1668 | ||
1646 | int err = kstrtoul(buf, 10, &val); | 1669 | err = kstrtoul(buf, 10, &val); |
1647 | if (err < 0) | 1670 | if (err < 0) |
1648 | return err; | 1671 | return err; |
1649 | if (val > 1) | 1672 | if (val > 1) |
@@ -1715,6 +1738,7 @@ show_fan(struct device *dev, struct device_attribute *attr, char *buf) | |||
1715 | struct nct6775_data *data = nct6775_update_device(dev); | 1738 | struct nct6775_data *data = nct6775_update_device(dev); |
1716 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | 1739 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); |
1717 | int nr = sattr->index; | 1740 | int nr = sattr->index; |
1741 | |||
1718 | return sprintf(buf, "%d\n", data->rpm[nr]); | 1742 | return sprintf(buf, "%d\n", data->rpm[nr]); |
1719 | } | 1743 | } |
1720 | 1744 | ||
@@ -1724,6 +1748,7 @@ show_fan_min(struct device *dev, struct device_attribute *attr, char *buf) | |||
1724 | struct nct6775_data *data = nct6775_update_device(dev); | 1748 | struct nct6775_data *data = nct6775_update_device(dev); |
1725 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | 1749 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); |
1726 | int nr = sattr->index; | 1750 | int nr = sattr->index; |
1751 | |||
1727 | return sprintf(buf, "%d\n", | 1752 | return sprintf(buf, "%d\n", |
1728 | data->fan_from_reg_min(data->fan_min[nr], | 1753 | data->fan_from_reg_min(data->fan_min[nr], |
1729 | data->fan_div[nr])); | 1754 | data->fan_div[nr])); |
@@ -1735,6 +1760,7 @@ show_fan_div(struct device *dev, struct device_attribute *attr, char *buf) | |||
1735 | struct nct6775_data *data = nct6775_update_device(dev); | 1760 | struct nct6775_data *data = nct6775_update_device(dev); |
1736 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | 1761 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); |
1737 | int nr = sattr->index; | 1762 | int nr = sattr->index; |
1763 | |||
1738 | return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr])); | 1764 | return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr])); |
1739 | } | 1765 | } |
1740 | 1766 | ||
@@ -1746,9 +1772,9 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
1746 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | 1772 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); |
1747 | int nr = sattr->index; | 1773 | int nr = sattr->index; |
1748 | unsigned long val; | 1774 | unsigned long val; |
1749 | int err; | ||
1750 | unsigned int reg; | 1775 | unsigned int reg; |
1751 | u8 new_div; | 1776 | u8 new_div; |
1777 | int err; | ||
1752 | 1778 | ||
1753 | err = kstrtoul(buf, 10, &val); | 1779 | err = kstrtoul(buf, 10, &val); |
1754 | if (err < 0) | 1780 | if (err < 0) |
@@ -1932,6 +1958,7 @@ show_temp_label(struct device *dev, struct device_attribute *attr, char *buf) | |||
1932 | struct nct6775_data *data = nct6775_update_device(dev); | 1958 | struct nct6775_data *data = nct6775_update_device(dev); |
1933 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | 1959 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); |
1934 | int nr = sattr->index; | 1960 | int nr = sattr->index; |
1961 | |||
1935 | return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]); | 1962 | return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]); |
1936 | } | 1963 | } |
1937 | 1964 | ||
@@ -2008,6 +2035,7 @@ show_temp_type(struct device *dev, struct device_attribute *attr, char *buf) | |||
2008 | struct nct6775_data *data = nct6775_update_device(dev); | 2035 | struct nct6775_data *data = nct6775_update_device(dev); |
2009 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | 2036 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); |
2010 | int nr = sattr->index; | 2037 | int nr = sattr->index; |
2038 | |||
2011 | return sprintf(buf, "%d\n", (int)data->temp_type[nr]); | 2039 | return sprintf(buf, "%d\n", (int)data->temp_type[nr]); |
2012 | } | 2040 | } |
2013 | 2041 | ||
@@ -2790,6 +2818,7 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr, | |||
2790 | case nct6106: | 2818 | case nct6106: |
2791 | case nct6779: | 2819 | case nct6779: |
2792 | case nct6791: | 2820 | case nct6791: |
2821 | case nct6792: | ||
2793 | nct6775_write_value(data, data->REG_CRITICAL_PWM[nr], | 2822 | nct6775_write_value(data, data->REG_CRITICAL_PWM[nr], |
2794 | val); | 2823 | val); |
2795 | reg = nct6775_read_value(data, | 2824 | reg = nct6775_read_value(data, |
@@ -2997,6 +3026,7 @@ static ssize_t | |||
2997 | show_vid(struct device *dev, struct device_attribute *attr, char *buf) | 3026 | show_vid(struct device *dev, struct device_attribute *attr, char *buf) |
2998 | { | 3027 | { |
2999 | struct nct6775_data *data = dev_get_drvdata(dev); | 3028 | struct nct6775_data *data = dev_get_drvdata(dev); |
3029 | |||
3000 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); | 3030 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); |
3001 | } | 3031 | } |
3002 | 3032 | ||
@@ -3202,7 +3232,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data) | |||
3202 | pwm4pin = false; | 3232 | pwm4pin = false; |
3203 | pwm5pin = false; | 3233 | pwm5pin = false; |
3204 | pwm6pin = false; | 3234 | pwm6pin = false; |
3205 | } else { /* NCT6779D or NCT6791D */ | 3235 | } else { /* NCT6779D, NCT6791D, or NCT6792D */ |
3206 | regval = superio_inb(sioreg, 0x1c); | 3236 | regval = superio_inb(sioreg, 0x1c); |
3207 | 3237 | ||
3208 | fan3pin = !(regval & (1 << 5)); | 3238 | fan3pin = !(regval & (1 << 5)); |
@@ -3215,7 +3245,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data) | |||
3215 | 3245 | ||
3216 | fan4min = fan4pin; | 3246 | fan4min = fan4pin; |
3217 | 3247 | ||
3218 | if (data->kind == nct6791) { | 3248 | if (data->kind == nct6791 || data->kind == nct6792) { |
3219 | regval = superio_inb(sioreg, 0x2d); | 3249 | regval = superio_inb(sioreg, 0x2d); |
3220 | fan6pin = (regval & (1 << 1)); | 3250 | fan6pin = (regval & (1 << 1)); |
3221 | pwm6pin = (regval & (1 << 0)); | 3251 | pwm6pin = (regval & (1 << 0)); |
@@ -3588,6 +3618,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3588 | 3618 | ||
3589 | break; | 3619 | break; |
3590 | case nct6791: | 3620 | case nct6791: |
3621 | case nct6792: | ||
3591 | data->in_num = 15; | 3622 | data->in_num = 15; |
3592 | data->pwm_num = 6; | 3623 | data->pwm_num = 6; |
3593 | data->auto_pwm_num = 4; | 3624 | data->auto_pwm_num = 4; |
@@ -3650,12 +3681,20 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3650 | data->REG_WEIGHT_TEMP[1] = NCT6791_REG_WEIGHT_TEMP_STEP_TOL; | 3681 | data->REG_WEIGHT_TEMP[1] = NCT6791_REG_WEIGHT_TEMP_STEP_TOL; |
3651 | data->REG_WEIGHT_TEMP[2] = NCT6791_REG_WEIGHT_TEMP_BASE; | 3682 | data->REG_WEIGHT_TEMP[2] = NCT6791_REG_WEIGHT_TEMP_BASE; |
3652 | data->REG_ALARM = NCT6791_REG_ALARM; | 3683 | data->REG_ALARM = NCT6791_REG_ALARM; |
3653 | data->REG_BEEP = NCT6776_REG_BEEP; | 3684 | if (data->kind == nct6791) |
3685 | data->REG_BEEP = NCT6776_REG_BEEP; | ||
3686 | else | ||
3687 | data->REG_BEEP = NCT6792_REG_BEEP; | ||
3654 | 3688 | ||
3655 | reg_temp = NCT6779_REG_TEMP; | 3689 | reg_temp = NCT6779_REG_TEMP; |
3656 | reg_temp_mon = NCT6779_REG_TEMP_MON; | ||
3657 | num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); | 3690 | num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); |
3658 | num_reg_temp_mon = ARRAY_SIZE(NCT6779_REG_TEMP_MON); | 3691 | if (data->kind == nct6791) { |
3692 | reg_temp_mon = NCT6779_REG_TEMP_MON; | ||
3693 | num_reg_temp_mon = ARRAY_SIZE(NCT6779_REG_TEMP_MON); | ||
3694 | } else { | ||
3695 | reg_temp_mon = NCT6792_REG_TEMP_MON; | ||
3696 | num_reg_temp_mon = ARRAY_SIZE(NCT6792_REG_TEMP_MON); | ||
3697 | } | ||
3659 | reg_temp_over = NCT6779_REG_TEMP_OVER; | 3698 | reg_temp_over = NCT6779_REG_TEMP_OVER; |
3660 | reg_temp_hyst = NCT6779_REG_TEMP_HYST; | 3699 | reg_temp_hyst = NCT6779_REG_TEMP_HYST; |
3661 | reg_temp_config = NCT6779_REG_TEMP_CONFIG; | 3700 | reg_temp_config = NCT6779_REG_TEMP_CONFIG; |
@@ -3854,6 +3893,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3854 | case nct6106: | 3893 | case nct6106: |
3855 | case nct6779: | 3894 | case nct6779: |
3856 | case nct6791: | 3895 | case nct6791: |
3896 | case nct6792: | ||
3857 | break; | 3897 | break; |
3858 | } | 3898 | } |
3859 | 3899 | ||
@@ -3885,6 +3925,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3885 | tmp |= 0x3e; | 3925 | tmp |= 0x3e; |
3886 | break; | 3926 | break; |
3887 | case nct6791: | 3927 | case nct6791: |
3928 | case nct6792: | ||
3888 | tmp |= 0x7e; | 3929 | tmp |= 0x7e; |
3889 | break; | 3930 | break; |
3890 | } | 3931 | } |
@@ -3972,7 +4013,7 @@ static int nct6775_resume(struct device *dev) | |||
3972 | mutex_lock(&data->update_lock); | 4013 | mutex_lock(&data->update_lock); |
3973 | data->bank = 0xff; /* Force initial bank selection */ | 4014 | data->bank = 0xff; /* Force initial bank selection */ |
3974 | 4015 | ||
3975 | if (data->kind == nct6791) { | 4016 | if (data->kind == nct6791 || data->kind == nct6792) { |
3976 | err = superio_enter(data->sioreg); | 4017 | err = superio_enter(data->sioreg); |
3977 | if (err) | 4018 | if (err) |
3978 | goto abort; | 4019 | goto abort; |
@@ -4052,6 +4093,7 @@ static const char * const nct6775_sio_names[] __initconst = { | |||
4052 | "NCT6776D/F", | 4093 | "NCT6776D/F", |
4053 | "NCT6779D", | 4094 | "NCT6779D", |
4054 | "NCT6791D", | 4095 | "NCT6791D", |
4096 | "NCT6792D", | ||
4055 | }; | 4097 | }; |
4056 | 4098 | ||
4057 | /* nct6775_find() looks for a '627 in the Super-I/O config space */ | 4099 | /* nct6775_find() looks for a '627 in the Super-I/O config space */ |
@@ -4086,6 +4128,9 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data) | |||
4086 | case SIO_NCT6791_ID: | 4128 | case SIO_NCT6791_ID: |
4087 | sio_data->kind = nct6791; | 4129 | sio_data->kind = nct6791; |
4088 | break; | 4130 | break; |
4131 | case SIO_NCT6792_ID: | ||
4132 | sio_data->kind = nct6792; | ||
4133 | break; | ||
4089 | default: | 4134 | default: |
4090 | if (val != 0xffff) | 4135 | if (val != 0xffff) |
4091 | pr_debug("unsupported chip ID: 0x%04x\n", val); | 4136 | pr_debug("unsupported chip ID: 0x%04x\n", val); |
@@ -4111,7 +4156,7 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data) | |||
4111 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); | 4156 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); |
4112 | } | 4157 | } |
4113 | 4158 | ||
4114 | if (sio_data->kind == nct6791) | 4159 | if (sio_data->kind == nct6791 || sio_data->kind == nct6792) |
4115 | nct6791_enable_io_mapping(sioaddr); | 4160 | nct6791_enable_io_mapping(sioaddr); |
4116 | 4161 | ||
4117 | superio_exit(sioaddr); | 4162 | superio_exit(sioaddr); |
@@ -4221,7 +4266,7 @@ static void __exit sensors_nct6775_exit(void) | |||
4221 | } | 4266 | } |
4222 | 4267 | ||
4223 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); | 4268 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); |
4224 | MODULE_DESCRIPTION("NCT6106D/NCT6775F/NCT6776F/NCT6779D/NCT6791D driver"); | 4269 | MODULE_DESCRIPTION("NCT6106D/NCT6775F/NCT6776F/NCT6779D/NCT6791D/NCT6792D driver"); |
4225 | MODULE_LICENSE("GPL"); | 4270 | MODULE_LICENSE("GPL"); |
4226 | 4271 | ||
4227 | module_init(sensors_nct6775_init); | 4272 | module_init(sensors_nct6775_init); |
diff --git a/drivers/hwmon/nct7802.c b/drivers/hwmon/nct7802.c new file mode 100644 index 000000000000..ec5678289e4a --- /dev/null +++ b/drivers/hwmon/nct7802.c | |||
@@ -0,0 +1,860 @@ | |||
1 | /* | ||
2 | * nct7802 - Driver for Nuvoton NCT7802Y | ||
3 | * | ||
4 | * Copyright (C) 2014 Guenter Roeck <linux@roeck-us.net> | ||
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, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
18 | |||
19 | #include <linux/err.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/hwmon.h> | ||
23 | #include <linux/hwmon-sysfs.h> | ||
24 | #include <linux/jiffies.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/mutex.h> | ||
27 | #include <linux/regmap.h> | ||
28 | #include <linux/slab.h> | ||
29 | |||
30 | #define DRVNAME "nct7802" | ||
31 | |||
32 | static const u8 REG_VOLTAGE[5] = { 0x09, 0x0a, 0x0c, 0x0d, 0x0e }; | ||
33 | |||
34 | static const u8 REG_VOLTAGE_LIMIT_LSB[2][5] = { | ||
35 | { 0x40, 0x00, 0x42, 0x44, 0x46 }, | ||
36 | { 0x3f, 0x00, 0x41, 0x43, 0x45 }, | ||
37 | }; | ||
38 | |||
39 | static const u8 REG_VOLTAGE_LIMIT_MSB[5] = { 0x48, 0x00, 0x47, 0x47, 0x48 }; | ||
40 | |||
41 | static const u8 REG_VOLTAGE_LIMIT_MSB_SHIFT[2][5] = { | ||
42 | { 0, 0, 4, 0, 4 }, | ||
43 | { 2, 0, 6, 2, 6 }, | ||
44 | }; | ||
45 | |||
46 | #define REG_BANK 0x00 | ||
47 | #define REG_TEMP_LSB 0x05 | ||
48 | #define REG_TEMP_PECI_LSB 0x08 | ||
49 | #define REG_VOLTAGE_LOW 0x0f | ||
50 | #define REG_FANCOUNT_LOW 0x13 | ||
51 | #define REG_START 0x21 | ||
52 | #define REG_MODE 0x22 | ||
53 | #define REG_PECI_ENABLE 0x23 | ||
54 | #define REG_FAN_ENABLE 0x24 | ||
55 | #define REG_VMON_ENABLE 0x25 | ||
56 | #define REG_VENDOR_ID 0xfd | ||
57 | #define REG_CHIP_ID 0xfe | ||
58 | #define REG_VERSION_ID 0xff | ||
59 | |||
60 | /* | ||
61 | * Data structures and manipulation thereof | ||
62 | */ | ||
63 | |||
64 | struct nct7802_data { | ||
65 | struct regmap *regmap; | ||
66 | struct mutex access_lock; /* for multi-byte read and write operations */ | ||
67 | }; | ||
68 | |||
69 | static int nct7802_read_temp(struct nct7802_data *data, | ||
70 | u8 reg_temp, u8 reg_temp_low, int *temp) | ||
71 | { | ||
72 | unsigned int t1, t2 = 0; | ||
73 | int err; | ||
74 | |||
75 | *temp = 0; | ||
76 | |||
77 | mutex_lock(&data->access_lock); | ||
78 | err = regmap_read(data->regmap, reg_temp, &t1); | ||
79 | if (err < 0) | ||
80 | goto abort; | ||
81 | t1 <<= 8; | ||
82 | if (reg_temp_low) { /* 11 bit data */ | ||
83 | err = regmap_read(data->regmap, reg_temp_low, &t2); | ||
84 | if (err < 0) | ||
85 | goto abort; | ||
86 | } | ||
87 | t1 |= t2 & 0xe0; | ||
88 | *temp = (s16)t1 / 32 * 125; | ||
89 | abort: | ||
90 | mutex_unlock(&data->access_lock); | ||
91 | return err; | ||
92 | } | ||
93 | |||
94 | static int nct7802_read_fan(struct nct7802_data *data, u8 reg_fan) | ||
95 | { | ||
96 | unsigned int f1, f2; | ||
97 | int ret; | ||
98 | |||
99 | mutex_lock(&data->access_lock); | ||
100 | ret = regmap_read(data->regmap, reg_fan, &f1); | ||
101 | if (ret < 0) | ||
102 | goto abort; | ||
103 | ret = regmap_read(data->regmap, REG_FANCOUNT_LOW, &f2); | ||
104 | if (ret < 0) | ||
105 | goto abort; | ||
106 | ret = (f1 << 5) | (f2 >> 3); | ||
107 | /* convert fan count to rpm */ | ||
108 | if (ret == 0x1fff) /* maximum value, assume fan is stopped */ | ||
109 | ret = 0; | ||
110 | else if (ret) | ||
111 | ret = DIV_ROUND_CLOSEST(1350000U, ret); | ||
112 | abort: | ||
113 | mutex_unlock(&data->access_lock); | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | static int nct7802_read_fan_min(struct nct7802_data *data, u8 reg_fan_low, | ||
118 | u8 reg_fan_high) | ||
119 | { | ||
120 | unsigned int f1, f2; | ||
121 | int ret; | ||
122 | |||
123 | mutex_lock(&data->access_lock); | ||
124 | ret = regmap_read(data->regmap, reg_fan_low, &f1); | ||
125 | if (ret < 0) | ||
126 | goto abort; | ||
127 | ret = regmap_read(data->regmap, reg_fan_high, &f2); | ||
128 | if (ret < 0) | ||
129 | goto abort; | ||
130 | ret = f1 | ((f2 & 0xf8) << 5); | ||
131 | /* convert fan count to rpm */ | ||
132 | if (ret == 0x1fff) /* maximum value, assume no limit */ | ||
133 | ret = 0; | ||
134 | else if (ret) | ||
135 | ret = DIV_ROUND_CLOSEST(1350000U, ret); | ||
136 | abort: | ||
137 | mutex_unlock(&data->access_lock); | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | static int nct7802_write_fan_min(struct nct7802_data *data, u8 reg_fan_low, | ||
142 | u8 reg_fan_high, unsigned int limit) | ||
143 | { | ||
144 | int err; | ||
145 | |||
146 | if (limit) | ||
147 | limit = DIV_ROUND_CLOSEST(1350000U, limit); | ||
148 | else | ||
149 | limit = 0x1fff; | ||
150 | limit = clamp_val(limit, 0, 0x1fff); | ||
151 | |||
152 | mutex_lock(&data->access_lock); | ||
153 | err = regmap_write(data->regmap, reg_fan_low, limit & 0xff); | ||
154 | if (err < 0) | ||
155 | goto abort; | ||
156 | |||
157 | err = regmap_write(data->regmap, reg_fan_high, (limit & 0x1f00) >> 5); | ||
158 | abort: | ||
159 | mutex_unlock(&data->access_lock); | ||
160 | return err; | ||
161 | } | ||
162 | |||
163 | static u8 nct7802_vmul[] = { 4, 2, 2, 2, 2 }; | ||
164 | |||
165 | static int nct7802_read_voltage(struct nct7802_data *data, int nr, int index) | ||
166 | { | ||
167 | unsigned int v1, v2; | ||
168 | int ret; | ||
169 | |||
170 | mutex_lock(&data->access_lock); | ||
171 | if (index == 0) { /* voltage */ | ||
172 | ret = regmap_read(data->regmap, REG_VOLTAGE[nr], &v1); | ||
173 | if (ret < 0) | ||
174 | goto abort; | ||
175 | ret = regmap_read(data->regmap, REG_VOLTAGE_LOW, &v2); | ||
176 | if (ret < 0) | ||
177 | goto abort; | ||
178 | ret = ((v1 << 2) | (v2 >> 6)) * nct7802_vmul[nr]; | ||
179 | } else { /* limit */ | ||
180 | int shift = 8 - REG_VOLTAGE_LIMIT_MSB_SHIFT[index - 1][nr]; | ||
181 | |||
182 | ret = regmap_read(data->regmap, | ||
183 | REG_VOLTAGE_LIMIT_LSB[index - 1][nr], &v1); | ||
184 | if (ret < 0) | ||
185 | goto abort; | ||
186 | ret = regmap_read(data->regmap, REG_VOLTAGE_LIMIT_MSB[nr], | ||
187 | &v2); | ||
188 | if (ret < 0) | ||
189 | goto abort; | ||
190 | ret = (v1 | ((v2 << shift) & 0x300)) * nct7802_vmul[nr]; | ||
191 | } | ||
192 | abort: | ||
193 | mutex_unlock(&data->access_lock); | ||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | static int nct7802_write_voltage(struct nct7802_data *data, int nr, int index, | ||
198 | unsigned int voltage) | ||
199 | { | ||
200 | int shift = 8 - REG_VOLTAGE_LIMIT_MSB_SHIFT[index - 1][nr]; | ||
201 | int err; | ||
202 | |||
203 | voltage = DIV_ROUND_CLOSEST(voltage, nct7802_vmul[nr]); | ||
204 | voltage = clamp_val(voltage, 0, 0x3ff); | ||
205 | |||
206 | mutex_lock(&data->access_lock); | ||
207 | err = regmap_write(data->regmap, | ||
208 | REG_VOLTAGE_LIMIT_LSB[index - 1][nr], | ||
209 | voltage & 0xff); | ||
210 | if (err < 0) | ||
211 | goto abort; | ||
212 | |||
213 | err = regmap_update_bits(data->regmap, REG_VOLTAGE_LIMIT_MSB[nr], | ||
214 | 0x0300 >> shift, (voltage & 0x0300) >> shift); | ||
215 | abort: | ||
216 | mutex_unlock(&data->access_lock); | ||
217 | return err; | ||
218 | } | ||
219 | |||
220 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | ||
221 | char *buf) | ||
222 | { | ||
223 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
224 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
225 | int voltage; | ||
226 | |||
227 | voltage = nct7802_read_voltage(data, sattr->nr, sattr->index); | ||
228 | if (voltage < 0) | ||
229 | return voltage; | ||
230 | |||
231 | return sprintf(buf, "%d\n", voltage); | ||
232 | } | ||
233 | |||
234 | static ssize_t store_in(struct device *dev, struct device_attribute *attr, | ||
235 | const char *buf, size_t count) | ||
236 | { | ||
237 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
238 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
239 | int index = sattr->index; | ||
240 | int nr = sattr->nr; | ||
241 | unsigned long val; | ||
242 | int err; | ||
243 | |||
244 | err = kstrtoul(buf, 10, &val); | ||
245 | if (err < 0) | ||
246 | return err; | ||
247 | |||
248 | err = nct7802_write_voltage(data, nr, index, val); | ||
249 | return err ? : count; | ||
250 | } | ||
251 | |||
252 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | ||
253 | char *buf) | ||
254 | { | ||
255 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
256 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
257 | int err, temp; | ||
258 | |||
259 | err = nct7802_read_temp(data, sattr->nr, sattr->index, &temp); | ||
260 | if (err < 0) | ||
261 | return err; | ||
262 | |||
263 | return sprintf(buf, "%d\n", temp); | ||
264 | } | ||
265 | |||
266 | static ssize_t store_temp(struct device *dev, struct device_attribute *attr, | ||
267 | const char *buf, size_t count) | ||
268 | { | ||
269 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
270 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
271 | int nr = sattr->nr; | ||
272 | long val; | ||
273 | int err; | ||
274 | |||
275 | err = kstrtol(buf, 10, &val); | ||
276 | if (err < 0) | ||
277 | return err; | ||
278 | |||
279 | val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127); | ||
280 | |||
281 | err = regmap_write(data->regmap, nr, val & 0xff); | ||
282 | return err ? : count; | ||
283 | } | ||
284 | |||
285 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | ||
286 | char *buf) | ||
287 | { | ||
288 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
289 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
290 | int speed; | ||
291 | |||
292 | speed = nct7802_read_fan(data, sattr->index); | ||
293 | if (speed < 0) | ||
294 | return speed; | ||
295 | |||
296 | return sprintf(buf, "%d\n", speed); | ||
297 | } | ||
298 | |||
299 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, | ||
300 | char *buf) | ||
301 | { | ||
302 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
303 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
304 | int speed; | ||
305 | |||
306 | speed = nct7802_read_fan_min(data, sattr->nr, sattr->index); | ||
307 | if (speed < 0) | ||
308 | return speed; | ||
309 | |||
310 | return sprintf(buf, "%d\n", speed); | ||
311 | } | ||
312 | |||
313 | static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, | ||
314 | const char *buf, size_t count) | ||
315 | { | ||
316 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
317 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
318 | unsigned long val; | ||
319 | int err; | ||
320 | |||
321 | err = kstrtoul(buf, 10, &val); | ||
322 | if (err < 0) | ||
323 | return err; | ||
324 | |||
325 | err = nct7802_write_fan_min(data, sattr->nr, sattr->index, val); | ||
326 | return err ? : count; | ||
327 | } | ||
328 | |||
329 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | ||
330 | char *buf) | ||
331 | { | ||
332 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
333 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
334 | int bit = sattr->index; | ||
335 | unsigned int val; | ||
336 | int ret; | ||
337 | |||
338 | ret = regmap_read(data->regmap, sattr->nr, &val); | ||
339 | if (ret < 0) | ||
340 | return ret; | ||
341 | |||
342 | return sprintf(buf, "%u\n", !!(val & (1 << bit))); | ||
343 | } | ||
344 | |||
345 | static ssize_t | ||
346 | show_beep(struct device *dev, struct device_attribute *attr, char *buf) | ||
347 | { | ||
348 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
349 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
350 | unsigned int regval; | ||
351 | int err; | ||
352 | |||
353 | err = regmap_read(data->regmap, sattr->nr, ®val); | ||
354 | if (err) | ||
355 | return err; | ||
356 | |||
357 | return sprintf(buf, "%u\n", !!(regval & (1 << sattr->index))); | ||
358 | } | ||
359 | |||
360 | static ssize_t | ||
361 | store_beep(struct device *dev, struct device_attribute *attr, const char *buf, | ||
362 | size_t count) | ||
363 | { | ||
364 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
365 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
366 | unsigned long val; | ||
367 | int err; | ||
368 | |||
369 | err = kstrtoul(buf, 10, &val); | ||
370 | if (err < 0) | ||
371 | return err; | ||
372 | if (val > 1) | ||
373 | return -EINVAL; | ||
374 | |||
375 | err = regmap_update_bits(data->regmap, sattr->nr, 1 << sattr->index, | ||
376 | val ? 1 << sattr->index : 0); | ||
377 | return err ? : count; | ||
378 | } | ||
379 | |||
380 | static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0x01, | ||
381 | REG_TEMP_LSB); | ||
382 | static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, | ||
383 | store_temp, 0x31, 0); | ||
384 | static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, | ||
385 | store_temp, 0x30, 0); | ||
386 | static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, | ||
387 | store_temp, 0x3a, 0); | ||
388 | |||
389 | static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0x02, | ||
390 | REG_TEMP_LSB); | ||
391 | static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, | ||
392 | store_temp, 0x33, 0); | ||
393 | static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, | ||
394 | store_temp, 0x32, 0); | ||
395 | static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, | ||
396 | store_temp, 0x3b, 0); | ||
397 | |||
398 | static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0x03, | ||
399 | REG_TEMP_LSB); | ||
400 | static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, | ||
401 | store_temp, 0x35, 0); | ||
402 | static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, | ||
403 | store_temp, 0x34, 0); | ||
404 | static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, | ||
405 | store_temp, 0x3c, 0); | ||
406 | |||
407 | static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 0x04, 0); | ||
408 | static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, | ||
409 | store_temp, 0x37, 0); | ||
410 | static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, | ||
411 | store_temp, 0x36, 0); | ||
412 | static SENSOR_DEVICE_ATTR_2(temp4_crit, S_IRUGO | S_IWUSR, show_temp, | ||
413 | store_temp, 0x3d, 0); | ||
414 | |||
415 | static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 0x06, | ||
416 | REG_TEMP_PECI_LSB); | ||
417 | static SENSOR_DEVICE_ATTR_2(temp5_min, S_IRUGO | S_IWUSR, show_temp, | ||
418 | store_temp, 0x39, 0); | ||
419 | static SENSOR_DEVICE_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, | ||
420 | store_temp, 0x38, 0); | ||
421 | static SENSOR_DEVICE_ATTR_2(temp5_crit, S_IRUGO | S_IWUSR, show_temp, | ||
422 | store_temp, 0x3e, 0); | ||
423 | |||
424 | static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 0x07, | ||
425 | REG_TEMP_PECI_LSB); | ||
426 | |||
427 | static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, show_alarm, NULL, | ||
428 | 0x18, 0); | ||
429 | static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, show_alarm, NULL, | ||
430 | 0x18, 1); | ||
431 | static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, show_alarm, NULL, | ||
432 | 0x18, 2); | ||
433 | static SENSOR_DEVICE_ATTR_2(temp4_min_alarm, S_IRUGO, show_alarm, NULL, | ||
434 | 0x18, 3); | ||
435 | static SENSOR_DEVICE_ATTR_2(temp5_min_alarm, S_IRUGO, show_alarm, NULL, | ||
436 | 0x18, 4); | ||
437 | |||
438 | static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, show_alarm, NULL, | ||
439 | 0x19, 0); | ||
440 | static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, show_alarm, NULL, | ||
441 | 0x19, 1); | ||
442 | static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, show_alarm, NULL, | ||
443 | 0x19, 2); | ||
444 | static SENSOR_DEVICE_ATTR_2(temp4_max_alarm, S_IRUGO, show_alarm, NULL, | ||
445 | 0x19, 3); | ||
446 | static SENSOR_DEVICE_ATTR_2(temp5_max_alarm, S_IRUGO, show_alarm, NULL, | ||
447 | 0x19, 4); | ||
448 | |||
449 | static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, | ||
450 | 0x1b, 0); | ||
451 | static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, | ||
452 | 0x1b, 1); | ||
453 | static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, | ||
454 | 0x1b, 2); | ||
455 | static SENSOR_DEVICE_ATTR_2(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, | ||
456 | 0x1b, 3); | ||
457 | static SENSOR_DEVICE_ATTR_2(temp5_crit_alarm, S_IRUGO, show_alarm, NULL, | ||
458 | 0x1b, 4); | ||
459 | |||
460 | static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_alarm, NULL, 0x17, 0); | ||
461 | static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_alarm, NULL, 0x17, 1); | ||
462 | static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_alarm, NULL, 0x17, 2); | ||
463 | |||
464 | static SENSOR_DEVICE_ATTR_2(temp1_beep, S_IRUGO | S_IWUSR, show_beep, | ||
465 | store_beep, 0x5c, 0); | ||
466 | static SENSOR_DEVICE_ATTR_2(temp2_beep, S_IRUGO | S_IWUSR, show_beep, | ||
467 | store_beep, 0x5c, 1); | ||
468 | static SENSOR_DEVICE_ATTR_2(temp3_beep, S_IRUGO | S_IWUSR, show_beep, | ||
469 | store_beep, 0x5c, 2); | ||
470 | static SENSOR_DEVICE_ATTR_2(temp4_beep, S_IRUGO | S_IWUSR, show_beep, | ||
471 | store_beep, 0x5c, 3); | ||
472 | static SENSOR_DEVICE_ATTR_2(temp5_beep, S_IRUGO | S_IWUSR, show_beep, | ||
473 | store_beep, 0x5c, 4); | ||
474 | static SENSOR_DEVICE_ATTR_2(temp6_beep, S_IRUGO | S_IWUSR, show_beep, | ||
475 | store_beep, 0x5c, 5); | ||
476 | |||
477 | static struct attribute *nct7802_temp_attrs[] = { | ||
478 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
479 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
480 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
481 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
482 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
483 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
484 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
485 | &sensor_dev_attr_temp1_fault.dev_attr.attr, | ||
486 | &sensor_dev_attr_temp1_beep.dev_attr.attr, | ||
487 | |||
488 | &sensor_dev_attr_temp2_input.dev_attr.attr, /* 9 */ | ||
489 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
490 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
491 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | ||
492 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | ||
493 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | ||
494 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | ||
495 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
496 | &sensor_dev_attr_temp2_beep.dev_attr.attr, | ||
497 | |||
498 | &sensor_dev_attr_temp3_input.dev_attr.attr, /* 18 */ | ||
499 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
500 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
501 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | ||
502 | &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, | ||
503 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | ||
504 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | ||
505 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
506 | &sensor_dev_attr_temp3_beep.dev_attr.attr, | ||
507 | |||
508 | &sensor_dev_attr_temp4_input.dev_attr.attr, /* 27 */ | ||
509 | &sensor_dev_attr_temp4_min.dev_attr.attr, | ||
510 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
511 | &sensor_dev_attr_temp4_crit.dev_attr.attr, | ||
512 | &sensor_dev_attr_temp4_min_alarm.dev_attr.attr, | ||
513 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, | ||
514 | &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, | ||
515 | &sensor_dev_attr_temp4_beep.dev_attr.attr, | ||
516 | |||
517 | &sensor_dev_attr_temp5_input.dev_attr.attr, /* 35 */ | ||
518 | &sensor_dev_attr_temp5_min.dev_attr.attr, | ||
519 | &sensor_dev_attr_temp5_max.dev_attr.attr, | ||
520 | &sensor_dev_attr_temp5_crit.dev_attr.attr, | ||
521 | &sensor_dev_attr_temp5_min_alarm.dev_attr.attr, | ||
522 | &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, | ||
523 | &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr, | ||
524 | &sensor_dev_attr_temp5_beep.dev_attr.attr, | ||
525 | |||
526 | &sensor_dev_attr_temp6_input.dev_attr.attr, /* 43 */ | ||
527 | &sensor_dev_attr_temp6_beep.dev_attr.attr, | ||
528 | |||
529 | NULL | ||
530 | }; | ||
531 | |||
532 | static umode_t nct7802_temp_is_visible(struct kobject *kobj, | ||
533 | struct attribute *attr, int index) | ||
534 | { | ||
535 | struct device *dev = container_of(kobj, struct device, kobj); | ||
536 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
537 | unsigned int reg; | ||
538 | int err; | ||
539 | |||
540 | err = regmap_read(data->regmap, REG_MODE, ®); | ||
541 | if (err < 0) | ||
542 | return 0; | ||
543 | |||
544 | if (index < 9 && | ||
545 | (reg & 03) != 0x01 && (reg & 0x03) != 0x02) /* RD1 */ | ||
546 | return 0; | ||
547 | if (index >= 9 && index < 18 && | ||
548 | (reg & 0x0c) != 0x04 && (reg & 0x0c) != 0x08) /* RD2 */ | ||
549 | return 0; | ||
550 | if (index >= 18 && index < 27 && (reg & 0x30) != 0x10) /* RD3 */ | ||
551 | return 0; | ||
552 | if (index >= 27 && index < 35) /* local */ | ||
553 | return attr->mode; | ||
554 | |||
555 | err = regmap_read(data->regmap, REG_PECI_ENABLE, ®); | ||
556 | if (err < 0) | ||
557 | return 0; | ||
558 | |||
559 | if (index >= 35 && index < 43 && !(reg & 0x01)) /* PECI 0 */ | ||
560 | return 0; | ||
561 | |||
562 | if (index >= 0x43 && (!(reg & 0x02))) /* PECI 1 */ | ||
563 | return 0; | ||
564 | |||
565 | return attr->mode; | ||
566 | } | ||
567 | |||
568 | static struct attribute_group nct7802_temp_group = { | ||
569 | .attrs = nct7802_temp_attrs, | ||
570 | .is_visible = nct7802_temp_is_visible, | ||
571 | }; | ||
572 | |||
573 | static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0); | ||
574 | static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_in, store_in, | ||
575 | 0, 1); | ||
576 | static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_in, store_in, | ||
577 | 0, 2); | ||
578 | static SENSOR_DEVICE_ATTR_2(in0_alarm, S_IRUGO, show_alarm, NULL, 0x1e, 3); | ||
579 | static SENSOR_DEVICE_ATTR_2(in0_beep, S_IRUGO | S_IWUSR, show_beep, store_beep, | ||
580 | 0x5a, 3); | ||
581 | |||
582 | static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 1, 0); | ||
583 | |||
584 | static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 2, 0); | ||
585 | static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_in, store_in, | ||
586 | 2, 1); | ||
587 | static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_in, store_in, | ||
588 | 2, 2); | ||
589 | static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, show_alarm, NULL, 0x1e, 0); | ||
590 | static SENSOR_DEVICE_ATTR_2(in2_beep, S_IRUGO | S_IWUSR, show_beep, store_beep, | ||
591 | 0x5a, 0); | ||
592 | |||
593 | static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 3, 0); | ||
594 | static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_in, store_in, | ||
595 | 3, 1); | ||
596 | static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_in, store_in, | ||
597 | 3, 2); | ||
598 | static SENSOR_DEVICE_ATTR_2(in3_alarm, S_IRUGO, show_alarm, NULL, 0x1e, 1); | ||
599 | static SENSOR_DEVICE_ATTR_2(in3_beep, S_IRUGO | S_IWUSR, show_beep, store_beep, | ||
600 | 0x5a, 1); | ||
601 | |||
602 | static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 4, 0); | ||
603 | static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_in, store_in, | ||
604 | 4, 1); | ||
605 | static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_in, store_in, | ||
606 | 4, 2); | ||
607 | static SENSOR_DEVICE_ATTR_2(in4_alarm, S_IRUGO, show_alarm, NULL, 0x1e, 2); | ||
608 | static SENSOR_DEVICE_ATTR_2(in4_beep, S_IRUGO | S_IWUSR, show_beep, store_beep, | ||
609 | 0x5a, 2); | ||
610 | |||
611 | static struct attribute *nct7802_in_attrs[] = { | ||
612 | &sensor_dev_attr_in0_input.dev_attr.attr, | ||
613 | &sensor_dev_attr_in0_min.dev_attr.attr, | ||
614 | &sensor_dev_attr_in0_max.dev_attr.attr, | ||
615 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | ||
616 | &sensor_dev_attr_in0_beep.dev_attr.attr, | ||
617 | |||
618 | &sensor_dev_attr_in1_input.dev_attr.attr, /* 5 */ | ||
619 | |||
620 | &sensor_dev_attr_in2_input.dev_attr.attr, /* 6 */ | ||
621 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
622 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
623 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
624 | &sensor_dev_attr_in2_beep.dev_attr.attr, | ||
625 | |||
626 | &sensor_dev_attr_in3_input.dev_attr.attr, /* 11 */ | ||
627 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
628 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
629 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
630 | &sensor_dev_attr_in3_beep.dev_attr.attr, | ||
631 | |||
632 | &sensor_dev_attr_in4_input.dev_attr.attr, /* 17 */ | ||
633 | &sensor_dev_attr_in4_min.dev_attr.attr, | ||
634 | &sensor_dev_attr_in4_max.dev_attr.attr, | ||
635 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
636 | &sensor_dev_attr_in4_beep.dev_attr.attr, | ||
637 | |||
638 | NULL, | ||
639 | }; | ||
640 | |||
641 | static umode_t nct7802_in_is_visible(struct kobject *kobj, | ||
642 | struct attribute *attr, int index) | ||
643 | { | ||
644 | struct device *dev = container_of(kobj, struct device, kobj); | ||
645 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
646 | unsigned int reg; | ||
647 | int err; | ||
648 | |||
649 | if (index < 6) /* VCC, VCORE */ | ||
650 | return attr->mode; | ||
651 | |||
652 | err = regmap_read(data->regmap, REG_MODE, ®); | ||
653 | if (err < 0) | ||
654 | return 0; | ||
655 | |||
656 | if (index >= 6 && index < 11 && (reg & 0x03) != 0x03) /* VSEN1 */ | ||
657 | return 0; | ||
658 | if (index >= 11 && index < 17 && (reg & 0x0c) != 0x0c) /* VSEN2 */ | ||
659 | return 0; | ||
660 | if (index >= 17 && (reg & 0x30) != 0x30) /* VSEN3 */ | ||
661 | return 0; | ||
662 | |||
663 | return attr->mode; | ||
664 | } | ||
665 | |||
666 | static struct attribute_group nct7802_in_group = { | ||
667 | .attrs = nct7802_in_attrs, | ||
668 | .is_visible = nct7802_in_is_visible, | ||
669 | }; | ||
670 | |||
671 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0x10); | ||
672 | static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan_min, | ||
673 | store_fan_min, 0x49, 0x4c); | ||
674 | static SENSOR_DEVICE_ATTR_2(fan1_alarm, S_IRUGO, show_alarm, NULL, 0x1a, 0); | ||
675 | static SENSOR_DEVICE_ATTR_2(fan1_beep, S_IRUGO | S_IWUSR, show_beep, store_beep, | ||
676 | 0x5b, 0); | ||
677 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 0x11); | ||
678 | static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_fan_min, | ||
679 | store_fan_min, 0x4a, 0x4d); | ||
680 | static SENSOR_DEVICE_ATTR_2(fan2_alarm, S_IRUGO, show_alarm, NULL, 0x1a, 1); | ||
681 | static SENSOR_DEVICE_ATTR_2(fan2_beep, S_IRUGO | S_IWUSR, show_beep, store_beep, | ||
682 | 0x5b, 1); | ||
683 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 0x12); | ||
684 | static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_fan_min, | ||
685 | store_fan_min, 0x4b, 0x4e); | ||
686 | static SENSOR_DEVICE_ATTR_2(fan3_alarm, S_IRUGO, show_alarm, NULL, 0x1a, 2); | ||
687 | static SENSOR_DEVICE_ATTR_2(fan3_beep, S_IRUGO | S_IWUSR, show_beep, store_beep, | ||
688 | 0x5b, 2); | ||
689 | |||
690 | static struct attribute *nct7802_fan_attrs[] = { | ||
691 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
692 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
693 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
694 | &sensor_dev_attr_fan1_beep.dev_attr.attr, | ||
695 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
696 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
697 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
698 | &sensor_dev_attr_fan2_beep.dev_attr.attr, | ||
699 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
700 | &sensor_dev_attr_fan3_min.dev_attr.attr, | ||
701 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | ||
702 | &sensor_dev_attr_fan3_beep.dev_attr.attr, | ||
703 | |||
704 | NULL | ||
705 | }; | ||
706 | |||
707 | static umode_t nct7802_fan_is_visible(struct kobject *kobj, | ||
708 | struct attribute *attr, int index) | ||
709 | { | ||
710 | struct device *dev = container_of(kobj, struct device, kobj); | ||
711 | struct nct7802_data *data = dev_get_drvdata(dev); | ||
712 | int fan = index / 4; /* 4 attributes per fan */ | ||
713 | unsigned int reg; | ||
714 | int err; | ||
715 | |||
716 | err = regmap_read(data->regmap, REG_FAN_ENABLE, ®); | ||
717 | if (err < 0 || !(reg & (1 << fan))) | ||
718 | return 0; | ||
719 | |||
720 | return attr->mode; | ||
721 | } | ||
722 | |||
723 | static struct attribute_group nct7802_fan_group = { | ||
724 | .attrs = nct7802_fan_attrs, | ||
725 | .is_visible = nct7802_fan_is_visible, | ||
726 | }; | ||
727 | |||
728 | static const struct attribute_group *nct7802_groups[] = { | ||
729 | &nct7802_temp_group, | ||
730 | &nct7802_in_group, | ||
731 | &nct7802_fan_group, | ||
732 | NULL | ||
733 | }; | ||
734 | |||
735 | static int nct7802_detect(struct i2c_client *client, | ||
736 | struct i2c_board_info *info) | ||
737 | { | ||
738 | int reg; | ||
739 | |||
740 | /* | ||
741 | * Chip identification registers are only available in bank 0, | ||
742 | * so only attempt chip detection if bank 0 is selected | ||
743 | */ | ||
744 | reg = i2c_smbus_read_byte_data(client, REG_BANK); | ||
745 | if (reg != 0x00) | ||
746 | return -ENODEV; | ||
747 | |||
748 | reg = i2c_smbus_read_byte_data(client, REG_VENDOR_ID); | ||
749 | if (reg != 0x50) | ||
750 | return -ENODEV; | ||
751 | |||
752 | reg = i2c_smbus_read_byte_data(client, REG_CHIP_ID); | ||
753 | if (reg != 0xc3) | ||
754 | return -ENODEV; | ||
755 | |||
756 | reg = i2c_smbus_read_byte_data(client, REG_VERSION_ID); | ||
757 | if (reg < 0 || (reg & 0xf0) != 0x20) | ||
758 | return -ENODEV; | ||
759 | |||
760 | /* Also validate lower bits of voltage and temperature registers */ | ||
761 | reg = i2c_smbus_read_byte_data(client, REG_TEMP_LSB); | ||
762 | if (reg < 0 || (reg & 0x1f)) | ||
763 | return -ENODEV; | ||
764 | |||
765 | reg = i2c_smbus_read_byte_data(client, REG_TEMP_PECI_LSB); | ||
766 | if (reg < 0 || (reg & 0x3f)) | ||
767 | return -ENODEV; | ||
768 | |||
769 | reg = i2c_smbus_read_byte_data(client, REG_VOLTAGE_LOW); | ||
770 | if (reg < 0 || (reg & 0x3f)) | ||
771 | return -ENODEV; | ||
772 | |||
773 | strlcpy(info->type, "nct7802", I2C_NAME_SIZE); | ||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | static bool nct7802_regmap_is_volatile(struct device *dev, unsigned int reg) | ||
778 | { | ||
779 | return reg != REG_BANK && reg <= 0x20; | ||
780 | } | ||
781 | |||
782 | static struct regmap_config nct7802_regmap_config = { | ||
783 | .reg_bits = 8, | ||
784 | .val_bits = 8, | ||
785 | .cache_type = REGCACHE_RBTREE, | ||
786 | .volatile_reg = nct7802_regmap_is_volatile, | ||
787 | }; | ||
788 | |||
789 | static int nct7802_init_chip(struct nct7802_data *data) | ||
790 | { | ||
791 | int err; | ||
792 | |||
793 | /* Enable ADC */ | ||
794 | err = regmap_update_bits(data->regmap, REG_START, 0x01, 0x01); | ||
795 | if (err) | ||
796 | return err; | ||
797 | |||
798 | /* Enable local temperature sensor */ | ||
799 | err = regmap_update_bits(data->regmap, REG_MODE, 0x40, 0x40); | ||
800 | if (err) | ||
801 | return err; | ||
802 | |||
803 | /* Enable Vcore and VCC voltage monitoring */ | ||
804 | return regmap_update_bits(data->regmap, REG_VMON_ENABLE, 0x03, 0x03); | ||
805 | } | ||
806 | |||
807 | static int nct7802_probe(struct i2c_client *client, | ||
808 | const struct i2c_device_id *id) | ||
809 | { | ||
810 | struct device *dev = &client->dev; | ||
811 | struct nct7802_data *data; | ||
812 | struct device *hwmon_dev; | ||
813 | int ret; | ||
814 | |||
815 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); | ||
816 | if (data == NULL) | ||
817 | return -ENOMEM; | ||
818 | |||
819 | data->regmap = devm_regmap_init_i2c(client, &nct7802_regmap_config); | ||
820 | if (IS_ERR(data->regmap)) | ||
821 | return PTR_ERR(data->regmap); | ||
822 | |||
823 | mutex_init(&data->access_lock); | ||
824 | |||
825 | ret = nct7802_init_chip(data); | ||
826 | if (ret < 0) | ||
827 | return ret; | ||
828 | |||
829 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | ||
830 | data, | ||
831 | nct7802_groups); | ||
832 | return PTR_ERR_OR_ZERO(hwmon_dev); | ||
833 | } | ||
834 | |||
835 | static const unsigned short nct7802_address_list[] = { | ||
836 | 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END | ||
837 | }; | ||
838 | |||
839 | static const struct i2c_device_id nct7802_idtable[] = { | ||
840 | { "nct7802", 0 }, | ||
841 | { } | ||
842 | }; | ||
843 | MODULE_DEVICE_TABLE(i2c, nct7802_idtable); | ||
844 | |||
845 | static struct i2c_driver nct7802_driver = { | ||
846 | .class = I2C_CLASS_HWMON, | ||
847 | .driver = { | ||
848 | .name = DRVNAME, | ||
849 | }, | ||
850 | .detect = nct7802_detect, | ||
851 | .probe = nct7802_probe, | ||
852 | .id_table = nct7802_idtable, | ||
853 | .address_list = nct7802_address_list, | ||
854 | }; | ||
855 | |||
856 | module_i2c_driver(nct7802_driver); | ||
857 | |||
858 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); | ||
859 | MODULE_DESCRIPTION("NCT7802Y Hardware Monitoring Driver"); | ||
860 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 6e1e4935fc62..a674cd83a4e2 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig | |||
@@ -47,15 +47,22 @@ config SENSORS_LM25066 | |||
47 | be called lm25066. | 47 | be called lm25066. |
48 | 48 | ||
49 | config SENSORS_LTC2978 | 49 | config SENSORS_LTC2978 |
50 | tristate "Linear Technologies LTC2974, LTC2978, LTC3880, and LTC3883" | 50 | tristate "Linear Technologies LTC2978 and compatibles" |
51 | default n | 51 | default n |
52 | help | 52 | help |
53 | If you say yes here you get hardware monitoring support for Linear | 53 | If you say yes here you get hardware monitoring support for Linear |
54 | Technology LTC2974, LTC2978, LTC3880, and LTC3883. | 54 | Technology LTC2974, LTC2977, LTC2978, LTC3880, LTC3883, and LTM4676. |
55 | 55 | ||
56 | This driver can also be built as a module. If so, the module will | 56 | This driver can also be built as a module. If so, the module will |
57 | be called ltc2978. | 57 | be called ltc2978. |
58 | 58 | ||
59 | config SENSORS_LTC2978_REGULATOR | ||
60 | boolean "Regulator support for LTC2978 and compatibles" | ||
61 | depends on SENSORS_LTC2978 && REGULATOR | ||
62 | help | ||
63 | If you say yes here you get regulator support for Linear | ||
64 | Technology LTC2974, LTC2977, LTC2978, LTC3880, LTC3883, and LTM4676. | ||
65 | |||
59 | config SENSORS_MAX16064 | 66 | config SENSORS_MAX16064 |
60 | tristate "Maxim MAX16064" | 67 | tristate "Maxim MAX16064" |
61 | default n | 68 | default n |
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index e24ed521051a..0835050ec245 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
25 | #include <linux/regulator/driver.h> | ||
25 | #include "pmbus.h" | 26 | #include "pmbus.h" |
26 | 27 | ||
27 | enum chips { ltc2974, ltc2977, ltc2978, ltc3880, ltc3883, ltm4676 }; | 28 | enum chips { ltc2974, ltc2977, ltc2978, ltc3880, ltc3883, ltm4676 }; |
@@ -374,6 +375,19 @@ static const struct i2c_device_id ltc2978_id[] = { | |||
374 | }; | 375 | }; |
375 | MODULE_DEVICE_TABLE(i2c, ltc2978_id); | 376 | MODULE_DEVICE_TABLE(i2c, ltc2978_id); |
376 | 377 | ||
378 | #if IS_ENABLED(CONFIG_SENSORS_LTC2978_REGULATOR) | ||
379 | static const struct regulator_desc ltc2978_reg_desc[] = { | ||
380 | PMBUS_REGULATOR("vout", 0), | ||
381 | PMBUS_REGULATOR("vout", 1), | ||
382 | PMBUS_REGULATOR("vout", 2), | ||
383 | PMBUS_REGULATOR("vout", 3), | ||
384 | PMBUS_REGULATOR("vout", 4), | ||
385 | PMBUS_REGULATOR("vout", 5), | ||
386 | PMBUS_REGULATOR("vout", 6), | ||
387 | PMBUS_REGULATOR("vout", 7), | ||
388 | }; | ||
389 | #endif /* CONFIG_SENSORS_LTC2978_REGULATOR */ | ||
390 | |||
377 | static int ltc2978_probe(struct i2c_client *client, | 391 | static int ltc2978_probe(struct i2c_client *client, |
378 | const struct i2c_device_id *id) | 392 | const struct i2c_device_id *id) |
379 | { | 393 | { |
@@ -487,13 +501,36 @@ static int ltc2978_probe(struct i2c_client *client, | |||
487 | default: | 501 | default: |
488 | return -ENODEV; | 502 | return -ENODEV; |
489 | } | 503 | } |
504 | |||
505 | #if IS_ENABLED(CONFIG_SENSORS_LTC2978_REGULATOR) | ||
506 | info->num_regulators = info->pages; | ||
507 | info->reg_desc = ltc2978_reg_desc; | ||
508 | if (info->num_regulators > ARRAY_SIZE(ltc2978_reg_desc)) { | ||
509 | dev_err(&client->dev, "num_regulators too large!"); | ||
510 | info->num_regulators = ARRAY_SIZE(ltc2978_reg_desc); | ||
511 | } | ||
512 | #endif | ||
513 | |||
490 | return pmbus_do_probe(client, id, info); | 514 | return pmbus_do_probe(client, id, info); |
491 | } | 515 | } |
492 | 516 | ||
493 | /* This is the driver that will be inserted */ | 517 | #ifdef CONFIG_OF |
518 | static const struct of_device_id ltc2978_of_match[] = { | ||
519 | { .compatible = "lltc,ltc2974" }, | ||
520 | { .compatible = "lltc,ltc2977" }, | ||
521 | { .compatible = "lltc,ltc2978" }, | ||
522 | { .compatible = "lltc,ltc3880" }, | ||
523 | { .compatible = "lltc,ltc3883" }, | ||
524 | { .compatible = "lltc,ltm4676" }, | ||
525 | { } | ||
526 | }; | ||
527 | MODULE_DEVICE_TABLE(of, ltc2978_of_match); | ||
528 | #endif | ||
529 | |||
494 | static struct i2c_driver ltc2978_driver = { | 530 | static struct i2c_driver ltc2978_driver = { |
495 | .driver = { | 531 | .driver = { |
496 | .name = "ltc2978", | 532 | .name = "ltc2978", |
533 | .of_match_table = of_match_ptr(ltc2978_of_match), | ||
497 | }, | 534 | }, |
498 | .probe = ltc2978_probe, | 535 | .probe = ltc2978_probe, |
499 | .remove = pmbus_do_remove, | 536 | .remove = pmbus_do_remove, |
diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h index fa9beb3eb60c..89a23ff836e7 100644 --- a/drivers/hwmon/pmbus/pmbus.h +++ b/drivers/hwmon/pmbus/pmbus.h | |||
@@ -19,6 +19,8 @@ | |||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/regulator/driver.h> | ||
23 | |||
22 | #ifndef PMBUS_H | 24 | #ifndef PMBUS_H |
23 | #define PMBUS_H | 25 | #define PMBUS_H |
24 | 26 | ||
@@ -186,6 +188,11 @@ | |||
186 | #define PMBUS_VIRT_STATUS_VMON (PMBUS_VIRT_BASE + 35) | 188 | #define PMBUS_VIRT_STATUS_VMON (PMBUS_VIRT_BASE + 35) |
187 | 189 | ||
188 | /* | 190 | /* |
191 | * OPERATION | ||
192 | */ | ||
193 | #define PB_OPERATION_CONTROL_ON (1<<7) | ||
194 | |||
195 | /* | ||
189 | * CAPABILITY | 196 | * CAPABILITY |
190 | */ | 197 | */ |
191 | #define PB_CAPABILITY_SMBALERT (1<<4) | 198 | #define PB_CAPABILITY_SMBALERT (1<<4) |
@@ -365,8 +372,27 @@ struct pmbus_driver_info { | |||
365 | */ | 372 | */ |
366 | int (*identify)(struct i2c_client *client, | 373 | int (*identify)(struct i2c_client *client, |
367 | struct pmbus_driver_info *info); | 374 | struct pmbus_driver_info *info); |
375 | |||
376 | /* Regulator functionality, if supported by this chip driver. */ | ||
377 | int num_regulators; | ||
378 | const struct regulator_desc *reg_desc; | ||
368 | }; | 379 | }; |
369 | 380 | ||
381 | /* Regulator ops */ | ||
382 | |||
383 | extern struct regulator_ops pmbus_regulator_ops; | ||
384 | |||
385 | /* Macro for filling in array of struct regulator_desc */ | ||
386 | #define PMBUS_REGULATOR(_name, _id) \ | ||
387 | [_id] = { \ | ||
388 | .name = (_name # _id), \ | ||
389 | .id = (_id), \ | ||
390 | .of_match = of_match_ptr(_name # _id), \ | ||
391 | .regulators_node = of_match_ptr("regulators"), \ | ||
392 | .ops = &pmbus_regulator_ops, \ | ||
393 | .owner = THIS_MODULE, \ | ||
394 | } | ||
395 | |||
370 | /* Function declarations */ | 396 | /* Function declarations */ |
371 | 397 | ||
372 | void pmbus_clear_cache(struct i2c_client *client); | 398 | void pmbus_clear_cache(struct i2c_client *client); |
@@ -375,6 +401,10 @@ int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); | |||
375 | int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); | 401 | int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); |
376 | int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); | 402 | int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); |
377 | int pmbus_write_byte(struct i2c_client *client, int page, u8 value); | 403 | int pmbus_write_byte(struct i2c_client *client, int page, u8 value); |
404 | int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, | ||
405 | u8 value); | ||
406 | int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, | ||
407 | u8 mask, u8 value); | ||
378 | void pmbus_clear_faults(struct i2c_client *client); | 408 | void pmbus_clear_faults(struct i2c_client *client); |
379 | bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); | 409 | bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); |
380 | bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); | 410 | bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); |
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 291d11fe93e7..f2e47c7dd808 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <linux/hwmon-sysfs.h> | 29 | #include <linux/hwmon-sysfs.h> |
30 | #include <linux/jiffies.h> | 30 | #include <linux/jiffies.h> |
31 | #include <linux/i2c/pmbus.h> | 31 | #include <linux/i2c/pmbus.h> |
32 | #include <linux/regulator/driver.h> | ||
33 | #include <linux/regulator/machine.h> | ||
32 | #include "pmbus.h" | 34 | #include "pmbus.h" |
33 | 35 | ||
34 | /* | 36 | /* |
@@ -253,6 +255,37 @@ int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg) | |||
253 | } | 255 | } |
254 | EXPORT_SYMBOL_GPL(pmbus_read_byte_data); | 256 | EXPORT_SYMBOL_GPL(pmbus_read_byte_data); |
255 | 257 | ||
258 | int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, u8 value) | ||
259 | { | ||
260 | int rv; | ||
261 | |||
262 | rv = pmbus_set_page(client, page); | ||
263 | if (rv < 0) | ||
264 | return rv; | ||
265 | |||
266 | return i2c_smbus_write_byte_data(client, reg, value); | ||
267 | } | ||
268 | EXPORT_SYMBOL_GPL(pmbus_write_byte_data); | ||
269 | |||
270 | int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, | ||
271 | u8 mask, u8 value) | ||
272 | { | ||
273 | unsigned int tmp; | ||
274 | int rv; | ||
275 | |||
276 | rv = pmbus_read_byte_data(client, page, reg); | ||
277 | if (rv < 0) | ||
278 | return rv; | ||
279 | |||
280 | tmp = (rv & ~mask) | (value & mask); | ||
281 | |||
282 | if (tmp != rv) | ||
283 | rv = pmbus_write_byte_data(client, page, reg, tmp); | ||
284 | |||
285 | return rv; | ||
286 | } | ||
287 | EXPORT_SYMBOL_GPL(pmbus_update_byte_data); | ||
288 | |||
256 | /* | 289 | /* |
257 | * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if | 290 | * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if |
258 | * a device specific mapping function exists and calls it if necessary. | 291 | * a device specific mapping function exists and calls it if necessary. |
@@ -1727,6 +1760,84 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, | |||
1727 | return 0; | 1760 | return 0; |
1728 | } | 1761 | } |
1729 | 1762 | ||
1763 | #if IS_ENABLED(CONFIG_REGULATOR) | ||
1764 | static int pmbus_regulator_is_enabled(struct regulator_dev *rdev) | ||
1765 | { | ||
1766 | struct device *dev = rdev_get_dev(rdev); | ||
1767 | struct i2c_client *client = to_i2c_client(dev->parent); | ||
1768 | u8 page = rdev_get_id(rdev); | ||
1769 | int ret; | ||
1770 | |||
1771 | ret = pmbus_read_byte_data(client, page, PMBUS_OPERATION); | ||
1772 | if (ret < 0) | ||
1773 | return ret; | ||
1774 | |||
1775 | return !!(ret & PB_OPERATION_CONTROL_ON); | ||
1776 | } | ||
1777 | |||
1778 | static int _pmbus_regulator_on_off(struct regulator_dev *rdev, bool enable) | ||
1779 | { | ||
1780 | struct device *dev = rdev_get_dev(rdev); | ||
1781 | struct i2c_client *client = to_i2c_client(dev->parent); | ||
1782 | u8 page = rdev_get_id(rdev); | ||
1783 | |||
1784 | return pmbus_update_byte_data(client, page, PMBUS_OPERATION, | ||
1785 | PB_OPERATION_CONTROL_ON, | ||
1786 | enable ? PB_OPERATION_CONTROL_ON : 0); | ||
1787 | } | ||
1788 | |||
1789 | static int pmbus_regulator_enable(struct regulator_dev *rdev) | ||
1790 | { | ||
1791 | return _pmbus_regulator_on_off(rdev, 1); | ||
1792 | } | ||
1793 | |||
1794 | static int pmbus_regulator_disable(struct regulator_dev *rdev) | ||
1795 | { | ||
1796 | return _pmbus_regulator_on_off(rdev, 0); | ||
1797 | } | ||
1798 | |||
1799 | struct regulator_ops pmbus_regulator_ops = { | ||
1800 | .enable = pmbus_regulator_enable, | ||
1801 | .disable = pmbus_regulator_disable, | ||
1802 | .is_enabled = pmbus_regulator_is_enabled, | ||
1803 | }; | ||
1804 | EXPORT_SYMBOL_GPL(pmbus_regulator_ops); | ||
1805 | |||
1806 | static int pmbus_regulator_register(struct pmbus_data *data) | ||
1807 | { | ||
1808 | struct device *dev = data->dev; | ||
1809 | const struct pmbus_driver_info *info = data->info; | ||
1810 | const struct pmbus_platform_data *pdata = dev_get_platdata(dev); | ||
1811 | struct regulator_dev *rdev; | ||
1812 | int i; | ||
1813 | |||
1814 | for (i = 0; i < info->num_regulators; i++) { | ||
1815 | struct regulator_config config = { }; | ||
1816 | |||
1817 | config.dev = dev; | ||
1818 | config.driver_data = data; | ||
1819 | |||
1820 | if (pdata && pdata->reg_init_data) | ||
1821 | config.init_data = &pdata->reg_init_data[i]; | ||
1822 | |||
1823 | rdev = devm_regulator_register(dev, &info->reg_desc[i], | ||
1824 | &config); | ||
1825 | if (IS_ERR(rdev)) { | ||
1826 | dev_err(dev, "Failed to register %s regulator\n", | ||
1827 | info->reg_desc[i].name); | ||
1828 | return PTR_ERR(rdev); | ||
1829 | } | ||
1830 | } | ||
1831 | |||
1832 | return 0; | ||
1833 | } | ||
1834 | #else | ||
1835 | static int pmbus_regulator_register(struct pmbus_data *data) | ||
1836 | { | ||
1837 | return 0; | ||
1838 | } | ||
1839 | #endif | ||
1840 | |||
1730 | int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, | 1841 | int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, |
1731 | struct pmbus_driver_info *info) | 1842 | struct pmbus_driver_info *info) |
1732 | { | 1843 | { |
@@ -1781,8 +1892,15 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, | |||
1781 | dev_err(dev, "Failed to register hwmon device\n"); | 1892 | dev_err(dev, "Failed to register hwmon device\n"); |
1782 | goto out_kfree; | 1893 | goto out_kfree; |
1783 | } | 1894 | } |
1895 | |||
1896 | ret = pmbus_regulator_register(data); | ||
1897 | if (ret) | ||
1898 | goto out_unregister; | ||
1899 | |||
1784 | return 0; | 1900 | return 0; |
1785 | 1901 | ||
1902 | out_unregister: | ||
1903 | hwmon_device_unregister(data->hwmon_dev); | ||
1786 | out_kfree: | 1904 | out_kfree: |
1787 | kfree(data->group.attrs); | 1905 | kfree(data->group.attrs); |
1788 | return ret; | 1906 | return ret; |
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index 7fa6e7d0b9b6..99664ebc738d 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c | |||
@@ -44,9 +44,10 @@ | |||
44 | #include <linux/sysfs.h> | 44 | #include <linux/sysfs.h> |
45 | 45 | ||
46 | /* Addresses to scan */ | 46 | /* Addresses to scan */ |
47 | static const unsigned short normal_i2c[] = { 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; | 47 | static const unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4c, 0x4d, |
48 | 0x4e, 0x4f, I2C_CLIENT_END }; | ||
48 | 49 | ||
49 | enum chips { tmp401, tmp411, tmp431, tmp432 }; | 50 | enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; |
50 | 51 | ||
51 | /* | 52 | /* |
52 | * The TMP401 registers, note some registers have different addresses for | 53 | * The TMP401 registers, note some registers have different addresses for |
@@ -136,6 +137,7 @@ static const u8 TMP432_STATUS_REG[] = { | |||
136 | #define TMP411C_DEVICE_ID 0x10 | 137 | #define TMP411C_DEVICE_ID 0x10 |
137 | #define TMP431_DEVICE_ID 0x31 | 138 | #define TMP431_DEVICE_ID 0x31 |
138 | #define TMP432_DEVICE_ID 0x32 | 139 | #define TMP432_DEVICE_ID 0x32 |
140 | #define TMP435_DEVICE_ID 0x35 | ||
139 | 141 | ||
140 | /* | 142 | /* |
141 | * Driver data (common to all clients) | 143 | * Driver data (common to all clients) |
@@ -146,6 +148,7 @@ static const struct i2c_device_id tmp401_id[] = { | |||
146 | { "tmp411", tmp411 }, | 148 | { "tmp411", tmp411 }, |
147 | { "tmp431", tmp431 }, | 149 | { "tmp431", tmp431 }, |
148 | { "tmp432", tmp432 }, | 150 | { "tmp432", tmp432 }, |
151 | { "tmp435", tmp435 }, | ||
149 | { } | 152 | { } |
150 | }; | 153 | }; |
151 | MODULE_DEVICE_TABLE(i2c, tmp401_id); | 154 | MODULE_DEVICE_TABLE(i2c, tmp401_id); |
@@ -613,10 +616,10 @@ static const struct attribute_group tmp432_group = { | |||
613 | * Begin non sysfs callback code (aka Real code) | 616 | * Begin non sysfs callback code (aka Real code) |
614 | */ | 617 | */ |
615 | 618 | ||
616 | static void tmp401_init_client(struct tmp401_data *data, | 619 | static int tmp401_init_client(struct tmp401_data *data, |
617 | struct i2c_client *client) | 620 | struct i2c_client *client) |
618 | { | 621 | { |
619 | int config, config_orig; | 622 | int config, config_orig, status = 0; |
620 | 623 | ||
621 | /* Set the conversion rate to 2 Hz */ | 624 | /* Set the conversion rate to 2 Hz */ |
622 | i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5); | 625 | i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5); |
@@ -624,16 +627,18 @@ static void tmp401_init_client(struct tmp401_data *data, | |||
624 | 627 | ||
625 | /* Start conversions (disable shutdown if necessary) */ | 628 | /* Start conversions (disable shutdown if necessary) */ |
626 | config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); | 629 | config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); |
627 | if (config < 0) { | 630 | if (config < 0) |
628 | dev_warn(&client->dev, "Initialization failed!\n"); | 631 | return config; |
629 | return; | ||
630 | } | ||
631 | 632 | ||
632 | config_orig = config; | 633 | config_orig = config; |
633 | config &= ~TMP401_CONFIG_SHUTDOWN; | 634 | config &= ~TMP401_CONFIG_SHUTDOWN; |
634 | 635 | ||
635 | if (config != config_orig) | 636 | if (config != config_orig) |
636 | i2c_smbus_write_byte_data(client, TMP401_CONFIG_WRITE, config); | 637 | status = i2c_smbus_write_byte_data(client, |
638 | TMP401_CONFIG_WRITE, | ||
639 | config); | ||
640 | |||
641 | return status; | ||
637 | } | 642 | } |
638 | 643 | ||
639 | static int tmp401_detect(struct i2c_client *client, | 644 | static int tmp401_detect(struct i2c_client *client, |
@@ -675,15 +680,18 @@ static int tmp401_detect(struct i2c_client *client, | |||
675 | kind = tmp411; | 680 | kind = tmp411; |
676 | break; | 681 | break; |
677 | case TMP431_DEVICE_ID: | 682 | case TMP431_DEVICE_ID: |
678 | if (client->addr == 0x4e) | 683 | if (client->addr != 0x4c && client->addr != 0x4d) |
679 | return -ENODEV; | 684 | return -ENODEV; |
680 | kind = tmp431; | 685 | kind = tmp431; |
681 | break; | 686 | break; |
682 | case TMP432_DEVICE_ID: | 687 | case TMP432_DEVICE_ID: |
683 | if (client->addr == 0x4e) | 688 | if (client->addr != 0x4c && client->addr != 0x4d) |
684 | return -ENODEV; | 689 | return -ENODEV; |
685 | kind = tmp432; | 690 | kind = tmp432; |
686 | break; | 691 | break; |
692 | case TMP435_DEVICE_ID: | ||
693 | kind = tmp435; | ||
694 | break; | ||
687 | default: | 695 | default: |
688 | return -ENODEV; | 696 | return -ENODEV; |
689 | } | 697 | } |
@@ -705,11 +713,13 @@ static int tmp401_detect(struct i2c_client *client, | |||
705 | static int tmp401_probe(struct i2c_client *client, | 713 | static int tmp401_probe(struct i2c_client *client, |
706 | const struct i2c_device_id *id) | 714 | const struct i2c_device_id *id) |
707 | { | 715 | { |
708 | const char *names[] = { "TMP401", "TMP411", "TMP431", "TMP432" }; | 716 | static const char * const names[] = { |
717 | "TMP401", "TMP411", "TMP431", "TMP432", "TMP435" | ||
718 | }; | ||
709 | struct device *dev = &client->dev; | 719 | struct device *dev = &client->dev; |
710 | struct device *hwmon_dev; | 720 | struct device *hwmon_dev; |
711 | struct tmp401_data *data; | 721 | struct tmp401_data *data; |
712 | int groups = 0; | 722 | int groups = 0, status; |
713 | 723 | ||
714 | data = devm_kzalloc(dev, sizeof(struct tmp401_data), GFP_KERNEL); | 724 | data = devm_kzalloc(dev, sizeof(struct tmp401_data), GFP_KERNEL); |
715 | if (!data) | 725 | if (!data) |
@@ -720,7 +730,9 @@ static int tmp401_probe(struct i2c_client *client, | |||
720 | data->kind = id->driver_data; | 730 | data->kind = id->driver_data; |
721 | 731 | ||
722 | /* Initialize the TMP401 chip */ | 732 | /* Initialize the TMP401 chip */ |
723 | tmp401_init_client(data, client); | 733 | status = tmp401_init_client(data, client); |
734 | if (status < 0) | ||
735 | return status; | ||
724 | 736 | ||
725 | /* Register sysfs hooks */ | 737 | /* Register sysfs hooks */ |
726 | data->groups[groups++] = &tmp401_group; | 738 | data->groups[groups++] = &tmp401_group; |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 917c3585f45b..b4d135cc2f39 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -881,6 +881,16 @@ config I2C_DIOLAN_U2C | |||
881 | This driver can also be built as a module. If so, the module | 881 | This driver can also be built as a module. If so, the module |
882 | will be called i2c-diolan-u2c. | 882 | will be called i2c-diolan-u2c. |
883 | 883 | ||
884 | config I2C_DLN2 | ||
885 | tristate "Diolan DLN-2 USB I2C adapter" | ||
886 | depends on MFD_DLN2 | ||
887 | help | ||
888 | If you say yes to this option, support will be included for Diolan | ||
889 | DLN2, a USB to I2C interface. | ||
890 | |||
891 | This driver can also be built as a module. If so, the module | ||
892 | will be called i2c-dln2. | ||
893 | |||
884 | config I2C_PARPORT | 894 | config I2C_PARPORT |
885 | tristate "Parallel port adapter" | 895 | tristate "Parallel port adapter" |
886 | depends on PARPORT | 896 | depends on PARPORT |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 78d56c54ba2b..cdac7f15eab5 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
@@ -87,6 +87,7 @@ obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o | |||
87 | 87 | ||
88 | # External I2C/SMBus adapter drivers | 88 | # External I2C/SMBus adapter drivers |
89 | obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o | 89 | obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o |
90 | obj-$(CONFIG_I2C_DLN2) += i2c-dln2.o | ||
90 | obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o | 91 | obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o |
91 | obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o | 92 | obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o |
92 | obj-$(CONFIG_I2C_ROBOTFUZZ_OSIF) += i2c-robotfuzz-osif.o | 93 | obj-$(CONFIG_I2C_ROBOTFUZZ_OSIF) += i2c-robotfuzz-osif.o |
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 63f3f03ecc9b..c604f4c3ac0d 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c | |||
@@ -111,6 +111,8 @@ | |||
111 | #define CDNS_I2C_DIVA_MAX 4 | 111 | #define CDNS_I2C_DIVA_MAX 4 |
112 | #define CDNS_I2C_DIVB_MAX 64 | 112 | #define CDNS_I2C_DIVB_MAX 64 |
113 | 113 | ||
114 | #define CDNS_I2C_TIMEOUT_MAX 0xFF | ||
115 | |||
114 | #define cdns_i2c_readreg(offset) readl_relaxed(id->membase + offset) | 116 | #define cdns_i2c_readreg(offset) readl_relaxed(id->membase + offset) |
115 | #define cdns_i2c_writereg(val, offset) writel_relaxed(val, id->membase + offset) | 117 | #define cdns_i2c_writereg(val, offset) writel_relaxed(val, id->membase + offset) |
116 | 118 | ||
@@ -852,6 +854,15 @@ static int cdns_i2c_probe(struct platform_device *pdev) | |||
852 | goto err_clk_dis; | 854 | goto err_clk_dis; |
853 | } | 855 | } |
854 | 856 | ||
857 | /* | ||
858 | * Cadence I2C controller has a bug wherein it generates | ||
859 | * invalid read transaction after HW timeout in master receiver mode. | ||
860 | * HW timeout is not used by this driver and the interrupt is disabled. | ||
861 | * But the feature itself cannot be disabled. Hence maximum value | ||
862 | * is written to this register to reduce the chances of error. | ||
863 | */ | ||
864 | cdns_i2c_writereg(CDNS_I2C_TIMEOUT_MAX, CDNS_I2C_TIME_OUT_OFFSET); | ||
865 | |||
855 | dev_info(&pdev->dev, "%u kHz mmio %08lx irq %d\n", | 866 | dev_info(&pdev->dev, "%u kHz mmio %08lx irq %d\n", |
856 | id->i2c_clk / 1000, (unsigned long)r_mem->start, id->irq); | 867 | id->i2c_clk / 1000, (unsigned long)r_mem->start, id->irq); |
857 | 868 | ||
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index d15b7c9b9219..01f0cd87a4a5 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -407,11 +407,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) | |||
407 | if (dev->cmd_err & DAVINCI_I2C_STR_NACK) { | 407 | if (dev->cmd_err & DAVINCI_I2C_STR_NACK) { |
408 | if (msg->flags & I2C_M_IGNORE_NAK) | 408 | if (msg->flags & I2C_M_IGNORE_NAK) |
409 | return msg->len; | 409 | return msg->len; |
410 | if (stop) { | 410 | w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); |
411 | w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); | 411 | w |= DAVINCI_I2C_MDR_STP; |
412 | w |= DAVINCI_I2C_MDR_STP; | 412 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); |
413 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); | ||
414 | } | ||
415 | return -EREMOTEIO; | 413 | return -EREMOTEIO; |
416 | } | 414 | } |
417 | return -EIO; | 415 | return -EIO; |
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index edca99dbba23..23628b7bfb8d 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c | |||
@@ -359,7 +359,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev) | |||
359 | } | 359 | } |
360 | 360 | ||
361 | /* Configure Tx/Rx FIFO threshold levels */ | 361 | /* Configure Tx/Rx FIFO threshold levels */ |
362 | dw_writel(dev, dev->tx_fifo_depth - 1, DW_IC_TX_TL); | 362 | dw_writel(dev, dev->tx_fifo_depth / 2, DW_IC_TX_TL); |
363 | dw_writel(dev, 0, DW_IC_RX_TL); | 363 | dw_writel(dev, 0, DW_IC_RX_TL); |
364 | 364 | ||
365 | /* configure the i2c master */ | 365 | /* configure the i2c master */ |
diff --git a/drivers/i2c/busses/i2c-dln2.c b/drivers/i2c/busses/i2c-dln2.c new file mode 100644 index 000000000000..b3fb86af4cbb --- /dev/null +++ b/drivers/i2c/busses/i2c-dln2.c | |||
@@ -0,0 +1,262 @@ | |||
1 | /* | ||
2 | * Driver for the Diolan DLN-2 USB-I2C adapter | ||
3 | * | ||
4 | * Copyright (c) 2014 Intel Corporation | ||
5 | * | ||
6 | * Derived from: | ||
7 | * i2c-diolan-u2c.c | ||
8 | * Copyright (c) 2010-2011 Ericsson AB | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License as | ||
12 | * published by the Free Software Foundation, version 2. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/mfd/dln2.h> | ||
22 | |||
23 | #define DLN2_I2C_MODULE_ID 0x03 | ||
24 | #define DLN2_I2C_CMD(cmd) DLN2_CMD(cmd, DLN2_I2C_MODULE_ID) | ||
25 | |||
26 | /* I2C commands */ | ||
27 | #define DLN2_I2C_GET_PORT_COUNT DLN2_I2C_CMD(0x00) | ||
28 | #define DLN2_I2C_ENABLE DLN2_I2C_CMD(0x01) | ||
29 | #define DLN2_I2C_DISABLE DLN2_I2C_CMD(0x02) | ||
30 | #define DLN2_I2C_IS_ENABLED DLN2_I2C_CMD(0x03) | ||
31 | #define DLN2_I2C_WRITE DLN2_I2C_CMD(0x06) | ||
32 | #define DLN2_I2C_READ DLN2_I2C_CMD(0x07) | ||
33 | #define DLN2_I2C_SCAN_DEVICES DLN2_I2C_CMD(0x08) | ||
34 | #define DLN2_I2C_PULLUP_ENABLE DLN2_I2C_CMD(0x09) | ||
35 | #define DLN2_I2C_PULLUP_DISABLE DLN2_I2C_CMD(0x0A) | ||
36 | #define DLN2_I2C_PULLUP_IS_ENABLED DLN2_I2C_CMD(0x0B) | ||
37 | #define DLN2_I2C_TRANSFER DLN2_I2C_CMD(0x0C) | ||
38 | #define DLN2_I2C_SET_MAX_REPLY_COUNT DLN2_I2C_CMD(0x0D) | ||
39 | #define DLN2_I2C_GET_MAX_REPLY_COUNT DLN2_I2C_CMD(0x0E) | ||
40 | |||
41 | #define DLN2_I2C_MAX_XFER_SIZE 256 | ||
42 | #define DLN2_I2C_BUF_SIZE (DLN2_I2C_MAX_XFER_SIZE + 16) | ||
43 | |||
44 | struct dln2_i2c { | ||
45 | struct platform_device *pdev; | ||
46 | struct i2c_adapter adapter; | ||
47 | u8 port; | ||
48 | /* | ||
49 | * Buffer to hold the packet for read or write transfers. One is enough | ||
50 | * since we can't have multiple transfers in parallel on the i2c bus. | ||
51 | */ | ||
52 | void *buf; | ||
53 | }; | ||
54 | |||
55 | static int dln2_i2c_enable(struct dln2_i2c *dln2, bool enable) | ||
56 | { | ||
57 | u16 cmd; | ||
58 | struct { | ||
59 | u8 port; | ||
60 | } tx; | ||
61 | |||
62 | tx.port = dln2->port; | ||
63 | |||
64 | if (enable) | ||
65 | cmd = DLN2_I2C_ENABLE; | ||
66 | else | ||
67 | cmd = DLN2_I2C_DISABLE; | ||
68 | |||
69 | return dln2_transfer_tx(dln2->pdev, cmd, &tx, sizeof(tx)); | ||
70 | } | ||
71 | |||
72 | static int dln2_i2c_write(struct dln2_i2c *dln2, u8 addr, | ||
73 | u8 *data, u16 data_len) | ||
74 | { | ||
75 | int ret; | ||
76 | struct { | ||
77 | u8 port; | ||
78 | u8 addr; | ||
79 | u8 mem_addr_len; | ||
80 | __le32 mem_addr; | ||
81 | __le16 buf_len; | ||
82 | u8 buf[DLN2_I2C_MAX_XFER_SIZE]; | ||
83 | } __packed *tx = dln2->buf; | ||
84 | unsigned len; | ||
85 | |||
86 | BUILD_BUG_ON(sizeof(*tx) > DLN2_I2C_BUF_SIZE); | ||
87 | |||
88 | tx->port = dln2->port; | ||
89 | tx->addr = addr; | ||
90 | tx->mem_addr_len = 0; | ||
91 | tx->mem_addr = 0; | ||
92 | tx->buf_len = cpu_to_le16(data_len); | ||
93 | memcpy(tx->buf, data, data_len); | ||
94 | |||
95 | len = sizeof(*tx) + data_len - DLN2_I2C_MAX_XFER_SIZE; | ||
96 | ret = dln2_transfer_tx(dln2->pdev, DLN2_I2C_WRITE, tx, len); | ||
97 | if (ret < 0) | ||
98 | return ret; | ||
99 | |||
100 | return data_len; | ||
101 | } | ||
102 | |||
103 | static int dln2_i2c_read(struct dln2_i2c *dln2, u16 addr, u8 *data, | ||
104 | u16 data_len) | ||
105 | { | ||
106 | int ret; | ||
107 | struct { | ||
108 | u8 port; | ||
109 | u8 addr; | ||
110 | u8 mem_addr_len; | ||
111 | __le32 mem_addr; | ||
112 | __le16 buf_len; | ||
113 | } __packed tx; | ||
114 | struct { | ||
115 | __le16 buf_len; | ||
116 | u8 buf[DLN2_I2C_MAX_XFER_SIZE]; | ||
117 | } __packed *rx = dln2->buf; | ||
118 | unsigned rx_len = sizeof(*rx); | ||
119 | |||
120 | BUILD_BUG_ON(sizeof(*rx) > DLN2_I2C_BUF_SIZE); | ||
121 | |||
122 | tx.port = dln2->port; | ||
123 | tx.addr = addr; | ||
124 | tx.mem_addr_len = 0; | ||
125 | tx.mem_addr = 0; | ||
126 | tx.buf_len = cpu_to_le16(data_len); | ||
127 | |||
128 | ret = dln2_transfer(dln2->pdev, DLN2_I2C_READ, &tx, sizeof(tx), | ||
129 | rx, &rx_len); | ||
130 | if (ret < 0) | ||
131 | return ret; | ||
132 | if (rx_len < sizeof(rx->buf_len) + data_len) | ||
133 | return -EPROTO; | ||
134 | if (le16_to_cpu(rx->buf_len) != data_len) | ||
135 | return -EPROTO; | ||
136 | |||
137 | memcpy(data, rx->buf, data_len); | ||
138 | |||
139 | return data_len; | ||
140 | } | ||
141 | |||
142 | static int dln2_i2c_xfer(struct i2c_adapter *adapter, | ||
143 | struct i2c_msg *msgs, int num) | ||
144 | { | ||
145 | struct dln2_i2c *dln2 = i2c_get_adapdata(adapter); | ||
146 | struct i2c_msg *pmsg; | ||
147 | struct device *dev = &dln2->adapter.dev; | ||
148 | int i; | ||
149 | |||
150 | for (i = 0; i < num; i++) { | ||
151 | int ret; | ||
152 | |||
153 | pmsg = &msgs[i]; | ||
154 | |||
155 | if (pmsg->len > DLN2_I2C_MAX_XFER_SIZE) { | ||
156 | dev_warn(dev, "maximum transfer size exceeded\n"); | ||
157 | return -EOPNOTSUPP; | ||
158 | } | ||
159 | |||
160 | if (pmsg->flags & I2C_M_RD) { | ||
161 | ret = dln2_i2c_read(dln2, pmsg->addr, pmsg->buf, | ||
162 | pmsg->len); | ||
163 | if (ret < 0) | ||
164 | return ret; | ||
165 | |||
166 | pmsg->len = ret; | ||
167 | } else { | ||
168 | ret = dln2_i2c_write(dln2, pmsg->addr, pmsg->buf, | ||
169 | pmsg->len); | ||
170 | if (ret != pmsg->len) | ||
171 | return -EPROTO; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | return num; | ||
176 | } | ||
177 | |||
178 | static u32 dln2_i2c_func(struct i2c_adapter *a) | ||
179 | { | ||
180 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | | ||
181 | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | | ||
182 | I2C_FUNC_SMBUS_I2C_BLOCK; | ||
183 | } | ||
184 | |||
185 | static const struct i2c_algorithm dln2_i2c_usb_algorithm = { | ||
186 | .master_xfer = dln2_i2c_xfer, | ||
187 | .functionality = dln2_i2c_func, | ||
188 | }; | ||
189 | |||
190 | static int dln2_i2c_probe(struct platform_device *pdev) | ||
191 | { | ||
192 | int ret; | ||
193 | struct dln2_i2c *dln2; | ||
194 | struct device *dev = &pdev->dev; | ||
195 | struct dln2_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
196 | |||
197 | dln2 = devm_kzalloc(dev, sizeof(*dln2), GFP_KERNEL); | ||
198 | if (!dln2) | ||
199 | return -ENOMEM; | ||
200 | |||
201 | dln2->buf = devm_kmalloc(dev, DLN2_I2C_BUF_SIZE, GFP_KERNEL); | ||
202 | if (!dln2->buf) | ||
203 | return -ENOMEM; | ||
204 | |||
205 | dln2->pdev = pdev; | ||
206 | dln2->port = pdata->port; | ||
207 | |||
208 | /* setup i2c adapter description */ | ||
209 | dln2->adapter.owner = THIS_MODULE; | ||
210 | dln2->adapter.class = I2C_CLASS_HWMON; | ||
211 | dln2->adapter.algo = &dln2_i2c_usb_algorithm; | ||
212 | dln2->adapter.dev.parent = dev; | ||
213 | i2c_set_adapdata(&dln2->adapter, dln2); | ||
214 | snprintf(dln2->adapter.name, sizeof(dln2->adapter.name), "%s-%s-%d", | ||
215 | "dln2-i2c", dev_name(pdev->dev.parent), dln2->port); | ||
216 | |||
217 | platform_set_drvdata(pdev, dln2); | ||
218 | |||
219 | /* initialize the i2c interface */ | ||
220 | ret = dln2_i2c_enable(dln2, true); | ||
221 | if (ret < 0) { | ||
222 | dev_err(dev, "failed to initialize adapter: %d\n", ret); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | /* and finally attach to i2c layer */ | ||
227 | ret = i2c_add_adapter(&dln2->adapter); | ||
228 | if (ret < 0) { | ||
229 | dev_err(dev, "failed to add I2C adapter: %d\n", ret); | ||
230 | goto out_disable; | ||
231 | } | ||
232 | |||
233 | return 0; | ||
234 | |||
235 | out_disable: | ||
236 | dln2_i2c_enable(dln2, false); | ||
237 | |||
238 | return ret; | ||
239 | } | ||
240 | |||
241 | static int dln2_i2c_remove(struct platform_device *pdev) | ||
242 | { | ||
243 | struct dln2_i2c *dln2 = platform_get_drvdata(pdev); | ||
244 | |||
245 | i2c_del_adapter(&dln2->adapter); | ||
246 | dln2_i2c_enable(dln2, false); | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static struct platform_driver dln2_i2c_driver = { | ||
252 | .driver.name = "dln2-i2c", | ||
253 | .probe = dln2_i2c_probe, | ||
254 | .remove = dln2_i2c_remove, | ||
255 | }; | ||
256 | |||
257 | module_platform_driver(dln2_i2c_driver); | ||
258 | |||
259 | MODULE_AUTHOR("Laurentiu Palcu <laurentiu.palcu@intel.com>"); | ||
260 | MODULE_DESCRIPTION("Driver for the Diolan DLN2 I2C master interface"); | ||
261 | MODULE_LICENSE("GPL v2"); | ||
262 | MODULE_ALIAS("platform:dln2-i2c"); | ||
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 26942c159de1..277a2288d4a8 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -922,14 +922,12 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) | |||
922 | if (stat & OMAP_I2C_STAT_NACK) { | 922 | if (stat & OMAP_I2C_STAT_NACK) { |
923 | err |= OMAP_I2C_STAT_NACK; | 923 | err |= OMAP_I2C_STAT_NACK; |
924 | omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); | 924 | omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); |
925 | break; | ||
926 | } | 925 | } |
927 | 926 | ||
928 | if (stat & OMAP_I2C_STAT_AL) { | 927 | if (stat & OMAP_I2C_STAT_AL) { |
929 | dev_err(dev->dev, "Arbitration lost\n"); | 928 | dev_err(dev->dev, "Arbitration lost\n"); |
930 | err |= OMAP_I2C_STAT_AL; | 929 | err |= OMAP_I2C_STAT_AL; |
931 | omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL); | 930 | omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL); |
932 | break; | ||
933 | } | 931 | } |
934 | 932 | ||
935 | /* | 933 | /* |
@@ -954,11 +952,13 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) | |||
954 | if (dev->fifo_size) | 952 | if (dev->fifo_size) |
955 | num_bytes = dev->buf_len; | 953 | num_bytes = dev->buf_len; |
956 | 954 | ||
957 | omap_i2c_receive_data(dev, num_bytes, true); | 955 | if (dev->errata & I2C_OMAP_ERRATA_I207) { |
958 | |||
959 | if (dev->errata & I2C_OMAP_ERRATA_I207) | ||
960 | i2c_omap_errata_i207(dev, stat); | 956 | i2c_omap_errata_i207(dev, stat); |
957 | num_bytes = (omap_i2c_read_reg(dev, | ||
958 | OMAP_I2C_BUFSTAT_REG) >> 8) & 0x3F; | ||
959 | } | ||
961 | 960 | ||
961 | omap_i2c_receive_data(dev, num_bytes, true); | ||
962 | omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR); | 962 | omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR); |
963 | continue; | 963 | continue; |
964 | } | 964 | } |
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 88bdc8f612e2..bc4e787096e8 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
@@ -127,6 +127,14 @@ config AT91_ADC | |||
127 | help | 127 | help |
128 | Say yes here to build support for Atmel AT91 ADC. | 128 | Say yes here to build support for Atmel AT91 ADC. |
129 | 129 | ||
130 | config AXP288_ADC | ||
131 | tristate "X-Powers AXP288 ADC driver" | ||
132 | depends on MFD_AXP20X | ||
133 | help | ||
134 | Say yes here to have support for X-Powers power management IC (PMIC) ADC | ||
135 | device. Depending on platform configuration, this general purpose ADC can | ||
136 | be used for sampling sensors such as thermal resistors. | ||
137 | |||
130 | config EXYNOS_ADC | 138 | config EXYNOS_ADC |
131 | tristate "Exynos ADC driver support" | 139 | tristate "Exynos ADC driver support" |
132 | depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST) | 140 | depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST) |
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index cb88a6a23b8f..f30093f5b67a 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_AD7793) += ad7793.o | |||
14 | obj-$(CONFIG_AD7887) += ad7887.o | 14 | obj-$(CONFIG_AD7887) += ad7887.o |
15 | obj-$(CONFIG_AD799X) += ad799x.o | 15 | obj-$(CONFIG_AD799X) += ad799x.o |
16 | obj-$(CONFIG_AT91_ADC) += at91_adc.o | 16 | obj-$(CONFIG_AT91_ADC) += at91_adc.o |
17 | obj-$(CONFIG_AXP288_ADC) += axp288_adc.o | ||
17 | obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o | 18 | obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o |
18 | obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o | 19 | obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o |
19 | obj-$(CONFIG_MAX1027) += max1027.o | 20 | obj-$(CONFIG_MAX1027) += max1027.o |
diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c new file mode 100644 index 000000000000..08bcfb061ca5 --- /dev/null +++ b/drivers/iio/adc/axp288_adc.c | |||
@@ -0,0 +1,261 @@ | |||
1 | /* | ||
2 | * axp288_adc.c - X-Powers AXP288 PMIC ADC Driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Intel Corporation | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <linux/mfd/axp20x.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | |||
26 | #include <linux/iio/iio.h> | ||
27 | #include <linux/iio/machine.h> | ||
28 | #include <linux/iio/driver.h> | ||
29 | |||
30 | #define AXP288_ADC_EN_MASK 0xF1 | ||
31 | #define AXP288_ADC_TS_PIN_GPADC 0xF2 | ||
32 | #define AXP288_ADC_TS_PIN_ON 0xF3 | ||
33 | |||
34 | enum axp288_adc_id { | ||
35 | AXP288_ADC_TS, | ||
36 | AXP288_ADC_PMIC, | ||
37 | AXP288_ADC_GP, | ||
38 | AXP288_ADC_BATT_CHRG_I, | ||
39 | AXP288_ADC_BATT_DISCHRG_I, | ||
40 | AXP288_ADC_BATT_V, | ||
41 | AXP288_ADC_NR_CHAN, | ||
42 | }; | ||
43 | |||
44 | struct axp288_adc_info { | ||
45 | int irq; | ||
46 | struct regmap *regmap; | ||
47 | }; | ||
48 | |||
49 | static const struct iio_chan_spec const axp288_adc_channels[] = { | ||
50 | { | ||
51 | .indexed = 1, | ||
52 | .type = IIO_TEMP, | ||
53 | .channel = 0, | ||
54 | .address = AXP288_TS_ADC_H, | ||
55 | .datasheet_name = "TS_PIN", | ||
56 | }, { | ||
57 | .indexed = 1, | ||
58 | .type = IIO_TEMP, | ||
59 | .channel = 1, | ||
60 | .address = AXP288_PMIC_ADC_H, | ||
61 | .datasheet_name = "PMIC_TEMP", | ||
62 | }, { | ||
63 | .indexed = 1, | ||
64 | .type = IIO_TEMP, | ||
65 | .channel = 2, | ||
66 | .address = AXP288_GP_ADC_H, | ||
67 | .datasheet_name = "GPADC", | ||
68 | }, { | ||
69 | .indexed = 1, | ||
70 | .type = IIO_CURRENT, | ||
71 | .channel = 3, | ||
72 | .address = AXP20X_BATT_CHRG_I_H, | ||
73 | .datasheet_name = "BATT_CHG_I", | ||
74 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), | ||
75 | }, { | ||
76 | .indexed = 1, | ||
77 | .type = IIO_CURRENT, | ||
78 | .channel = 4, | ||
79 | .address = AXP20X_BATT_DISCHRG_I_H, | ||
80 | .datasheet_name = "BATT_DISCHRG_I", | ||
81 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), | ||
82 | }, { | ||
83 | .indexed = 1, | ||
84 | .type = IIO_VOLTAGE, | ||
85 | .channel = 5, | ||
86 | .address = AXP20X_BATT_V_H, | ||
87 | .datasheet_name = "BATT_V", | ||
88 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), | ||
89 | }, | ||
90 | }; | ||
91 | |||
92 | #define AXP288_ADC_MAP(_adc_channel_label, _consumer_dev_name, \ | ||
93 | _consumer_channel) \ | ||
94 | { \ | ||
95 | .adc_channel_label = _adc_channel_label, \ | ||
96 | .consumer_dev_name = _consumer_dev_name, \ | ||
97 | .consumer_channel = _consumer_channel, \ | ||
98 | } | ||
99 | |||
100 | /* for consumer drivers */ | ||
101 | static struct iio_map axp288_adc_default_maps[] = { | ||
102 | AXP288_ADC_MAP("TS_PIN", "axp288-batt", "axp288-batt-temp"), | ||
103 | AXP288_ADC_MAP("PMIC_TEMP", "axp288-pmic", "axp288-pmic-temp"), | ||
104 | AXP288_ADC_MAP("GPADC", "axp288-gpadc", "axp288-system-temp"), | ||
105 | AXP288_ADC_MAP("BATT_CHG_I", "axp288-chrg", "axp288-chrg-curr"), | ||
106 | AXP288_ADC_MAP("BATT_DISCHRG_I", "axp288-chrg", "axp288-chrg-d-curr"), | ||
107 | AXP288_ADC_MAP("BATT_V", "axp288-batt", "axp288-batt-volt"), | ||
108 | {}, | ||
109 | }; | ||
110 | |||
111 | static int axp288_adc_read_channel(int *val, unsigned long address, | ||
112 | struct regmap *regmap) | ||
113 | { | ||
114 | u8 buf[2]; | ||
115 | |||
116 | if (regmap_bulk_read(regmap, address, buf, 2)) | ||
117 | return -EIO; | ||
118 | *val = (buf[0] << 4) + ((buf[1] >> 4) & 0x0F); | ||
119 | |||
120 | return IIO_VAL_INT; | ||
121 | } | ||
122 | |||
123 | static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode, | ||
124 | unsigned long address) | ||
125 | { | ||
126 | /* channels other than GPADC do not need to switch TS pin */ | ||
127 | if (address != AXP288_GP_ADC_H) | ||
128 | return 0; | ||
129 | |||
130 | return regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode); | ||
131 | } | ||
132 | |||
133 | static int axp288_adc_read_raw(struct iio_dev *indio_dev, | ||
134 | struct iio_chan_spec const *chan, | ||
135 | int *val, int *val2, long mask) | ||
136 | { | ||
137 | int ret; | ||
138 | struct axp288_adc_info *info = iio_priv(indio_dev); | ||
139 | |||
140 | mutex_lock(&indio_dev->mlock); | ||
141 | switch (mask) { | ||
142 | case IIO_CHAN_INFO_RAW: | ||
143 | if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC, | ||
144 | chan->address)) { | ||
145 | dev_err(&indio_dev->dev, "GPADC mode\n"); | ||
146 | ret = -EINVAL; | ||
147 | break; | ||
148 | } | ||
149 | ret = axp288_adc_read_channel(val, chan->address, info->regmap); | ||
150 | if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON, | ||
151 | chan->address)) | ||
152 | dev_err(&indio_dev->dev, "TS pin restore\n"); | ||
153 | break; | ||
154 | case IIO_CHAN_INFO_PROCESSED: | ||
155 | ret = axp288_adc_read_channel(val, chan->address, info->regmap); | ||
156 | break; | ||
157 | default: | ||
158 | ret = -EINVAL; | ||
159 | } | ||
160 | mutex_unlock(&indio_dev->mlock); | ||
161 | |||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | static int axp288_adc_set_state(struct regmap *regmap) | ||
166 | { | ||
167 | /* ADC should be always enabled for internal FG to function */ | ||
168 | if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON)) | ||
169 | return -EIO; | ||
170 | |||
171 | return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK); | ||
172 | } | ||
173 | |||
174 | static const struct iio_info axp288_adc_iio_info = { | ||
175 | .read_raw = &axp288_adc_read_raw, | ||
176 | .driver_module = THIS_MODULE, | ||
177 | }; | ||
178 | |||
179 | static int axp288_adc_probe(struct platform_device *pdev) | ||
180 | { | ||
181 | int ret; | ||
182 | struct axp288_adc_info *info; | ||
183 | struct iio_dev *indio_dev; | ||
184 | struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); | ||
185 | |||
186 | indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); | ||
187 | if (!indio_dev) | ||
188 | return -ENOMEM; | ||
189 | |||
190 | info = iio_priv(indio_dev); | ||
191 | info->irq = platform_get_irq(pdev, 0); | ||
192 | if (info->irq < 0) { | ||
193 | dev_err(&pdev->dev, "no irq resource?\n"); | ||
194 | return info->irq; | ||
195 | } | ||
196 | platform_set_drvdata(pdev, indio_dev); | ||
197 | info->regmap = axp20x->regmap; | ||
198 | /* | ||
199 | * Set ADC to enabled state at all time, including system suspend. | ||
200 | * otherwise internal fuel gauge functionality may be affected. | ||
201 | */ | ||
202 | ret = axp288_adc_set_state(axp20x->regmap); | ||
203 | if (ret) { | ||
204 | dev_err(&pdev->dev, "unable to enable ADC device\n"); | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | indio_dev->dev.parent = &pdev->dev; | ||
209 | indio_dev->name = pdev->name; | ||
210 | indio_dev->channels = axp288_adc_channels; | ||
211 | indio_dev->num_channels = ARRAY_SIZE(axp288_adc_channels); | ||
212 | indio_dev->info = &axp288_adc_iio_info; | ||
213 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
214 | ret = iio_map_array_register(indio_dev, axp288_adc_default_maps); | ||
215 | if (ret < 0) | ||
216 | return ret; | ||
217 | |||
218 | ret = iio_device_register(indio_dev); | ||
219 | if (ret < 0) { | ||
220 | dev_err(&pdev->dev, "unable to register iio device\n"); | ||
221 | goto err_array_unregister; | ||
222 | } | ||
223 | return 0; | ||
224 | |||
225 | err_array_unregister: | ||
226 | iio_map_array_unregister(indio_dev); | ||
227 | |||
228 | return ret; | ||
229 | } | ||
230 | |||
231 | static int axp288_adc_remove(struct platform_device *pdev) | ||
232 | { | ||
233 | struct iio_dev *indio_dev = platform_get_drvdata(pdev); | ||
234 | |||
235 | iio_device_unregister(indio_dev); | ||
236 | iio_map_array_unregister(indio_dev); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static struct platform_device_id axp288_adc_id_table[] = { | ||
242 | { .name = "axp288_adc" }, | ||
243 | {}, | ||
244 | }; | ||
245 | |||
246 | static struct platform_driver axp288_adc_driver = { | ||
247 | .probe = axp288_adc_probe, | ||
248 | .remove = axp288_adc_remove, | ||
249 | .id_table = axp288_adc_id_table, | ||
250 | .driver = { | ||
251 | .name = "axp288_adc", | ||
252 | }, | ||
253 | }; | ||
254 | |||
255 | MODULE_DEVICE_TABLE(platform, axp288_adc_id_table); | ||
256 | |||
257 | module_platform_driver(axp288_adc_driver); | ||
258 | |||
259 | MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@linux.intel.com>"); | ||
260 | MODULE_DESCRIPTION("X-Powers AXP288 ADC Driver"); | ||
261 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index bc203485716d..8afa28e4570e 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -421,7 +421,7 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
421 | 421 | ||
422 | err_free_client: | 422 | err_free_client: |
423 | evdev_detach_client(evdev, client); | 423 | evdev_detach_client(evdev, client); |
424 | kfree(client); | 424 | kvfree(client); |
425 | return error; | 425 | return error; |
426 | } | 426 | } |
427 | 427 | ||
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 932ed9be9ff3..b10aaeda2bb4 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c | |||
@@ -2190,7 +2190,7 @@ static int smiapp_set_selection(struct v4l2_subdev *subdev, | |||
2190 | ret = smiapp_set_compose(subdev, fh, sel); | 2190 | ret = smiapp_set_compose(subdev, fh, sel); |
2191 | break; | 2191 | break; |
2192 | default: | 2192 | default: |
2193 | BUG(); | 2193 | ret = -EINVAL; |
2194 | } | 2194 | } |
2195 | 2195 | ||
2196 | mutex_unlock(&sensor->mutex); | 2196 | mutex_unlock(&sensor->mutex); |
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 331eddac7222..3bd386c371f7 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c | |||
@@ -1078,7 +1078,7 @@ static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, | |||
1078 | for (line = 0; line < lines; line++) { | 1078 | for (line = 0; line < lines; line++) { |
1079 | while (offset && offset >= sg_dma_len(sg)) { | 1079 | while (offset && offset >= sg_dma_len(sg)) { |
1080 | offset -= sg_dma_len(sg); | 1080 | offset -= sg_dma_len(sg); |
1081 | sg++; | 1081 | sg = sg_next(sg); |
1082 | } | 1082 | } |
1083 | 1083 | ||
1084 | if (lpi && line > 0 && !(line % lpi)) | 1084 | if (lpi && line > 0 && !(line % lpi)) |
@@ -1101,14 +1101,14 @@ static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, | |||
1101 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 1101 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
1102 | todo -= (sg_dma_len(sg)-offset); | 1102 | todo -= (sg_dma_len(sg)-offset); |
1103 | offset = 0; | 1103 | offset = 0; |
1104 | sg++; | 1104 | sg = sg_next(sg); |
1105 | while (todo > sg_dma_len(sg)) { | 1105 | while (todo > sg_dma_len(sg)) { |
1106 | *(rp++) = cpu_to_le32(RISC_WRITE| | 1106 | *(rp++) = cpu_to_le32(RISC_WRITE| |
1107 | sg_dma_len(sg)); | 1107 | sg_dma_len(sg)); |
1108 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); | 1108 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); |
1109 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | 1109 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ |
1110 | todo -= sg_dma_len(sg); | 1110 | todo -= sg_dma_len(sg); |
1111 | sg++; | 1111 | sg = sg_next(sg); |
1112 | } | 1112 | } |
1113 | *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo); | 1113 | *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo); |
1114 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); | 1114 | *(rp++) = cpu_to_le32(sg_dma_address(sg)); |
diff --git a/drivers/media/pci/solo6x10/solo6x10-core.c b/drivers/media/pci/solo6x10/solo6x10-core.c index 172583d736fe..8cbe6b49f4c2 100644 --- a/drivers/media/pci/solo6x10/solo6x10-core.c +++ b/drivers/media/pci/solo6x10/solo6x10-core.c | |||
@@ -105,11 +105,8 @@ static irqreturn_t solo_isr(int irq, void *data) | |||
105 | if (!status) | 105 | if (!status) |
106 | return IRQ_NONE; | 106 | return IRQ_NONE; |
107 | 107 | ||
108 | if (status & ~solo_dev->irq_mask) { | 108 | /* Acknowledge all interrupts immediately */ |
109 | solo_reg_write(solo_dev, SOLO_IRQ_STAT, | 109 | solo_reg_write(solo_dev, SOLO_IRQ_STAT, status); |
110 | status & ~solo_dev->irq_mask); | ||
111 | status &= solo_dev->irq_mask; | ||
112 | } | ||
113 | 110 | ||
114 | if (status & SOLO_IRQ_PCI_ERR) | 111 | if (status & SOLO_IRQ_PCI_ERR) |
115 | solo_p2m_error_isr(solo_dev); | 112 | solo_p2m_error_isr(solo_dev); |
@@ -132,9 +129,6 @@ static irqreturn_t solo_isr(int irq, void *data) | |||
132 | if (status & SOLO_IRQ_G723) | 129 | if (status & SOLO_IRQ_G723) |
133 | solo_g723_isr(solo_dev); | 130 | solo_g723_isr(solo_dev); |
134 | 131 | ||
135 | /* Clear all interrupts handled */ | ||
136 | solo_reg_write(solo_dev, SOLO_IRQ_STAT, status); | ||
137 | |||
138 | return IRQ_HANDLED; | 132 | return IRQ_HANDLED; |
139 | } | 133 | } |
140 | 134 | ||
diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index f1f098e22f7e..d16bc67af732 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c | |||
@@ -259,8 +259,8 @@ again: | |||
259 | case 32: | 259 | case 32: |
260 | if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { | 260 | if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { |
261 | protocol = RC_TYPE_RC6_MCE; | 261 | protocol = RC_TYPE_RC6_MCE; |
262 | scancode &= ~RC6_6A_MCE_TOGGLE_MASK; | ||
263 | toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK); | 262 | toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK); |
263 | scancode &= ~RC6_6A_MCE_TOGGLE_MASK; | ||
264 | } else { | 264 | } else { |
265 | protocol = RC_BIT_RC6_6A_32; | 265 | protocol = RC_BIT_RC6_6A_32; |
266 | toggle = 0; | 266 | toggle = 0; |
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index ccc00099b261..1c0dbf428a3a 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c | |||
@@ -632,7 +632,7 @@ static void s2255_fillbuff(struct s2255_vc *vc, | |||
632 | break; | 632 | break; |
633 | case V4L2_PIX_FMT_JPEG: | 633 | case V4L2_PIX_FMT_JPEG: |
634 | case V4L2_PIX_FMT_MJPEG: | 634 | case V4L2_PIX_FMT_MJPEG: |
635 | buf->vb.v4l2_buf.length = jpgsize; | 635 | vb2_set_plane_payload(&buf->vb, 0, jpgsize); |
636 | memcpy(vbuf, tmpbuf, jpgsize); | 636 | memcpy(vbuf, tmpbuf, jpgsize); |
637 | break; | 637 | break; |
638 | case V4L2_PIX_FMT_YUV422P: | 638 | case V4L2_PIX_FMT_YUV422P: |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 1456ea70bbc7..2e6b7311fabc 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -59,6 +59,17 @@ config MFD_AAT2870_CORE | |||
59 | additional drivers must be enabled in order to use the | 59 | additional drivers must be enabled in order to use the |
60 | functionality of the device. | 60 | functionality of the device. |
61 | 61 | ||
62 | config MFD_ATMEL_HLCDC | ||
63 | tristate "Atmel HLCDC (High-end LCD Controller)" | ||
64 | select MFD_CORE | ||
65 | select REGMAP_MMIO | ||
66 | depends on OF | ||
67 | help | ||
68 | If you say yes here you get support for the HLCDC block. | ||
69 | This driver provides common support for accessing the device, | ||
70 | additional drivers must be enabled in order to use the | ||
71 | functionality of the device. | ||
72 | |||
62 | config MFD_BCM590XX | 73 | config MFD_BCM590XX |
63 | tristate "Broadcom BCM590xx PMUs" | 74 | tristate "Broadcom BCM590xx PMUs" |
64 | select MFD_CORE | 75 | select MFD_CORE |
@@ -74,7 +85,8 @@ config MFD_AXP20X | |||
74 | select REGMAP_IRQ | 85 | select REGMAP_IRQ |
75 | depends on I2C=y | 86 | depends on I2C=y |
76 | help | 87 | help |
77 | If you say Y here you get support for the X-Powers AXP202 and AXP209. | 88 | If you say Y here you get support for the X-Powers AXP202, AXP209 and |
89 | AXP288 power management IC (PMIC). | ||
78 | This driver include only the core APIs. You have to select individual | 90 | This driver include only the core APIs. You have to select individual |
79 | components like regulators or the PEK (Power Enable Key) under the | 91 | components like regulators or the PEK (Power Enable Key) under the |
80 | corresponding menus. | 92 | corresponding menus. |
@@ -183,6 +195,16 @@ config MFD_DA9063 | |||
183 | Additional drivers must be enabled in order to use the functionality | 195 | Additional drivers must be enabled in order to use the functionality |
184 | of the device. | 196 | of the device. |
185 | 197 | ||
198 | config MFD_DLN2 | ||
199 | tristate "Diolan DLN2 support" | ||
200 | select MFD_CORE | ||
201 | depends on USB | ||
202 | help | ||
203 | This adds support for Diolan USB-I2C/SPI/GPIO Master Adapter | ||
204 | DLN-2. Additional drivers such as I2C_DLN2, GPIO_DLN2, | ||
205 | etc. must be enabled in order to use the functionality of | ||
206 | the device. | ||
207 | |||
186 | config MFD_MC13XXX | 208 | config MFD_MC13XXX |
187 | tristate | 209 | tristate |
188 | depends on (SPI_MASTER || I2C) | 210 | depends on (SPI_MASTER || I2C) |
@@ -655,7 +677,6 @@ config MFD_SEC_CORE | |||
655 | select MFD_CORE | 677 | select MFD_CORE |
656 | select REGMAP_I2C | 678 | select REGMAP_I2C |
657 | select REGMAP_IRQ | 679 | select REGMAP_IRQ |
658 | select REGULATOR | ||
659 | help | 680 | help |
660 | Support for the Samsung Electronics MFD series. | 681 | Support for the Samsung Electronics MFD series. |
661 | This driver provides common support for accessing the device, | 682 | This driver provides common support for accessing the device, |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 8bd54b1253af..53467e211381 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -13,7 +13,7 @@ obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o | |||
13 | obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o | 13 | obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o |
14 | obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o | 14 | obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o |
15 | 15 | ||
16 | rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o | 16 | rtsx_pci-objs := rtsx_pcr.o rtsx_gops.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o |
17 | obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o | 17 | obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o |
18 | obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o | 18 | obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o |
19 | 19 | ||
@@ -157,6 +157,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o | |||
157 | obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o | 157 | obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o |
158 | obj-$(CONFIG_MFD_TPS65090) += tps65090.o | 158 | obj-$(CONFIG_MFD_TPS65090) += tps65090.o |
159 | obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o | 159 | obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o |
160 | obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o | ||
160 | obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o | 161 | obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o |
161 | obj-$(CONFIG_MFD_PALMAS) += palmas.o | 162 | obj-$(CONFIG_MFD_PALMAS) += palmas.o |
162 | obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o | 163 | obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o |
@@ -174,6 +175,7 @@ obj-$(CONFIG_MFD_STW481X) += stw481x.o | |||
174 | obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o | 175 | obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o |
175 | obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o | 176 | obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o |
176 | obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o | 177 | obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o |
178 | obj-$(CONFIG_MFD_DLN2) += dln2.o | ||
177 | 179 | ||
178 | intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o | 180 | intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o |
179 | obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o | 181 | obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o |
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index 8e0dae59844d..94dbcdd2a1ff 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c | |||
@@ -85,63 +85,6 @@ shutdown: | |||
85 | } | 85 | } |
86 | } | 86 | } |
87 | 87 | ||
88 | /* | ||
89 | * Use the AB WD to reset the platform. It will perform a hard | ||
90 | * reset instead of a soft reset. Write the reset reason to | ||
91 | * the AB before reset, which can be read upon restart. | ||
92 | */ | ||
93 | void ab8500_restart(char mode, const char *cmd) | ||
94 | { | ||
95 | struct ab8500_platform_data *plat; | ||
96 | struct ab8500_sysctrl_platform_data *pdata; | ||
97 | u16 reason = 0; | ||
98 | u8 val; | ||
99 | |||
100 | if (sysctrl_dev == NULL) { | ||
101 | pr_err("%s: sysctrl not initialized\n", __func__); | ||
102 | return; | ||
103 | } | ||
104 | |||
105 | plat = dev_get_platdata(sysctrl_dev->parent); | ||
106 | pdata = plat->sysctrl; | ||
107 | if (pdata && pdata->reboot_reason_code) | ||
108 | reason = pdata->reboot_reason_code(cmd); | ||
109 | else | ||
110 | pr_warn("[%s] No reboot reason set. Default reason %d\n", | ||
111 | __func__, reason); | ||
112 | |||
113 | /* | ||
114 | * Disable RTC alarm, just a precaution so that no alarm | ||
115 | * is running when WD reset is executed. | ||
116 | */ | ||
117 | abx500_get_register_interruptible(sysctrl_dev, AB8500_RTC, | ||
118 | RTC_CTRL , &val); | ||
119 | abx500_set_register_interruptible(sysctrl_dev, AB8500_RTC, | ||
120 | RTC_CTRL , (val & ~RTC_ALARM_ENABLE)); | ||
121 | |||
122 | /* | ||
123 | * Android is not using the RTC alarm registers during reboot | ||
124 | * so we borrow them for writing the reason of reset | ||
125 | */ | ||
126 | |||
127 | /* reason[8 LSB] */ | ||
128 | val = reason & 0xFF; | ||
129 | abx500_set_register_interruptible(sysctrl_dev, AB8500_RTC, | ||
130 | AB8500_ALARM_MIN_LOW , val); | ||
131 | |||
132 | /* reason[8 MSB] */ | ||
133 | val = (reason>>8) & 0xFF; | ||
134 | abx500_set_register_interruptible(sysctrl_dev, AB8500_RTC, | ||
135 | AB8500_ALARM_MIN_MID , val); | ||
136 | |||
137 | /* Setting WD timeout to 0 */ | ||
138 | ab8500_sysctrl_write(AB8500_MAINWDOGTIMER, 0xFF, 0x0); | ||
139 | |||
140 | /* Setting the parameters to AB8500 WD*/ | ||
141 | ab8500_sysctrl_write(AB8500_MAINWDOGCTRL, 0xFF, (AB8500_ENABLE_WD | | ||
142 | AB8500_WD_RESTART_ON_EXPIRE | AB8500_KICK_WD)); | ||
143 | } | ||
144 | |||
145 | static inline bool valid_bank(u8 bank) | 88 | static inline bool valid_bank(u8 bank) |
146 | { | 89 | { |
147 | return ((bank == AB8500_SYS_CTRL1_BLOCK) || | 90 | return ((bank == AB8500_SYS_CTRL1_BLOCK) || |
diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c index 5145d78bf07e..8ef58bcff193 100644 --- a/drivers/mfd/arizona-spi.c +++ b/drivers/mfd/arizona-spi.c | |||
@@ -75,7 +75,9 @@ static int arizona_spi_probe(struct spi_device *spi) | |||
75 | static int arizona_spi_remove(struct spi_device *spi) | 75 | static int arizona_spi_remove(struct spi_device *spi) |
76 | { | 76 | { |
77 | struct arizona *arizona = spi_get_drvdata(spi); | 77 | struct arizona *arizona = spi_get_drvdata(spi); |
78 | |||
78 | arizona_dev_exit(arizona); | 79 | arizona_dev_exit(arizona); |
80 | |||
79 | return 0; | 81 | return 0; |
80 | } | 82 | } |
81 | 83 | ||
diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c new file mode 100644 index 000000000000..cfd58f4cc5c3 --- /dev/null +++ b/drivers/mfd/atmel-hlcdc.c | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Free Electrons | ||
3 | * Copyright (C) 2014 Atmel | ||
4 | * | ||
5 | * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
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 with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/clk.h> | ||
21 | #include <linux/mfd/atmel-hlcdc.h> | ||
22 | #include <linux/mfd/core.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/regmap.h> | ||
26 | |||
27 | #define ATMEL_HLCDC_REG_MAX (0x4000 - 0x4) | ||
28 | |||
29 | static const struct mfd_cell atmel_hlcdc_cells[] = { | ||
30 | { | ||
31 | .name = "atmel-hlcdc-pwm", | ||
32 | .of_compatible = "atmel,hlcdc-pwm", | ||
33 | }, | ||
34 | { | ||
35 | .name = "atmel-hlcdc-dc", | ||
36 | .of_compatible = "atmel,hlcdc-display-controller", | ||
37 | }, | ||
38 | }; | ||
39 | |||
40 | static const struct regmap_config atmel_hlcdc_regmap_config = { | ||
41 | .reg_bits = 32, | ||
42 | .val_bits = 32, | ||
43 | .reg_stride = 4, | ||
44 | .max_register = ATMEL_HLCDC_REG_MAX, | ||
45 | }; | ||
46 | |||
47 | static int atmel_hlcdc_probe(struct platform_device *pdev) | ||
48 | { | ||
49 | struct device *dev = &pdev->dev; | ||
50 | struct atmel_hlcdc *hlcdc; | ||
51 | struct resource *res; | ||
52 | void __iomem *regs; | ||
53 | |||
54 | hlcdc = devm_kzalloc(dev, sizeof(*hlcdc), GFP_KERNEL); | ||
55 | if (!hlcdc) | ||
56 | return -ENOMEM; | ||
57 | |||
58 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
59 | regs = devm_ioremap_resource(dev, res); | ||
60 | if (IS_ERR(regs)) | ||
61 | return PTR_ERR(regs); | ||
62 | |||
63 | hlcdc->irq = platform_get_irq(pdev, 0); | ||
64 | if (hlcdc->irq < 0) | ||
65 | return hlcdc->irq; | ||
66 | |||
67 | hlcdc->periph_clk = devm_clk_get(dev, "periph_clk"); | ||
68 | if (IS_ERR(hlcdc->periph_clk)) { | ||
69 | dev_err(dev, "failed to get peripheral clock\n"); | ||
70 | return PTR_ERR(hlcdc->periph_clk); | ||
71 | } | ||
72 | |||
73 | hlcdc->sys_clk = devm_clk_get(dev, "sys_clk"); | ||
74 | if (IS_ERR(hlcdc->sys_clk)) { | ||
75 | dev_err(dev, "failed to get system clock\n"); | ||
76 | return PTR_ERR(hlcdc->sys_clk); | ||
77 | } | ||
78 | |||
79 | hlcdc->slow_clk = devm_clk_get(dev, "slow_clk"); | ||
80 | if (IS_ERR(hlcdc->slow_clk)) { | ||
81 | dev_err(dev, "failed to get slow clock\n"); | ||
82 | return PTR_ERR(hlcdc->slow_clk); | ||
83 | } | ||
84 | |||
85 | hlcdc->regmap = devm_regmap_init_mmio(dev, regs, | ||
86 | &atmel_hlcdc_regmap_config); | ||
87 | if (IS_ERR(hlcdc->regmap)) | ||
88 | return PTR_ERR(hlcdc->regmap); | ||
89 | |||
90 | dev_set_drvdata(dev, hlcdc); | ||
91 | |||
92 | return mfd_add_devices(dev, -1, atmel_hlcdc_cells, | ||
93 | ARRAY_SIZE(atmel_hlcdc_cells), | ||
94 | NULL, 0, NULL); | ||
95 | } | ||
96 | |||
97 | static int atmel_hlcdc_remove(struct platform_device *pdev) | ||
98 | { | ||
99 | mfd_remove_devices(&pdev->dev); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static const struct of_device_id atmel_hlcdc_match[] = { | ||
105 | { .compatible = "atmel,sama5d3-hlcdc" }, | ||
106 | { /* sentinel */ }, | ||
107 | }; | ||
108 | |||
109 | static struct platform_driver atmel_hlcdc_driver = { | ||
110 | .probe = atmel_hlcdc_probe, | ||
111 | .remove = atmel_hlcdc_remove, | ||
112 | .driver = { | ||
113 | .name = "atmel-hlcdc", | ||
114 | .of_match_table = atmel_hlcdc_match, | ||
115 | }, | ||
116 | }; | ||
117 | module_platform_driver(atmel_hlcdc_driver); | ||
118 | |||
119 | MODULE_ALIAS("platform:atmel-hlcdc"); | ||
120 | MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>"); | ||
121 | MODULE_DESCRIPTION("Atmel HLCDC driver"); | ||
122 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 6231adbb295d..c522ee22b1c0 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * axp20x.c - MFD core driver for the X-Powers AXP202 and AXP209 | 2 | * axp20x.c - MFD core driver for the X-Powers' Power Management ICs |
3 | * | 3 | * |
4 | * AXP20x comprises an adaptive USB-Compatible PWM charger, 2 BUCK DC-DC | 4 | * AXP20x typically comprises an adaptive USB-Compatible PWM charger, BUCK DC-DC |
5 | * converters, 5 LDOs, multiple 12-bit ADCs of voltage, current and temperature | 5 | * converters, LDOs, multiple 12-bit ADCs of voltage, current and temperature |
6 | * as well as 4 configurable GPIOs. | 6 | * as well as configurable GPIOs. |
7 | * | 7 | * |
8 | * Author: Carlo Caione <carlo@caione.org> | 8 | * Author: Carlo Caione <carlo@caione.org> |
9 | * | 9 | * |
@@ -25,9 +25,16 @@ | |||
25 | #include <linux/mfd/core.h> | 25 | #include <linux/mfd/core.h> |
26 | #include <linux/of_device.h> | 26 | #include <linux/of_device.h> |
27 | #include <linux/of_irq.h> | 27 | #include <linux/of_irq.h> |
28 | #include <linux/acpi.h> | ||
28 | 29 | ||
29 | #define AXP20X_OFF 0x80 | 30 | #define AXP20X_OFF 0x80 |
30 | 31 | ||
32 | static const char const *axp20x_model_names[] = { | ||
33 | "AXP202", | ||
34 | "AXP209", | ||
35 | "AXP288", | ||
36 | }; | ||
37 | |||
31 | static const struct regmap_range axp20x_writeable_ranges[] = { | 38 | static const struct regmap_range axp20x_writeable_ranges[] = { |
32 | regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), | 39 | regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), |
33 | regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES), | 40 | regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES), |
@@ -47,6 +54,25 @@ static const struct regmap_access_table axp20x_volatile_table = { | |||
47 | .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges), | 54 | .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges), |
48 | }; | 55 | }; |
49 | 56 | ||
57 | static const struct regmap_range axp288_writeable_ranges[] = { | ||
58 | regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE), | ||
59 | regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5), | ||
60 | }; | ||
61 | |||
62 | static const struct regmap_range axp288_volatile_ranges[] = { | ||
63 | regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L), | ||
64 | }; | ||
65 | |||
66 | static const struct regmap_access_table axp288_writeable_table = { | ||
67 | .yes_ranges = axp288_writeable_ranges, | ||
68 | .n_yes_ranges = ARRAY_SIZE(axp288_writeable_ranges), | ||
69 | }; | ||
70 | |||
71 | static const struct regmap_access_table axp288_volatile_table = { | ||
72 | .yes_ranges = axp288_volatile_ranges, | ||
73 | .n_yes_ranges = ARRAY_SIZE(axp288_volatile_ranges), | ||
74 | }; | ||
75 | |||
50 | static struct resource axp20x_pek_resources[] = { | 76 | static struct resource axp20x_pek_resources[] = { |
51 | { | 77 | { |
52 | .name = "PEK_DBR", | 78 | .name = "PEK_DBR", |
@@ -61,6 +87,39 @@ static struct resource axp20x_pek_resources[] = { | |||
61 | }, | 87 | }, |
62 | }; | 88 | }; |
63 | 89 | ||
90 | static struct resource axp288_battery_resources[] = { | ||
91 | { | ||
92 | .start = AXP288_IRQ_QWBTU, | ||
93 | .end = AXP288_IRQ_QWBTU, | ||
94 | .flags = IORESOURCE_IRQ, | ||
95 | }, | ||
96 | { | ||
97 | .start = AXP288_IRQ_WBTU, | ||
98 | .end = AXP288_IRQ_WBTU, | ||
99 | .flags = IORESOURCE_IRQ, | ||
100 | }, | ||
101 | { | ||
102 | .start = AXP288_IRQ_QWBTO, | ||
103 | .end = AXP288_IRQ_QWBTO, | ||
104 | .flags = IORESOURCE_IRQ, | ||
105 | }, | ||
106 | { | ||
107 | .start = AXP288_IRQ_WBTO, | ||
108 | .end = AXP288_IRQ_WBTO, | ||
109 | .flags = IORESOURCE_IRQ, | ||
110 | }, | ||
111 | { | ||
112 | .start = AXP288_IRQ_WL2, | ||
113 | .end = AXP288_IRQ_WL2, | ||
114 | .flags = IORESOURCE_IRQ, | ||
115 | }, | ||
116 | { | ||
117 | .start = AXP288_IRQ_WL1, | ||
118 | .end = AXP288_IRQ_WL1, | ||
119 | .flags = IORESOURCE_IRQ, | ||
120 | }, | ||
121 | }; | ||
122 | |||
64 | static const struct regmap_config axp20x_regmap_config = { | 123 | static const struct regmap_config axp20x_regmap_config = { |
65 | .reg_bits = 8, | 124 | .reg_bits = 8, |
66 | .val_bits = 8, | 125 | .val_bits = 8, |
@@ -70,47 +129,96 @@ static const struct regmap_config axp20x_regmap_config = { | |||
70 | .cache_type = REGCACHE_RBTREE, | 129 | .cache_type = REGCACHE_RBTREE, |
71 | }; | 130 | }; |
72 | 131 | ||
73 | #define AXP20X_IRQ(_irq, _off, _mask) \ | 132 | static const struct regmap_config axp288_regmap_config = { |
74 | [AXP20X_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) } | 133 | .reg_bits = 8, |
134 | .val_bits = 8, | ||
135 | .wr_table = &axp288_writeable_table, | ||
136 | .volatile_table = &axp288_volatile_table, | ||
137 | .max_register = AXP288_FG_TUNE5, | ||
138 | .cache_type = REGCACHE_RBTREE, | ||
139 | }; | ||
140 | |||
141 | #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \ | ||
142 | [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) } | ||
75 | 143 | ||
76 | static const struct regmap_irq axp20x_regmap_irqs[] = { | 144 | static const struct regmap_irq axp20x_regmap_irqs[] = { |
77 | AXP20X_IRQ(ACIN_OVER_V, 0, 7), | 145 | INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7), |
78 | AXP20X_IRQ(ACIN_PLUGIN, 0, 6), | 146 | INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN, 0, 6), |
79 | AXP20X_IRQ(ACIN_REMOVAL, 0, 5), | 147 | INIT_REGMAP_IRQ(AXP20X, ACIN_REMOVAL, 0, 5), |
80 | AXP20X_IRQ(VBUS_OVER_V, 0, 4), | 148 | INIT_REGMAP_IRQ(AXP20X, VBUS_OVER_V, 0, 4), |
81 | AXP20X_IRQ(VBUS_PLUGIN, 0, 3), | 149 | INIT_REGMAP_IRQ(AXP20X, VBUS_PLUGIN, 0, 3), |
82 | AXP20X_IRQ(VBUS_REMOVAL, 0, 2), | 150 | INIT_REGMAP_IRQ(AXP20X, VBUS_REMOVAL, 0, 2), |
83 | AXP20X_IRQ(VBUS_V_LOW, 0, 1), | 151 | INIT_REGMAP_IRQ(AXP20X, VBUS_V_LOW, 0, 1), |
84 | AXP20X_IRQ(BATT_PLUGIN, 1, 7), | 152 | INIT_REGMAP_IRQ(AXP20X, BATT_PLUGIN, 1, 7), |
85 | AXP20X_IRQ(BATT_REMOVAL, 1, 6), | 153 | INIT_REGMAP_IRQ(AXP20X, BATT_REMOVAL, 1, 6), |
86 | AXP20X_IRQ(BATT_ENT_ACT_MODE, 1, 5), | 154 | INIT_REGMAP_IRQ(AXP20X, BATT_ENT_ACT_MODE, 1, 5), |
87 | AXP20X_IRQ(BATT_EXIT_ACT_MODE, 1, 4), | 155 | INIT_REGMAP_IRQ(AXP20X, BATT_EXIT_ACT_MODE, 1, 4), |
88 | AXP20X_IRQ(CHARG, 1, 3), | 156 | INIT_REGMAP_IRQ(AXP20X, CHARG, 1, 3), |
89 | AXP20X_IRQ(CHARG_DONE, 1, 2), | 157 | INIT_REGMAP_IRQ(AXP20X, CHARG_DONE, 1, 2), |
90 | AXP20X_IRQ(BATT_TEMP_HIGH, 1, 1), | 158 | INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_HIGH, 1, 1), |
91 | AXP20X_IRQ(BATT_TEMP_LOW, 1, 0), | 159 | INIT_REGMAP_IRQ(AXP20X, BATT_TEMP_LOW, 1, 0), |
92 | AXP20X_IRQ(DIE_TEMP_HIGH, 2, 7), | 160 | INIT_REGMAP_IRQ(AXP20X, DIE_TEMP_HIGH, 2, 7), |
93 | AXP20X_IRQ(CHARG_I_LOW, 2, 6), | 161 | INIT_REGMAP_IRQ(AXP20X, CHARG_I_LOW, 2, 6), |
94 | AXP20X_IRQ(DCDC1_V_LONG, 2, 5), | 162 | INIT_REGMAP_IRQ(AXP20X, DCDC1_V_LONG, 2, 5), |
95 | AXP20X_IRQ(DCDC2_V_LONG, 2, 4), | 163 | INIT_REGMAP_IRQ(AXP20X, DCDC2_V_LONG, 2, 4), |
96 | AXP20X_IRQ(DCDC3_V_LONG, 2, 3), | 164 | INIT_REGMAP_IRQ(AXP20X, DCDC3_V_LONG, 2, 3), |
97 | AXP20X_IRQ(PEK_SHORT, 2, 1), | 165 | INIT_REGMAP_IRQ(AXP20X, PEK_SHORT, 2, 1), |
98 | AXP20X_IRQ(PEK_LONG, 2, 0), | 166 | INIT_REGMAP_IRQ(AXP20X, PEK_LONG, 2, 0), |
99 | AXP20X_IRQ(N_OE_PWR_ON, 3, 7), | 167 | INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_ON, 3, 7), |
100 | AXP20X_IRQ(N_OE_PWR_OFF, 3, 6), | 168 | INIT_REGMAP_IRQ(AXP20X, N_OE_PWR_OFF, 3, 6), |
101 | AXP20X_IRQ(VBUS_VALID, 3, 5), | 169 | INIT_REGMAP_IRQ(AXP20X, VBUS_VALID, 3, 5), |
102 | AXP20X_IRQ(VBUS_NOT_VALID, 3, 4), | 170 | INIT_REGMAP_IRQ(AXP20X, VBUS_NOT_VALID, 3, 4), |
103 | AXP20X_IRQ(VBUS_SESS_VALID, 3, 3), | 171 | INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_VALID, 3, 3), |
104 | AXP20X_IRQ(VBUS_SESS_END, 3, 2), | 172 | INIT_REGMAP_IRQ(AXP20X, VBUS_SESS_END, 3, 2), |
105 | AXP20X_IRQ(LOW_PWR_LVL1, 3, 1), | 173 | INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL1, 3, 1), |
106 | AXP20X_IRQ(LOW_PWR_LVL2, 3, 0), | 174 | INIT_REGMAP_IRQ(AXP20X, LOW_PWR_LVL2, 3, 0), |
107 | AXP20X_IRQ(TIMER, 4, 7), | 175 | INIT_REGMAP_IRQ(AXP20X, TIMER, 4, 7), |
108 | AXP20X_IRQ(PEK_RIS_EDGE, 4, 6), | 176 | INIT_REGMAP_IRQ(AXP20X, PEK_RIS_EDGE, 4, 6), |
109 | AXP20X_IRQ(PEK_FAL_EDGE, 4, 5), | 177 | INIT_REGMAP_IRQ(AXP20X, PEK_FAL_EDGE, 4, 5), |
110 | AXP20X_IRQ(GPIO3_INPUT, 4, 3), | 178 | INIT_REGMAP_IRQ(AXP20X, GPIO3_INPUT, 4, 3), |
111 | AXP20X_IRQ(GPIO2_INPUT, 4, 2), | 179 | INIT_REGMAP_IRQ(AXP20X, GPIO2_INPUT, 4, 2), |
112 | AXP20X_IRQ(GPIO1_INPUT, 4, 1), | 180 | INIT_REGMAP_IRQ(AXP20X, GPIO1_INPUT, 4, 1), |
113 | AXP20X_IRQ(GPIO0_INPUT, 4, 0), | 181 | INIT_REGMAP_IRQ(AXP20X, GPIO0_INPUT, 4, 0), |
182 | }; | ||
183 | |||
184 | /* some IRQs are compatible with axp20x models */ | ||
185 | static const struct regmap_irq axp288_regmap_irqs[] = { | ||
186 | INIT_REGMAP_IRQ(AXP288, VBUS_FALL, 0, 2), | ||
187 | INIT_REGMAP_IRQ(AXP288, VBUS_RISE, 0, 3), | ||
188 | INIT_REGMAP_IRQ(AXP288, OV, 0, 4), | ||
189 | |||
190 | INIT_REGMAP_IRQ(AXP288, DONE, 1, 2), | ||
191 | INIT_REGMAP_IRQ(AXP288, CHARGING, 1, 3), | ||
192 | INIT_REGMAP_IRQ(AXP288, SAFE_QUIT, 1, 4), | ||
193 | INIT_REGMAP_IRQ(AXP288, SAFE_ENTER, 1, 5), | ||
194 | INIT_REGMAP_IRQ(AXP288, ABSENT, 1, 6), | ||
195 | INIT_REGMAP_IRQ(AXP288, APPEND, 1, 7), | ||
196 | |||
197 | INIT_REGMAP_IRQ(AXP288, QWBTU, 2, 0), | ||
198 | INIT_REGMAP_IRQ(AXP288, WBTU, 2, 1), | ||
199 | INIT_REGMAP_IRQ(AXP288, QWBTO, 2, 2), | ||
200 | INIT_REGMAP_IRQ(AXP288, WBTO, 2, 3), | ||
201 | INIT_REGMAP_IRQ(AXP288, QCBTU, 2, 4), | ||
202 | INIT_REGMAP_IRQ(AXP288, CBTU, 2, 5), | ||
203 | INIT_REGMAP_IRQ(AXP288, QCBTO, 2, 6), | ||
204 | INIT_REGMAP_IRQ(AXP288, CBTO, 2, 7), | ||
205 | |||
206 | INIT_REGMAP_IRQ(AXP288, WL2, 3, 0), | ||
207 | INIT_REGMAP_IRQ(AXP288, WL1, 3, 1), | ||
208 | INIT_REGMAP_IRQ(AXP288, GPADC, 3, 2), | ||
209 | INIT_REGMAP_IRQ(AXP288, OT, 3, 7), | ||
210 | |||
211 | INIT_REGMAP_IRQ(AXP288, GPIO0, 4, 0), | ||
212 | INIT_REGMAP_IRQ(AXP288, GPIO1, 4, 1), | ||
213 | INIT_REGMAP_IRQ(AXP288, POKO, 4, 2), | ||
214 | INIT_REGMAP_IRQ(AXP288, POKL, 4, 3), | ||
215 | INIT_REGMAP_IRQ(AXP288, POKS, 4, 4), | ||
216 | INIT_REGMAP_IRQ(AXP288, POKN, 4, 5), | ||
217 | INIT_REGMAP_IRQ(AXP288, POKP, 4, 6), | ||
218 | INIT_REGMAP_IRQ(AXP288, TIMER, 4, 7), | ||
219 | |||
220 | INIT_REGMAP_IRQ(AXP288, MV_CHNG, 5, 0), | ||
221 | INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1), | ||
114 | }; | 222 | }; |
115 | 223 | ||
116 | static const struct of_device_id axp20x_of_match[] = { | 224 | static const struct of_device_id axp20x_of_match[] = { |
@@ -128,16 +236,39 @@ static const struct i2c_device_id axp20x_i2c_id[] = { | |||
128 | }; | 236 | }; |
129 | MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id); | 237 | MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id); |
130 | 238 | ||
239 | static const struct acpi_device_id axp20x_acpi_match[] = { | ||
240 | { | ||
241 | .id = "INT33F4", | ||
242 | .driver_data = AXP288_ID, | ||
243 | }, | ||
244 | { }, | ||
245 | }; | ||
246 | MODULE_DEVICE_TABLE(acpi, axp20x_acpi_match); | ||
247 | |||
131 | static const struct regmap_irq_chip axp20x_regmap_irq_chip = { | 248 | static const struct regmap_irq_chip axp20x_regmap_irq_chip = { |
132 | .name = "axp20x_irq_chip", | 249 | .name = "axp20x_irq_chip", |
133 | .status_base = AXP20X_IRQ1_STATE, | 250 | .status_base = AXP20X_IRQ1_STATE, |
134 | .ack_base = AXP20X_IRQ1_STATE, | 251 | .ack_base = AXP20X_IRQ1_STATE, |
135 | .mask_base = AXP20X_IRQ1_EN, | 252 | .mask_base = AXP20X_IRQ1_EN, |
136 | .num_regs = 5, | 253 | .mask_invert = true, |
254 | .init_ack_masked = true, | ||
137 | .irqs = axp20x_regmap_irqs, | 255 | .irqs = axp20x_regmap_irqs, |
138 | .num_irqs = ARRAY_SIZE(axp20x_regmap_irqs), | 256 | .num_irqs = ARRAY_SIZE(axp20x_regmap_irqs), |
257 | .num_regs = 5, | ||
258 | |||
259 | }; | ||
260 | |||
261 | static const struct regmap_irq_chip axp288_regmap_irq_chip = { | ||
262 | .name = "axp288_irq_chip", | ||
263 | .status_base = AXP20X_IRQ1_STATE, | ||
264 | .ack_base = AXP20X_IRQ1_STATE, | ||
265 | .mask_base = AXP20X_IRQ1_EN, | ||
139 | .mask_invert = true, | 266 | .mask_invert = true, |
140 | .init_ack_masked = true, | 267 | .init_ack_masked = true, |
268 | .irqs = axp288_regmap_irqs, | ||
269 | .num_irqs = ARRAY_SIZE(axp288_regmap_irqs), | ||
270 | .num_regs = 6, | ||
271 | |||
141 | }; | 272 | }; |
142 | 273 | ||
143 | static struct mfd_cell axp20x_cells[] = { | 274 | static struct mfd_cell axp20x_cells[] = { |
@@ -150,36 +281,155 @@ static struct mfd_cell axp20x_cells[] = { | |||
150 | }, | 281 | }, |
151 | }; | 282 | }; |
152 | 283 | ||
284 | static struct resource axp288_adc_resources[] = { | ||
285 | { | ||
286 | .name = "GPADC", | ||
287 | .start = AXP288_IRQ_GPADC, | ||
288 | .end = AXP288_IRQ_GPADC, | ||
289 | .flags = IORESOURCE_IRQ, | ||
290 | }, | ||
291 | }; | ||
292 | |||
293 | static struct resource axp288_charger_resources[] = { | ||
294 | { | ||
295 | .start = AXP288_IRQ_OV, | ||
296 | .end = AXP288_IRQ_OV, | ||
297 | .flags = IORESOURCE_IRQ, | ||
298 | }, | ||
299 | { | ||
300 | .start = AXP288_IRQ_DONE, | ||
301 | .end = AXP288_IRQ_DONE, | ||
302 | .flags = IORESOURCE_IRQ, | ||
303 | }, | ||
304 | { | ||
305 | .start = AXP288_IRQ_CHARGING, | ||
306 | .end = AXP288_IRQ_CHARGING, | ||
307 | .flags = IORESOURCE_IRQ, | ||
308 | }, | ||
309 | { | ||
310 | .start = AXP288_IRQ_SAFE_QUIT, | ||
311 | .end = AXP288_IRQ_SAFE_QUIT, | ||
312 | .flags = IORESOURCE_IRQ, | ||
313 | }, | ||
314 | { | ||
315 | .start = AXP288_IRQ_SAFE_ENTER, | ||
316 | .end = AXP288_IRQ_SAFE_ENTER, | ||
317 | .flags = IORESOURCE_IRQ, | ||
318 | }, | ||
319 | { | ||
320 | .start = AXP288_IRQ_QCBTU, | ||
321 | .end = AXP288_IRQ_QCBTU, | ||
322 | .flags = IORESOURCE_IRQ, | ||
323 | }, | ||
324 | { | ||
325 | .start = AXP288_IRQ_CBTU, | ||
326 | .end = AXP288_IRQ_CBTU, | ||
327 | .flags = IORESOURCE_IRQ, | ||
328 | }, | ||
329 | { | ||
330 | .start = AXP288_IRQ_QCBTO, | ||
331 | .end = AXP288_IRQ_QCBTO, | ||
332 | .flags = IORESOURCE_IRQ, | ||
333 | }, | ||
334 | { | ||
335 | .start = AXP288_IRQ_CBTO, | ||
336 | .end = AXP288_IRQ_CBTO, | ||
337 | .flags = IORESOURCE_IRQ, | ||
338 | }, | ||
339 | }; | ||
340 | |||
341 | static struct mfd_cell axp288_cells[] = { | ||
342 | { | ||
343 | .name = "axp288_adc", | ||
344 | .num_resources = ARRAY_SIZE(axp288_adc_resources), | ||
345 | .resources = axp288_adc_resources, | ||
346 | }, | ||
347 | { | ||
348 | .name = "axp288_charger", | ||
349 | .num_resources = ARRAY_SIZE(axp288_charger_resources), | ||
350 | .resources = axp288_charger_resources, | ||
351 | }, | ||
352 | { | ||
353 | .name = "axp288_battery", | ||
354 | .num_resources = ARRAY_SIZE(axp288_battery_resources), | ||
355 | .resources = axp288_battery_resources, | ||
356 | }, | ||
357 | }; | ||
358 | |||
153 | static struct axp20x_dev *axp20x_pm_power_off; | 359 | static struct axp20x_dev *axp20x_pm_power_off; |
154 | static void axp20x_power_off(void) | 360 | static void axp20x_power_off(void) |
155 | { | 361 | { |
362 | if (axp20x_pm_power_off->variant == AXP288_ID) | ||
363 | return; | ||
364 | |||
156 | regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL, | 365 | regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL, |
157 | AXP20X_OFF); | 366 | AXP20X_OFF); |
158 | } | 367 | } |
159 | 368 | ||
369 | static int axp20x_match_device(struct axp20x_dev *axp20x, struct device *dev) | ||
370 | { | ||
371 | const struct acpi_device_id *acpi_id; | ||
372 | const struct of_device_id *of_id; | ||
373 | |||
374 | if (dev->of_node) { | ||
375 | of_id = of_match_device(axp20x_of_match, dev); | ||
376 | if (!of_id) { | ||
377 | dev_err(dev, "Unable to match OF ID\n"); | ||
378 | return -ENODEV; | ||
379 | } | ||
380 | axp20x->variant = (long) of_id->data; | ||
381 | } else { | ||
382 | acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev); | ||
383 | if (!acpi_id || !acpi_id->driver_data) { | ||
384 | dev_err(dev, "Unable to match ACPI ID and data\n"); | ||
385 | return -ENODEV; | ||
386 | } | ||
387 | axp20x->variant = (long) acpi_id->driver_data; | ||
388 | } | ||
389 | |||
390 | switch (axp20x->variant) { | ||
391 | case AXP202_ID: | ||
392 | case AXP209_ID: | ||
393 | axp20x->nr_cells = ARRAY_SIZE(axp20x_cells); | ||
394 | axp20x->cells = axp20x_cells; | ||
395 | axp20x->regmap_cfg = &axp20x_regmap_config; | ||
396 | axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip; | ||
397 | break; | ||
398 | case AXP288_ID: | ||
399 | axp20x->cells = axp288_cells; | ||
400 | axp20x->nr_cells = ARRAY_SIZE(axp288_cells); | ||
401 | axp20x->regmap_cfg = &axp288_regmap_config; | ||
402 | axp20x->regmap_irq_chip = &axp288_regmap_irq_chip; | ||
403 | break; | ||
404 | default: | ||
405 | dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant); | ||
406 | return -EINVAL; | ||
407 | } | ||
408 | dev_info(dev, "AXP20x variant %s found\n", | ||
409 | axp20x_model_names[axp20x->variant]); | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
160 | static int axp20x_i2c_probe(struct i2c_client *i2c, | 414 | static int axp20x_i2c_probe(struct i2c_client *i2c, |
161 | const struct i2c_device_id *id) | 415 | const struct i2c_device_id *id) |
162 | { | 416 | { |
163 | struct axp20x_dev *axp20x; | 417 | struct axp20x_dev *axp20x; |
164 | const struct of_device_id *of_id; | ||
165 | int ret; | 418 | int ret; |
166 | 419 | ||
167 | axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL); | 420 | axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL); |
168 | if (!axp20x) | 421 | if (!axp20x) |
169 | return -ENOMEM; | 422 | return -ENOMEM; |
170 | 423 | ||
171 | of_id = of_match_device(axp20x_of_match, &i2c->dev); | 424 | ret = axp20x_match_device(axp20x, &i2c->dev); |
172 | if (!of_id) { | 425 | if (ret) |
173 | dev_err(&i2c->dev, "Unable to setup AXP20X data\n"); | 426 | return ret; |
174 | return -ENODEV; | ||
175 | } | ||
176 | axp20x->variant = (long) of_id->data; | ||
177 | 427 | ||
178 | axp20x->i2c_client = i2c; | 428 | axp20x->i2c_client = i2c; |
179 | axp20x->dev = &i2c->dev; | 429 | axp20x->dev = &i2c->dev; |
180 | dev_set_drvdata(axp20x->dev, axp20x); | 430 | dev_set_drvdata(axp20x->dev, axp20x); |
181 | 431 | ||
182 | axp20x->regmap = devm_regmap_init_i2c(i2c, &axp20x_regmap_config); | 432 | axp20x->regmap = devm_regmap_init_i2c(i2c, axp20x->regmap_cfg); |
183 | if (IS_ERR(axp20x->regmap)) { | 433 | if (IS_ERR(axp20x->regmap)) { |
184 | ret = PTR_ERR(axp20x->regmap); | 434 | ret = PTR_ERR(axp20x->regmap); |
185 | dev_err(&i2c->dev, "regmap init failed: %d\n", ret); | 435 | dev_err(&i2c->dev, "regmap init failed: %d\n", ret); |
@@ -188,15 +438,15 @@ static int axp20x_i2c_probe(struct i2c_client *i2c, | |||
188 | 438 | ||
189 | ret = regmap_add_irq_chip(axp20x->regmap, i2c->irq, | 439 | ret = regmap_add_irq_chip(axp20x->regmap, i2c->irq, |
190 | IRQF_ONESHOT | IRQF_SHARED, -1, | 440 | IRQF_ONESHOT | IRQF_SHARED, -1, |
191 | &axp20x_regmap_irq_chip, | 441 | axp20x->regmap_irq_chip, |
192 | &axp20x->regmap_irqc); | 442 | &axp20x->regmap_irqc); |
193 | if (ret) { | 443 | if (ret) { |
194 | dev_err(&i2c->dev, "failed to add irq chip: %d\n", ret); | 444 | dev_err(&i2c->dev, "failed to add irq chip: %d\n", ret); |
195 | return ret; | 445 | return ret; |
196 | } | 446 | } |
197 | 447 | ||
198 | ret = mfd_add_devices(axp20x->dev, -1, axp20x_cells, | 448 | ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells, |
199 | ARRAY_SIZE(axp20x_cells), NULL, 0, NULL); | 449 | axp20x->nr_cells, NULL, 0, NULL); |
200 | 450 | ||
201 | if (ret) { | 451 | if (ret) { |
202 | dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret); | 452 | dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret); |
@@ -234,6 +484,7 @@ static struct i2c_driver axp20x_i2c_driver = { | |||
234 | .name = "axp20x", | 484 | .name = "axp20x", |
235 | .owner = THIS_MODULE, | 485 | .owner = THIS_MODULE, |
236 | .of_match_table = of_match_ptr(axp20x_of_match), | 486 | .of_match_table = of_match_ptr(axp20x_of_match), |
487 | .acpi_match_table = ACPI_PTR(axp20x_acpi_match), | ||
237 | }, | 488 | }, |
238 | .probe = axp20x_i2c_probe, | 489 | .probe = axp20x_i2c_probe, |
239 | .remove = axp20x_i2c_remove, | 490 | .remove = axp20x_i2c_remove, |
diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c index 93db8bb8c8f0..f38bc98a3c57 100644 --- a/drivers/mfd/da9063-core.c +++ b/drivers/mfd/da9063-core.c | |||
@@ -118,7 +118,7 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq) | |||
118 | da9063->irq_base = pdata->irq_base; | 118 | da9063->irq_base = pdata->irq_base; |
119 | } else { | 119 | } else { |
120 | da9063->flags = 0; | 120 | da9063->flags = 0; |
121 | da9063->irq_base = 0; | 121 | da9063->irq_base = -1; |
122 | } | 122 | } |
123 | da9063->chip_irq = irq; | 123 | da9063->chip_irq = irq; |
124 | 124 | ||
@@ -168,6 +168,8 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq) | |||
168 | return ret; | 168 | return ret; |
169 | } | 169 | } |
170 | 170 | ||
171 | da9063->irq_base = regmap_irq_chip_get_base(da9063->regmap_irq); | ||
172 | |||
171 | ret = mfd_add_devices(da9063->dev, -1, da9063_devs, | 173 | ret = mfd_add_devices(da9063->dev, -1, da9063_devs, |
172 | ARRAY_SIZE(da9063_devs), NULL, da9063->irq_base, | 174 | ARRAY_SIZE(da9063_devs), NULL, da9063->irq_base, |
173 | NULL); | 175 | NULL); |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 193cf168ba84..a8204730f01c 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -3150,23 +3150,28 @@ static int db8500_prcmu_probe(struct platform_device *pdev) | |||
3150 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu"); | 3150 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu"); |
3151 | if (!res) { | 3151 | if (!res) { |
3152 | dev_err(&pdev->dev, "no prcmu memory region provided\n"); | 3152 | dev_err(&pdev->dev, "no prcmu memory region provided\n"); |
3153 | return -ENOENT; | 3153 | return -EINVAL; |
3154 | } | 3154 | } |
3155 | prcmu_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | 3155 | prcmu_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); |
3156 | if (!prcmu_base) { | 3156 | if (!prcmu_base) { |
3157 | dev_err(&pdev->dev, | 3157 | dev_err(&pdev->dev, |
3158 | "failed to ioremap prcmu register memory\n"); | 3158 | "failed to ioremap prcmu register memory\n"); |
3159 | return -ENOENT; | 3159 | return -ENOMEM; |
3160 | } | 3160 | } |
3161 | init_prcm_registers(); | 3161 | init_prcm_registers(); |
3162 | dbx500_fw_version_init(pdev, pdata->version_offset); | 3162 | dbx500_fw_version_init(pdev, pdata->version_offset); |
3163 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm"); | 3163 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm"); |
3164 | if (!res) { | 3164 | if (!res) { |
3165 | dev_err(&pdev->dev, "no prcmu tcdm region provided\n"); | 3165 | dev_err(&pdev->dev, "no prcmu tcdm region provided\n"); |
3166 | return -ENOENT; | 3166 | return -EINVAL; |
3167 | } | 3167 | } |
3168 | tcdm_base = devm_ioremap(&pdev->dev, res->start, | 3168 | tcdm_base = devm_ioremap(&pdev->dev, res->start, |
3169 | resource_size(res)); | 3169 | resource_size(res)); |
3170 | if (!tcdm_base) { | ||
3171 | dev_err(&pdev->dev, | ||
3172 | "failed to ioremap prcmu-tcdm register memory\n"); | ||
3173 | return -ENOMEM; | ||
3174 | } | ||
3170 | 3175 | ||
3171 | /* Clean up the mailbox interrupts after pre-kernel code. */ | 3176 | /* Clean up the mailbox interrupts after pre-kernel code. */ |
3172 | writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); | 3177 | writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); |
@@ -3174,15 +3179,14 @@ static int db8500_prcmu_probe(struct platform_device *pdev) | |||
3174 | irq = platform_get_irq(pdev, 0); | 3179 | irq = platform_get_irq(pdev, 0); |
3175 | if (irq <= 0) { | 3180 | if (irq <= 0) { |
3176 | dev_err(&pdev->dev, "no prcmu irq provided\n"); | 3181 | dev_err(&pdev->dev, "no prcmu irq provided\n"); |
3177 | return -ENOENT; | 3182 | return irq; |
3178 | } | 3183 | } |
3179 | 3184 | ||
3180 | err = request_threaded_irq(irq, prcmu_irq_handler, | 3185 | err = request_threaded_irq(irq, prcmu_irq_handler, |
3181 | prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); | 3186 | prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); |
3182 | if (err < 0) { | 3187 | if (err < 0) { |
3183 | pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n"); | 3188 | pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n"); |
3184 | err = -EBUSY; | 3189 | return err; |
3185 | goto no_irq_return; | ||
3186 | } | 3190 | } |
3187 | 3191 | ||
3188 | db8500_irq_init(np); | 3192 | db8500_irq_init(np); |
@@ -3206,7 +3210,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev) | |||
3206 | if (err) { | 3210 | if (err) { |
3207 | mfd_remove_devices(&pdev->dev); | 3211 | mfd_remove_devices(&pdev->dev); |
3208 | pr_err("prcmu: Failed to add subdevices\n"); | 3212 | pr_err("prcmu: Failed to add subdevices\n"); |
3209 | goto no_irq_return; | 3213 | return err; |
3210 | } | 3214 | } |
3211 | } | 3215 | } |
3212 | 3216 | ||
@@ -3214,12 +3218,10 @@ static int db8500_prcmu_probe(struct platform_device *pdev) | |||
3214 | if (err) { | 3218 | if (err) { |
3215 | mfd_remove_devices(&pdev->dev); | 3219 | mfd_remove_devices(&pdev->dev); |
3216 | pr_err("prcmu: Failed to add ab8500 subdevice\n"); | 3220 | pr_err("prcmu: Failed to add ab8500 subdevice\n"); |
3217 | goto no_irq_return; | 3221 | return err; |
3218 | } | 3222 | } |
3219 | 3223 | ||
3220 | pr_info("DB8500 PRCMU initialized\n"); | 3224 | pr_info("DB8500 PRCMU initialized\n"); |
3221 | |||
3222 | no_irq_return: | ||
3223 | return err; | 3225 | return err; |
3224 | } | 3226 | } |
3225 | static const struct of_device_id db8500_prcmu_match[] = { | 3227 | static const struct of_device_id db8500_prcmu_match[] = { |
diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c new file mode 100644 index 000000000000..6d49685d4ee4 --- /dev/null +++ b/drivers/mfd/dln2.c | |||
@@ -0,0 +1,781 @@ | |||
1 | /* | ||
2 | * Driver for the Diolan DLN-2 USB adapter | ||
3 | * | ||
4 | * Copyright (c) 2014 Intel Corporation | ||
5 | * | ||
6 | * Derived from: | ||
7 | * i2c-diolan-u2c.c | ||
8 | * Copyright (c) 2010-2011 Ericsson AB | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License as | ||
12 | * published by the Free Software Foundation, version 2. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/usb.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/mfd/core.h> | ||
24 | #include <linux/mfd/dln2.h> | ||
25 | #include <linux/rculist.h> | ||
26 | |||
27 | struct dln2_header { | ||
28 | __le16 size; | ||
29 | __le16 id; | ||
30 | __le16 echo; | ||
31 | __le16 handle; | ||
32 | }; | ||
33 | |||
34 | struct dln2_response { | ||
35 | struct dln2_header hdr; | ||
36 | __le16 result; | ||
37 | }; | ||
38 | |||
39 | #define DLN2_GENERIC_MODULE_ID 0x00 | ||
40 | #define DLN2_GENERIC_CMD(cmd) DLN2_CMD(cmd, DLN2_GENERIC_MODULE_ID) | ||
41 | #define CMD_GET_DEVICE_VER DLN2_GENERIC_CMD(0x30) | ||
42 | #define CMD_GET_DEVICE_SN DLN2_GENERIC_CMD(0x31) | ||
43 | |||
44 | #define DLN2_HW_ID 0x200 | ||
45 | #define DLN2_USB_TIMEOUT 200 /* in ms */ | ||
46 | #define DLN2_MAX_RX_SLOTS 16 | ||
47 | #define DLN2_MAX_URBS 16 | ||
48 | #define DLN2_RX_BUF_SIZE 512 | ||
49 | |||
50 | enum dln2_handle { | ||
51 | DLN2_HANDLE_EVENT = 0, /* don't change, hardware defined */ | ||
52 | DLN2_HANDLE_CTRL, | ||
53 | DLN2_HANDLE_GPIO, | ||
54 | DLN2_HANDLE_I2C, | ||
55 | DLN2_HANDLE_SPI, | ||
56 | DLN2_HANDLES | ||
57 | }; | ||
58 | |||
59 | /* | ||
60 | * Receive context used between the receive demultiplexer and the transfer | ||
61 | * routine. While sending a request the transfer routine will look for a free | ||
62 | * receive context and use it to wait for a response and to receive the URB and | ||
63 | * thus the response data. | ||
64 | */ | ||
65 | struct dln2_rx_context { | ||
66 | /* completion used to wait for a response */ | ||
67 | struct completion done; | ||
68 | |||
69 | /* if non-NULL the URB contains the response */ | ||
70 | struct urb *urb; | ||
71 | |||
72 | /* if true then this context is used to wait for a response */ | ||
73 | bool in_use; | ||
74 | }; | ||
75 | |||
76 | /* | ||
77 | * Receive contexts for a particular DLN2 module (i2c, gpio, etc.). We use the | ||
78 | * handle header field to identify the module in dln2_dev.mod_rx_slots and then | ||
79 | * the echo header field to index the slots field and find the receive context | ||
80 | * for a particular request. | ||
81 | */ | ||
82 | struct dln2_mod_rx_slots { | ||
83 | /* RX slots bitmap */ | ||
84 | DECLARE_BITMAP(bmap, DLN2_MAX_RX_SLOTS); | ||
85 | |||
86 | /* used to wait for a free RX slot */ | ||
87 | wait_queue_head_t wq; | ||
88 | |||
89 | /* used to wait for an RX operation to complete */ | ||
90 | struct dln2_rx_context slots[DLN2_MAX_RX_SLOTS]; | ||
91 | |||
92 | /* avoid races between alloc/free_rx_slot and dln2_rx_transfer */ | ||
93 | spinlock_t lock; | ||
94 | }; | ||
95 | |||
96 | struct dln2_dev { | ||
97 | struct usb_device *usb_dev; | ||
98 | struct usb_interface *interface; | ||
99 | u8 ep_in; | ||
100 | u8 ep_out; | ||
101 | |||
102 | struct urb *rx_urb[DLN2_MAX_URBS]; | ||
103 | void *rx_buf[DLN2_MAX_URBS]; | ||
104 | |||
105 | struct dln2_mod_rx_slots mod_rx_slots[DLN2_HANDLES]; | ||
106 | |||
107 | struct list_head event_cb_list; | ||
108 | spinlock_t event_cb_lock; | ||
109 | |||
110 | bool disconnect; | ||
111 | int active_transfers; | ||
112 | wait_queue_head_t disconnect_wq; | ||
113 | spinlock_t disconnect_lock; | ||
114 | }; | ||
115 | |||
116 | struct dln2_event_cb_entry { | ||
117 | struct list_head list; | ||
118 | u16 id; | ||
119 | struct platform_device *pdev; | ||
120 | dln2_event_cb_t callback; | ||
121 | }; | ||
122 | |||
123 | int dln2_register_event_cb(struct platform_device *pdev, u16 id, | ||
124 | dln2_event_cb_t event_cb) | ||
125 | { | ||
126 | struct dln2_dev *dln2 = dev_get_drvdata(pdev->dev.parent); | ||
127 | struct dln2_event_cb_entry *i, *entry; | ||
128 | unsigned long flags; | ||
129 | int ret = 0; | ||
130 | |||
131 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | ||
132 | if (!entry) | ||
133 | return -ENOMEM; | ||
134 | |||
135 | entry->id = id; | ||
136 | entry->callback = event_cb; | ||
137 | entry->pdev = pdev; | ||
138 | |||
139 | spin_lock_irqsave(&dln2->event_cb_lock, flags); | ||
140 | |||
141 | list_for_each_entry(i, &dln2->event_cb_list, list) { | ||
142 | if (i->id == id) { | ||
143 | ret = -EBUSY; | ||
144 | break; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | if (!ret) | ||
149 | list_add_rcu(&entry->list, &dln2->event_cb_list); | ||
150 | |||
151 | spin_unlock_irqrestore(&dln2->event_cb_lock, flags); | ||
152 | |||
153 | if (ret) | ||
154 | kfree(entry); | ||
155 | |||
156 | return ret; | ||
157 | } | ||
158 | EXPORT_SYMBOL(dln2_register_event_cb); | ||
159 | |||
160 | void dln2_unregister_event_cb(struct platform_device *pdev, u16 id) | ||
161 | { | ||
162 | struct dln2_dev *dln2 = dev_get_drvdata(pdev->dev.parent); | ||
163 | struct dln2_event_cb_entry *i; | ||
164 | unsigned long flags; | ||
165 | bool found = false; | ||
166 | |||
167 | spin_lock_irqsave(&dln2->event_cb_lock, flags); | ||
168 | |||
169 | list_for_each_entry(i, &dln2->event_cb_list, list) { | ||
170 | if (i->id == id) { | ||
171 | list_del_rcu(&i->list); | ||
172 | found = true; | ||
173 | break; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | spin_unlock_irqrestore(&dln2->event_cb_lock, flags); | ||
178 | |||
179 | if (found) { | ||
180 | synchronize_rcu(); | ||
181 | kfree(i); | ||
182 | } | ||
183 | } | ||
184 | EXPORT_SYMBOL(dln2_unregister_event_cb); | ||
185 | |||
186 | /* | ||
187 | * Returns true if a valid transfer slot is found. In this case the URB must not | ||
188 | * be resubmitted immediately in dln2_rx as we need the data when dln2_transfer | ||
189 | * is woke up. It will be resubmitted there. | ||
190 | */ | ||
191 | static bool dln2_transfer_complete(struct dln2_dev *dln2, struct urb *urb, | ||
192 | u16 handle, u16 rx_slot) | ||
193 | { | ||
194 | struct device *dev = &dln2->interface->dev; | ||
195 | struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle]; | ||
196 | struct dln2_rx_context *rxc; | ||
197 | bool valid_slot = false; | ||
198 | |||
199 | if (rx_slot >= DLN2_MAX_RX_SLOTS) | ||
200 | goto out; | ||
201 | |||
202 | rxc = &rxs->slots[rx_slot]; | ||
203 | |||
204 | /* | ||
205 | * No need to disable interrupts as this lock is not taken in interrupt | ||
206 | * context elsewhere in this driver. This function (or its callers) are | ||
207 | * also not exported to other modules. | ||
208 | */ | ||
209 | spin_lock(&rxs->lock); | ||
210 | if (rxc->in_use && !rxc->urb) { | ||
211 | rxc->urb = urb; | ||
212 | complete(&rxc->done); | ||
213 | valid_slot = true; | ||
214 | } | ||
215 | spin_unlock(&rxs->lock); | ||
216 | |||
217 | out: | ||
218 | if (!valid_slot) | ||
219 | dev_warn(dev, "bad/late response %d/%d\n", handle, rx_slot); | ||
220 | |||
221 | return valid_slot; | ||
222 | } | ||
223 | |||
224 | static void dln2_run_event_callbacks(struct dln2_dev *dln2, u16 id, u16 echo, | ||
225 | void *data, int len) | ||
226 | { | ||
227 | struct dln2_event_cb_entry *i; | ||
228 | |||
229 | rcu_read_lock(); | ||
230 | |||
231 | list_for_each_entry_rcu(i, &dln2->event_cb_list, list) { | ||
232 | if (i->id == id) { | ||
233 | i->callback(i->pdev, echo, data, len); | ||
234 | break; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | rcu_read_unlock(); | ||
239 | } | ||
240 | |||
241 | static void dln2_rx(struct urb *urb) | ||
242 | { | ||
243 | struct dln2_dev *dln2 = urb->context; | ||
244 | struct dln2_header *hdr = urb->transfer_buffer; | ||
245 | struct device *dev = &dln2->interface->dev; | ||
246 | u16 id, echo, handle, size; | ||
247 | u8 *data; | ||
248 | int len; | ||
249 | int err; | ||
250 | |||
251 | switch (urb->status) { | ||
252 | case 0: | ||
253 | /* success */ | ||
254 | break; | ||
255 | case -ECONNRESET: | ||
256 | case -ENOENT: | ||
257 | case -ESHUTDOWN: | ||
258 | case -EPIPE: | ||
259 | /* this urb is terminated, clean up */ | ||
260 | dev_dbg(dev, "urb shutting down with status %d\n", urb->status); | ||
261 | return; | ||
262 | default: | ||
263 | dev_dbg(dev, "nonzero urb status received %d\n", urb->status); | ||
264 | goto out; | ||
265 | } | ||
266 | |||
267 | if (urb->actual_length < sizeof(struct dln2_header)) { | ||
268 | dev_err(dev, "short response: %d\n", urb->actual_length); | ||
269 | goto out; | ||
270 | } | ||
271 | |||
272 | handle = le16_to_cpu(hdr->handle); | ||
273 | id = le16_to_cpu(hdr->id); | ||
274 | echo = le16_to_cpu(hdr->echo); | ||
275 | size = le16_to_cpu(hdr->size); | ||
276 | |||
277 | if (size != urb->actual_length) { | ||
278 | dev_err(dev, "size mismatch: handle %x cmd %x echo %x size %d actual %d\n", | ||
279 | handle, id, echo, size, urb->actual_length); | ||
280 | goto out; | ||
281 | } | ||
282 | |||
283 | if (handle >= DLN2_HANDLES) { | ||
284 | dev_warn(dev, "invalid handle %d\n", handle); | ||
285 | goto out; | ||
286 | } | ||
287 | |||
288 | data = urb->transfer_buffer + sizeof(struct dln2_header); | ||
289 | len = urb->actual_length - sizeof(struct dln2_header); | ||
290 | |||
291 | if (handle == DLN2_HANDLE_EVENT) { | ||
292 | dln2_run_event_callbacks(dln2, id, echo, data, len); | ||
293 | } else { | ||
294 | /* URB will be re-submitted in _dln2_transfer (free_rx_slot) */ | ||
295 | if (dln2_transfer_complete(dln2, urb, handle, echo)) | ||
296 | return; | ||
297 | } | ||
298 | |||
299 | out: | ||
300 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
301 | if (err < 0) | ||
302 | dev_err(dev, "failed to resubmit RX URB: %d\n", err); | ||
303 | } | ||
304 | |||
305 | static void *dln2_prep_buf(u16 handle, u16 cmd, u16 echo, const void *obuf, | ||
306 | int *obuf_len, gfp_t gfp) | ||
307 | { | ||
308 | int len; | ||
309 | void *buf; | ||
310 | struct dln2_header *hdr; | ||
311 | |||
312 | len = *obuf_len + sizeof(*hdr); | ||
313 | buf = kmalloc(len, gfp); | ||
314 | if (!buf) | ||
315 | return NULL; | ||
316 | |||
317 | hdr = (struct dln2_header *)buf; | ||
318 | hdr->id = cpu_to_le16(cmd); | ||
319 | hdr->size = cpu_to_le16(len); | ||
320 | hdr->echo = cpu_to_le16(echo); | ||
321 | hdr->handle = cpu_to_le16(handle); | ||
322 | |||
323 | memcpy(buf + sizeof(*hdr), obuf, *obuf_len); | ||
324 | |||
325 | *obuf_len = len; | ||
326 | |||
327 | return buf; | ||
328 | } | ||
329 | |||
330 | static int dln2_send_wait(struct dln2_dev *dln2, u16 handle, u16 cmd, u16 echo, | ||
331 | const void *obuf, int obuf_len) | ||
332 | { | ||
333 | int ret = 0; | ||
334 | int len = obuf_len; | ||
335 | void *buf; | ||
336 | int actual; | ||
337 | |||
338 | buf = dln2_prep_buf(handle, cmd, echo, obuf, &len, GFP_KERNEL); | ||
339 | if (!buf) | ||
340 | return -ENOMEM; | ||
341 | |||
342 | ret = usb_bulk_msg(dln2->usb_dev, | ||
343 | usb_sndbulkpipe(dln2->usb_dev, dln2->ep_out), | ||
344 | buf, len, &actual, DLN2_USB_TIMEOUT); | ||
345 | |||
346 | kfree(buf); | ||
347 | |||
348 | return ret; | ||
349 | } | ||
350 | |||
351 | static bool find_free_slot(struct dln2_dev *dln2, u16 handle, int *slot) | ||
352 | { | ||
353 | struct dln2_mod_rx_slots *rxs; | ||
354 | unsigned long flags; | ||
355 | |||
356 | if (dln2->disconnect) { | ||
357 | *slot = -ENODEV; | ||
358 | return true; | ||
359 | } | ||
360 | |||
361 | rxs = &dln2->mod_rx_slots[handle]; | ||
362 | |||
363 | spin_lock_irqsave(&rxs->lock, flags); | ||
364 | |||
365 | *slot = find_first_zero_bit(rxs->bmap, DLN2_MAX_RX_SLOTS); | ||
366 | |||
367 | if (*slot < DLN2_MAX_RX_SLOTS) { | ||
368 | struct dln2_rx_context *rxc = &rxs->slots[*slot]; | ||
369 | |||
370 | set_bit(*slot, rxs->bmap); | ||
371 | rxc->in_use = true; | ||
372 | } | ||
373 | |||
374 | spin_unlock_irqrestore(&rxs->lock, flags); | ||
375 | |||
376 | return *slot < DLN2_MAX_RX_SLOTS; | ||
377 | } | ||
378 | |||
379 | static int alloc_rx_slot(struct dln2_dev *dln2, u16 handle) | ||
380 | { | ||
381 | int ret; | ||
382 | int slot; | ||
383 | |||
384 | /* | ||
385 | * No need to timeout here, the wait is bounded by the timeout in | ||
386 | * _dln2_transfer. | ||
387 | */ | ||
388 | ret = wait_event_interruptible(dln2->mod_rx_slots[handle].wq, | ||
389 | find_free_slot(dln2, handle, &slot)); | ||
390 | if (ret < 0) | ||
391 | return ret; | ||
392 | |||
393 | return slot; | ||
394 | } | ||
395 | |||
396 | static void free_rx_slot(struct dln2_dev *dln2, u16 handle, int slot) | ||
397 | { | ||
398 | struct dln2_mod_rx_slots *rxs; | ||
399 | struct urb *urb = NULL; | ||
400 | unsigned long flags; | ||
401 | struct dln2_rx_context *rxc; | ||
402 | |||
403 | rxs = &dln2->mod_rx_slots[handle]; | ||
404 | |||
405 | spin_lock_irqsave(&rxs->lock, flags); | ||
406 | |||
407 | clear_bit(slot, rxs->bmap); | ||
408 | |||
409 | rxc = &rxs->slots[slot]; | ||
410 | rxc->in_use = false; | ||
411 | urb = rxc->urb; | ||
412 | rxc->urb = NULL; | ||
413 | reinit_completion(&rxc->done); | ||
414 | |||
415 | spin_unlock_irqrestore(&rxs->lock, flags); | ||
416 | |||
417 | if (urb) { | ||
418 | int err; | ||
419 | struct device *dev = &dln2->interface->dev; | ||
420 | |||
421 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
422 | if (err < 0) | ||
423 | dev_err(dev, "failed to resubmit RX URB: %d\n", err); | ||
424 | } | ||
425 | |||
426 | wake_up_interruptible(&rxs->wq); | ||
427 | } | ||
428 | |||
429 | static int _dln2_transfer(struct dln2_dev *dln2, u16 handle, u16 cmd, | ||
430 | const void *obuf, unsigned obuf_len, | ||
431 | void *ibuf, unsigned *ibuf_len) | ||
432 | { | ||
433 | int ret = 0; | ||
434 | int rx_slot; | ||
435 | struct dln2_response *rsp; | ||
436 | struct dln2_rx_context *rxc; | ||
437 | struct device *dev = &dln2->interface->dev; | ||
438 | const unsigned long timeout = DLN2_USB_TIMEOUT * HZ / 1000; | ||
439 | struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle]; | ||
440 | int size; | ||
441 | |||
442 | spin_lock(&dln2->disconnect_lock); | ||
443 | if (!dln2->disconnect) | ||
444 | dln2->active_transfers++; | ||
445 | else | ||
446 | ret = -ENODEV; | ||
447 | spin_unlock(&dln2->disconnect_lock); | ||
448 | |||
449 | if (ret) | ||
450 | return ret; | ||
451 | |||
452 | rx_slot = alloc_rx_slot(dln2, handle); | ||
453 | if (rx_slot < 0) { | ||
454 | ret = rx_slot; | ||
455 | goto out_decr; | ||
456 | } | ||
457 | |||
458 | ret = dln2_send_wait(dln2, handle, cmd, rx_slot, obuf, obuf_len); | ||
459 | if (ret < 0) { | ||
460 | dev_err(dev, "USB write failed: %d\n", ret); | ||
461 | goto out_free_rx_slot; | ||
462 | } | ||
463 | |||
464 | rxc = &rxs->slots[rx_slot]; | ||
465 | |||
466 | ret = wait_for_completion_interruptible_timeout(&rxc->done, timeout); | ||
467 | if (ret <= 0) { | ||
468 | if (!ret) | ||
469 | ret = -ETIMEDOUT; | ||
470 | goto out_free_rx_slot; | ||
471 | } else { | ||
472 | ret = 0; | ||
473 | } | ||
474 | |||
475 | if (dln2->disconnect) { | ||
476 | ret = -ENODEV; | ||
477 | goto out_free_rx_slot; | ||
478 | } | ||
479 | |||
480 | /* if we got here we know that the response header has been checked */ | ||
481 | rsp = rxc->urb->transfer_buffer; | ||
482 | size = le16_to_cpu(rsp->hdr.size); | ||
483 | |||
484 | if (size < sizeof(*rsp)) { | ||
485 | ret = -EPROTO; | ||
486 | goto out_free_rx_slot; | ||
487 | } | ||
488 | |||
489 | if (le16_to_cpu(rsp->result) > 0x80) { | ||
490 | dev_dbg(dev, "%d received response with error %d\n", | ||
491 | handle, le16_to_cpu(rsp->result)); | ||
492 | ret = -EREMOTEIO; | ||
493 | goto out_free_rx_slot; | ||
494 | } | ||
495 | |||
496 | if (!ibuf) | ||
497 | goto out_free_rx_slot; | ||
498 | |||
499 | if (*ibuf_len > size - sizeof(*rsp)) | ||
500 | *ibuf_len = size - sizeof(*rsp); | ||
501 | |||
502 | memcpy(ibuf, rsp + 1, *ibuf_len); | ||
503 | |||
504 | out_free_rx_slot: | ||
505 | free_rx_slot(dln2, handle, rx_slot); | ||
506 | out_decr: | ||
507 | spin_lock(&dln2->disconnect_lock); | ||
508 | dln2->active_transfers--; | ||
509 | spin_unlock(&dln2->disconnect_lock); | ||
510 | if (dln2->disconnect) | ||
511 | wake_up(&dln2->disconnect_wq); | ||
512 | |||
513 | return ret; | ||
514 | } | ||
515 | |||
516 | int dln2_transfer(struct platform_device *pdev, u16 cmd, | ||
517 | const void *obuf, unsigned obuf_len, | ||
518 | void *ibuf, unsigned *ibuf_len) | ||
519 | { | ||
520 | struct dln2_platform_data *dln2_pdata; | ||
521 | struct dln2_dev *dln2; | ||
522 | u16 handle; | ||
523 | |||
524 | dln2 = dev_get_drvdata(pdev->dev.parent); | ||
525 | dln2_pdata = dev_get_platdata(&pdev->dev); | ||
526 | handle = dln2_pdata->handle; | ||
527 | |||
528 | return _dln2_transfer(dln2, handle, cmd, obuf, obuf_len, ibuf, | ||
529 | ibuf_len); | ||
530 | } | ||
531 | EXPORT_SYMBOL(dln2_transfer); | ||
532 | |||
533 | static int dln2_check_hw(struct dln2_dev *dln2) | ||
534 | { | ||
535 | int ret; | ||
536 | __le32 hw_type; | ||
537 | int len = sizeof(hw_type); | ||
538 | |||
539 | ret = _dln2_transfer(dln2, DLN2_HANDLE_CTRL, CMD_GET_DEVICE_VER, | ||
540 | NULL, 0, &hw_type, &len); | ||
541 | if (ret < 0) | ||
542 | return ret; | ||
543 | if (len < sizeof(hw_type)) | ||
544 | return -EREMOTEIO; | ||
545 | |||
546 | if (le32_to_cpu(hw_type) != DLN2_HW_ID) { | ||
547 | dev_err(&dln2->interface->dev, "Device ID 0x%x not supported\n", | ||
548 | le32_to_cpu(hw_type)); | ||
549 | return -ENODEV; | ||
550 | } | ||
551 | |||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | static int dln2_print_serialno(struct dln2_dev *dln2) | ||
556 | { | ||
557 | int ret; | ||
558 | __le32 serial_no; | ||
559 | int len = sizeof(serial_no); | ||
560 | struct device *dev = &dln2->interface->dev; | ||
561 | |||
562 | ret = _dln2_transfer(dln2, DLN2_HANDLE_CTRL, CMD_GET_DEVICE_SN, NULL, 0, | ||
563 | &serial_no, &len); | ||
564 | if (ret < 0) | ||
565 | return ret; | ||
566 | if (len < sizeof(serial_no)) | ||
567 | return -EREMOTEIO; | ||
568 | |||
569 | dev_info(dev, "Diolan DLN2 serial %u\n", le32_to_cpu(serial_no)); | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | static int dln2_hw_init(struct dln2_dev *dln2) | ||
575 | { | ||
576 | int ret; | ||
577 | |||
578 | ret = dln2_check_hw(dln2); | ||
579 | if (ret < 0) | ||
580 | return ret; | ||
581 | |||
582 | return dln2_print_serialno(dln2); | ||
583 | } | ||
584 | |||
585 | static void dln2_free_rx_urbs(struct dln2_dev *dln2) | ||
586 | { | ||
587 | int i; | ||
588 | |||
589 | for (i = 0; i < DLN2_MAX_URBS; i++) { | ||
590 | usb_kill_urb(dln2->rx_urb[i]); | ||
591 | usb_free_urb(dln2->rx_urb[i]); | ||
592 | kfree(dln2->rx_buf[i]); | ||
593 | } | ||
594 | } | ||
595 | |||
596 | static void dln2_free(struct dln2_dev *dln2) | ||
597 | { | ||
598 | dln2_free_rx_urbs(dln2); | ||
599 | usb_put_dev(dln2->usb_dev); | ||
600 | kfree(dln2); | ||
601 | } | ||
602 | |||
603 | static int dln2_setup_rx_urbs(struct dln2_dev *dln2, | ||
604 | struct usb_host_interface *hostif) | ||
605 | { | ||
606 | int i; | ||
607 | int ret; | ||
608 | const int rx_max_size = DLN2_RX_BUF_SIZE; | ||
609 | struct device *dev = &dln2->interface->dev; | ||
610 | |||
611 | for (i = 0; i < DLN2_MAX_URBS; i++) { | ||
612 | dln2->rx_buf[i] = kmalloc(rx_max_size, GFP_KERNEL); | ||
613 | if (!dln2->rx_buf[i]) | ||
614 | return -ENOMEM; | ||
615 | |||
616 | dln2->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); | ||
617 | if (!dln2->rx_urb[i]) | ||
618 | return -ENOMEM; | ||
619 | |||
620 | usb_fill_bulk_urb(dln2->rx_urb[i], dln2->usb_dev, | ||
621 | usb_rcvbulkpipe(dln2->usb_dev, dln2->ep_in), | ||
622 | dln2->rx_buf[i], rx_max_size, dln2_rx, dln2); | ||
623 | |||
624 | ret = usb_submit_urb(dln2->rx_urb[i], GFP_KERNEL); | ||
625 | if (ret < 0) { | ||
626 | dev_err(dev, "failed to submit RX URB: %d\n", ret); | ||
627 | return ret; | ||
628 | } | ||
629 | } | ||
630 | |||
631 | return 0; | ||
632 | } | ||
633 | |||
634 | static struct dln2_platform_data dln2_pdata_gpio = { | ||
635 | .handle = DLN2_HANDLE_GPIO, | ||
636 | }; | ||
637 | |||
638 | /* Only one I2C port seems to be supported on current hardware */ | ||
639 | static struct dln2_platform_data dln2_pdata_i2c = { | ||
640 | .handle = DLN2_HANDLE_I2C, | ||
641 | .port = 0, | ||
642 | }; | ||
643 | |||
644 | /* Only one SPI port supported */ | ||
645 | static struct dln2_platform_data dln2_pdata_spi = { | ||
646 | .handle = DLN2_HANDLE_SPI, | ||
647 | .port = 0, | ||
648 | }; | ||
649 | |||
650 | static const struct mfd_cell dln2_devs[] = { | ||
651 | { | ||
652 | .name = "dln2-gpio", | ||
653 | .platform_data = &dln2_pdata_gpio, | ||
654 | .pdata_size = sizeof(struct dln2_platform_data), | ||
655 | }, | ||
656 | { | ||
657 | .name = "dln2-i2c", | ||
658 | .platform_data = &dln2_pdata_i2c, | ||
659 | .pdata_size = sizeof(struct dln2_platform_data), | ||
660 | }, | ||
661 | { | ||
662 | .name = "dln2-spi", | ||
663 | .platform_data = &dln2_pdata_spi, | ||
664 | .pdata_size = sizeof(struct dln2_platform_data), | ||
665 | }, | ||
666 | }; | ||
667 | |||
668 | static void dln2_disconnect(struct usb_interface *interface) | ||
669 | { | ||
670 | struct dln2_dev *dln2 = usb_get_intfdata(interface); | ||
671 | int i, j; | ||
672 | |||
673 | /* don't allow starting new transfers */ | ||
674 | spin_lock(&dln2->disconnect_lock); | ||
675 | dln2->disconnect = true; | ||
676 | spin_unlock(&dln2->disconnect_lock); | ||
677 | |||
678 | /* cancel in progress transfers */ | ||
679 | for (i = 0; i < DLN2_HANDLES; i++) { | ||
680 | struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[i]; | ||
681 | unsigned long flags; | ||
682 | |||
683 | spin_lock_irqsave(&rxs->lock, flags); | ||
684 | |||
685 | /* cancel all response waiters */ | ||
686 | for (j = 0; j < DLN2_MAX_RX_SLOTS; j++) { | ||
687 | struct dln2_rx_context *rxc = &rxs->slots[j]; | ||
688 | |||
689 | if (rxc->in_use) | ||
690 | complete(&rxc->done); | ||
691 | } | ||
692 | |||
693 | spin_unlock_irqrestore(&rxs->lock, flags); | ||
694 | } | ||
695 | |||
696 | /* wait for transfers to end */ | ||
697 | wait_event(dln2->disconnect_wq, !dln2->active_transfers); | ||
698 | |||
699 | mfd_remove_devices(&interface->dev); | ||
700 | |||
701 | dln2_free(dln2); | ||
702 | } | ||
703 | |||
704 | static int dln2_probe(struct usb_interface *interface, | ||
705 | const struct usb_device_id *usb_id) | ||
706 | { | ||
707 | struct usb_host_interface *hostif = interface->cur_altsetting; | ||
708 | struct device *dev = &interface->dev; | ||
709 | struct dln2_dev *dln2; | ||
710 | int ret; | ||
711 | int i, j; | ||
712 | |||
713 | if (hostif->desc.bInterfaceNumber != 0 || | ||
714 | hostif->desc.bNumEndpoints < 2) | ||
715 | return -ENODEV; | ||
716 | |||
717 | dln2 = kzalloc(sizeof(*dln2), GFP_KERNEL); | ||
718 | if (!dln2) | ||
719 | return -ENOMEM; | ||
720 | |||
721 | dln2->ep_out = hostif->endpoint[0].desc.bEndpointAddress; | ||
722 | dln2->ep_in = hostif->endpoint[1].desc.bEndpointAddress; | ||
723 | dln2->usb_dev = usb_get_dev(interface_to_usbdev(interface)); | ||
724 | dln2->interface = interface; | ||
725 | usb_set_intfdata(interface, dln2); | ||
726 | init_waitqueue_head(&dln2->disconnect_wq); | ||
727 | |||
728 | for (i = 0; i < DLN2_HANDLES; i++) { | ||
729 | init_waitqueue_head(&dln2->mod_rx_slots[i].wq); | ||
730 | spin_lock_init(&dln2->mod_rx_slots[i].lock); | ||
731 | for (j = 0; j < DLN2_MAX_RX_SLOTS; j++) | ||
732 | init_completion(&dln2->mod_rx_slots[i].slots[j].done); | ||
733 | } | ||
734 | |||
735 | spin_lock_init(&dln2->event_cb_lock); | ||
736 | spin_lock_init(&dln2->disconnect_lock); | ||
737 | INIT_LIST_HEAD(&dln2->event_cb_list); | ||
738 | |||
739 | ret = dln2_setup_rx_urbs(dln2, hostif); | ||
740 | if (ret) | ||
741 | goto out_cleanup; | ||
742 | |||
743 | ret = dln2_hw_init(dln2); | ||
744 | if (ret < 0) { | ||
745 | dev_err(dev, "failed to initialize hardware\n"); | ||
746 | goto out_cleanup; | ||
747 | } | ||
748 | |||
749 | ret = mfd_add_hotplug_devices(dev, dln2_devs, ARRAY_SIZE(dln2_devs)); | ||
750 | if (ret != 0) { | ||
751 | dev_err(dev, "failed to add mfd devices to core\n"); | ||
752 | goto out_cleanup; | ||
753 | } | ||
754 | |||
755 | return 0; | ||
756 | |||
757 | out_cleanup: | ||
758 | dln2_free(dln2); | ||
759 | |||
760 | return ret; | ||
761 | } | ||
762 | |||
763 | static const struct usb_device_id dln2_table[] = { | ||
764 | { USB_DEVICE(0xa257, 0x2013) }, | ||
765 | { } | ||
766 | }; | ||
767 | |||
768 | MODULE_DEVICE_TABLE(usb, dln2_table); | ||
769 | |||
770 | static struct usb_driver dln2_driver = { | ||
771 | .name = "dln2", | ||
772 | .probe = dln2_probe, | ||
773 | .disconnect = dln2_disconnect, | ||
774 | .id_table = dln2_table, | ||
775 | }; | ||
776 | |||
777 | module_usb_driver(dln2_driver); | ||
778 | |||
779 | MODULE_AUTHOR("Octavian Purdila <octavian.purdila@intel.com>"); | ||
780 | MODULE_DESCRIPTION("Core driver for the Diolan DLN2 interface adapter"); | ||
781 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c index c980da479a35..5c38df35a84d 100644 --- a/drivers/mfd/lpc_sch.c +++ b/drivers/mfd/lpc_sch.c | |||
@@ -193,11 +193,7 @@ static int lpc_sch_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
193 | return -ENODEV; | 193 | return -ENODEV; |
194 | } | 194 | } |
195 | 195 | ||
196 | ret = mfd_add_devices(&dev->dev, 0, lpc_sch_cells, cells, NULL, 0, NULL); | 196 | return mfd_add_devices(&dev->dev, 0, lpc_sch_cells, cells, NULL, 0, NULL); |
197 | if (ret) | ||
198 | mfd_remove_devices(&dev->dev); | ||
199 | |||
200 | return ret; | ||
201 | } | 197 | } |
202 | 198 | ||
203 | static void lpc_sch_remove(struct pci_dev *dev) | 199 | static void lpc_sch_remove(struct pci_dev *dev) |
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c index de96b7fb1f6d..3bf8def82f1e 100644 --- a/drivers/mfd/max14577.c +++ b/drivers/mfd/max14577.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * max14577.c - mfd core driver for the Maxim 14577/77836 | 2 | * max14577.c - mfd core driver for the Maxim 14577/77836 |
3 | * | 3 | * |
4 | * Copyright (C) 2014 Samsung Electrnoics | 4 | * Copyright (C) 2014 Samsung Electronics |
5 | * Chanwoo Choi <cw00.choi@samsung.com> | 5 | * Chanwoo Choi <cw00.choi@samsung.com> |
6 | * Krzysztof Kozlowski <k.kozlowski@samsung.com> | 6 | * Krzysztof Kozlowski <k.kozlowski@samsung.com> |
7 | * | 7 | * |
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index 711773e8e64b..a159593e27a0 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c | |||
@@ -43,9 +43,15 @@ | |||
43 | 43 | ||
44 | static const struct mfd_cell max77693_devs[] = { | 44 | static const struct mfd_cell max77693_devs[] = { |
45 | { .name = "max77693-pmic", }, | 45 | { .name = "max77693-pmic", }, |
46 | { .name = "max77693-charger", }, | 46 | { |
47 | .name = "max77693-charger", | ||
48 | .of_compatible = "maxim,max77693-charger", | ||
49 | }, | ||
47 | { .name = "max77693-muic", }, | 50 | { .name = "max77693-muic", }, |
48 | { .name = "max77693-haptic", }, | 51 | { |
52 | .name = "max77693-haptic", | ||
53 | .of_compatible = "maxim,max77693-haptic", | ||
54 | }, | ||
49 | { | 55 | { |
50 | .name = "max77693-flash", | 56 | .name = "max77693-flash", |
51 | .of_compatible = "maxim,max77693-flash", | 57 | .of_compatible = "maxim,max77693-flash", |
@@ -147,6 +153,12 @@ static const struct regmap_irq_chip max77693_muic_irq_chip = { | |||
147 | .num_irqs = ARRAY_SIZE(max77693_muic_irqs), | 153 | .num_irqs = ARRAY_SIZE(max77693_muic_irqs), |
148 | }; | 154 | }; |
149 | 155 | ||
156 | static const struct regmap_config max77693_regmap_haptic_config = { | ||
157 | .reg_bits = 8, | ||
158 | .val_bits = 8, | ||
159 | .max_register = MAX77693_HAPTIC_REG_END, | ||
160 | }; | ||
161 | |||
150 | static int max77693_i2c_probe(struct i2c_client *i2c, | 162 | static int max77693_i2c_probe(struct i2c_client *i2c, |
151 | const struct i2c_device_id *id) | 163 | const struct i2c_device_id *id) |
152 | { | 164 | { |
@@ -196,6 +208,15 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
196 | } | 208 | } |
197 | i2c_set_clientdata(max77693->haptic, max77693); | 209 | i2c_set_clientdata(max77693->haptic, max77693); |
198 | 210 | ||
211 | max77693->regmap_haptic = devm_regmap_init_i2c(max77693->haptic, | ||
212 | &max77693_regmap_haptic_config); | ||
213 | if (IS_ERR(max77693->regmap_haptic)) { | ||
214 | ret = PTR_ERR(max77693->regmap_haptic); | ||
215 | dev_err(max77693->dev, | ||
216 | "failed to initialize haptic register map: %d\n", ret); | ||
217 | goto err_regmap; | ||
218 | } | ||
219 | |||
199 | /* | 220 | /* |
200 | * Initialize register map for MUIC device because use regmap-muic | 221 | * Initialize register map for MUIC device because use regmap-muic |
201 | * instance of MUIC device when irq of max77693 is initialized | 222 | * instance of MUIC device when irq of max77693 is initialized |
@@ -207,7 +228,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
207 | ret = PTR_ERR(max77693->regmap_muic); | 228 | ret = PTR_ERR(max77693->regmap_muic); |
208 | dev_err(max77693->dev, | 229 | dev_err(max77693->dev, |
209 | "failed to allocate register map: %d\n", ret); | 230 | "failed to allocate register map: %d\n", ret); |
210 | goto err_regmap_muic; | 231 | goto err_regmap; |
211 | } | 232 | } |
212 | 233 | ||
213 | ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, | 234 | ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, |
@@ -217,7 +238,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
217 | &max77693->irq_data_led); | 238 | &max77693->irq_data_led); |
218 | if (ret) { | 239 | if (ret) { |
219 | dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); | 240 | dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); |
220 | goto err_regmap_muic; | 241 | goto err_regmap; |
221 | } | 242 | } |
222 | 243 | ||
223 | ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, | 244 | ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, |
@@ -280,7 +301,7 @@ err_irq_charger: | |||
280 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys); | 301 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys); |
281 | err_irq_topsys: | 302 | err_irq_topsys: |
282 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_led); | 303 | regmap_del_irq_chip(max77693->irq, max77693->irq_data_led); |
283 | err_regmap_muic: | 304 | err_regmap: |
284 | i2c_unregister_device(max77693->haptic); | 305 | i2c_unregister_device(max77693->haptic); |
285 | err_i2c_haptic: | 306 | err_i2c_haptic: |
286 | i2c_unregister_device(max77693->muic); | 307 | i2c_unregister_device(max77693->muic); |
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index f3338fe9d069..2a87f69be53d 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
@@ -125,9 +125,15 @@ static int mfd_add_device(struct device *parent, int id, | |||
125 | struct platform_device *pdev; | 125 | struct platform_device *pdev; |
126 | struct device_node *np = NULL; | 126 | struct device_node *np = NULL; |
127 | int ret = -ENOMEM; | 127 | int ret = -ENOMEM; |
128 | int platform_id; | ||
128 | int r; | 129 | int r; |
129 | 130 | ||
130 | pdev = platform_device_alloc(cell->name, id + cell->id); | 131 | if (id < 0) |
132 | platform_id = id; | ||
133 | else | ||
134 | platform_id = id + cell->id; | ||
135 | |||
136 | pdev = platform_device_alloc(cell->name, platform_id); | ||
131 | if (!pdev) | 137 | if (!pdev) |
132 | goto fail_alloc; | 138 | goto fail_alloc; |
133 | 139 | ||
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c index 9c8eec80ceed..32407404d838 100644 --- a/drivers/mfd/rts5227.c +++ b/drivers/mfd/rts5227.c | |||
@@ -130,6 +130,12 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) | |||
130 | 130 | ||
131 | static int rts5227_optimize_phy(struct rtsx_pcr *pcr) | 131 | static int rts5227_optimize_phy(struct rtsx_pcr *pcr) |
132 | { | 132 | { |
133 | int err; | ||
134 | |||
135 | err = rtsx_gops_pm_reset(pcr); | ||
136 | if (err < 0) | ||
137 | return err; | ||
138 | |||
133 | /* Optimize RX sensitivity */ | 139 | /* Optimize RX sensitivity */ |
134 | return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42); | 140 | return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42); |
135 | } | 141 | } |
diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c index 573de7bfcced..cf425cc959d5 100644 --- a/drivers/mfd/rts5249.c +++ b/drivers/mfd/rts5249.c | |||
@@ -130,6 +130,10 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr) | |||
130 | { | 130 | { |
131 | int err; | 131 | int err; |
132 | 132 | ||
133 | err = rtsx_gops_pm_reset(pcr); | ||
134 | if (err < 0) | ||
135 | return err; | ||
136 | |||
133 | err = rtsx_pci_write_phy_register(pcr, PHY_REG_REV, | 137 | err = rtsx_pci_write_phy_register(pcr, PHY_REG_REV, |
134 | PHY_REG_REV_RESV | PHY_REG_REV_RXIDLE_LATCHED | | 138 | PHY_REG_REV_RESV | PHY_REG_REV_RXIDLE_LATCHED | |
135 | PHY_REG_REV_P1_EN | PHY_REG_REV_RXIDLE_EN | | 139 | PHY_REG_REV_P1_EN | PHY_REG_REV_RXIDLE_EN | |
diff --git a/drivers/mfd/rtsx_gops.c b/drivers/mfd/rtsx_gops.c new file mode 100644 index 000000000000..b1a98c678593 --- /dev/null +++ b/drivers/mfd/rtsx_gops.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* Driver for Realtek PCI-Express card reader | ||
2 | * | ||
3 | * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2, or (at your option) any | ||
8 | * later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, see <http://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * Author: | ||
19 | * Micky Ching <micky_ching@realsil.com.cn> | ||
20 | */ | ||
21 | |||
22 | #include <linux/mfd/rtsx_pci.h> | ||
23 | #include "rtsx_pcr.h" | ||
24 | |||
25 | int rtsx_gops_pm_reset(struct rtsx_pcr *pcr) | ||
26 | { | ||
27 | int err; | ||
28 | |||
29 | /* init aspm */ | ||
30 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0x00); | ||
31 | err = rtsx_pci_update_cfg_byte(pcr, LCTLR, ~LCTLR_ASPM_CTL_MASK, 0x00); | ||
32 | if (err < 0) | ||
33 | return err; | ||
34 | |||
35 | /* reset PM_CTRL3 before send buffer cmd */ | ||
36 | return rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00); | ||
37 | } | ||
diff --git a/drivers/mfd/rtsx_pcr.h b/drivers/mfd/rtsx_pcr.h index 07e4c2ebf05a..fe2bbb67defc 100644 --- a/drivers/mfd/rtsx_pcr.h +++ b/drivers/mfd/rtsx_pcr.h | |||
@@ -72,4 +72,7 @@ do { \ | |||
72 | pcr->ms_pull_ctl_disable_tbl = __device##_ms_pull_ctl_disable_tbl; \ | 72 | pcr->ms_pull_ctl_disable_tbl = __device##_ms_pull_ctl_disable_tbl; \ |
73 | } while (0) | 73 | } while (0) |
74 | 74 | ||
75 | /* generic operations */ | ||
76 | int rtsx_gops_pm_reset(struct rtsx_pcr *pcr); | ||
77 | |||
75 | #endif | 78 | #endif |
diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c index 9cf98d142d9a..dbdd0faeb6ce 100644 --- a/drivers/mfd/rtsx_usb.c +++ b/drivers/mfd/rtsx_usb.c | |||
@@ -647,8 +647,8 @@ static int rtsx_usb_probe(struct usb_interface *intf, | |||
647 | /* initialize USB SG transfer timer */ | 647 | /* initialize USB SG transfer timer */ |
648 | setup_timer(&ucr->sg_timer, rtsx_usb_sg_timed_out, (unsigned long) ucr); | 648 | setup_timer(&ucr->sg_timer, rtsx_usb_sg_timed_out, (unsigned long) ucr); |
649 | 649 | ||
650 | ret = mfd_add_devices(&intf->dev, usb_dev->devnum, rtsx_usb_cells, | 650 | ret = mfd_add_hotplug_devices(&intf->dev, rtsx_usb_cells, |
651 | ARRAY_SIZE(rtsx_usb_cells), NULL, 0, NULL); | 651 | ARRAY_SIZE(rtsx_usb_cells)); |
652 | if (ret) | 652 | if (ret) |
653 | goto out_init_fail; | 653 | goto out_init_fail; |
654 | 654 | ||
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index dba7e2b6f8e9..0a7bc43db4e4 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c | |||
@@ -27,11 +27,11 @@ | |||
27 | #include <linux/mfd/samsung/irq.h> | 27 | #include <linux/mfd/samsung/irq.h> |
28 | #include <linux/mfd/samsung/s2mpa01.h> | 28 | #include <linux/mfd/samsung/s2mpa01.h> |
29 | #include <linux/mfd/samsung/s2mps11.h> | 29 | #include <linux/mfd/samsung/s2mps11.h> |
30 | #include <linux/mfd/samsung/s2mps13.h> | ||
30 | #include <linux/mfd/samsung/s2mps14.h> | 31 | #include <linux/mfd/samsung/s2mps14.h> |
31 | #include <linux/mfd/samsung/s2mpu02.h> | 32 | #include <linux/mfd/samsung/s2mpu02.h> |
32 | #include <linux/mfd/samsung/s5m8763.h> | 33 | #include <linux/mfd/samsung/s5m8763.h> |
33 | #include <linux/mfd/samsung/s5m8767.h> | 34 | #include <linux/mfd/samsung/s5m8767.h> |
34 | #include <linux/regulator/machine.h> | ||
35 | #include <linux/regmap.h> | 35 | #include <linux/regmap.h> |
36 | 36 | ||
37 | static const struct mfd_cell s5m8751_devs[] = { | 37 | static const struct mfd_cell s5m8751_devs[] = { |
@@ -74,6 +74,15 @@ static const struct mfd_cell s2mps11_devs[] = { | |||
74 | } | 74 | } |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static const struct mfd_cell s2mps13_devs[] = { | ||
78 | { .name = "s2mps13-pmic", }, | ||
79 | { .name = "s2mps13-rtc", }, | ||
80 | { | ||
81 | .name = "s2mps13-clk", | ||
82 | .of_compatible = "samsung,s2mps13-clk", | ||
83 | }, | ||
84 | }; | ||
85 | |||
77 | static const struct mfd_cell s2mps14_devs[] = { | 86 | static const struct mfd_cell s2mps14_devs[] = { |
78 | { | 87 | { |
79 | .name = "s2mps14-pmic", | 88 | .name = "s2mps14-pmic", |
@@ -108,6 +117,9 @@ static const struct of_device_id sec_dt_match[] = { | |||
108 | .compatible = "samsung,s2mps11-pmic", | 117 | .compatible = "samsung,s2mps11-pmic", |
109 | .data = (void *)S2MPS11X, | 118 | .data = (void *)S2MPS11X, |
110 | }, { | 119 | }, { |
120 | .compatible = "samsung,s2mps13-pmic", | ||
121 | .data = (void *)S2MPS13X, | ||
122 | }, { | ||
111 | .compatible = "samsung,s2mps14-pmic", | 123 | .compatible = "samsung,s2mps14-pmic", |
112 | .data = (void *)S2MPS14X, | 124 | .data = (void *)S2MPS14X, |
113 | }, { | 125 | }, { |
@@ -194,6 +206,15 @@ static const struct regmap_config s2mps11_regmap_config = { | |||
194 | .cache_type = REGCACHE_FLAT, | 206 | .cache_type = REGCACHE_FLAT, |
195 | }; | 207 | }; |
196 | 208 | ||
209 | static const struct regmap_config s2mps13_regmap_config = { | ||
210 | .reg_bits = 8, | ||
211 | .val_bits = 8, | ||
212 | |||
213 | .max_register = S2MPS13_REG_LDODSCH5, | ||
214 | .volatile_reg = s2mps11_volatile, | ||
215 | .cache_type = REGCACHE_FLAT, | ||
216 | }; | ||
217 | |||
197 | static const struct regmap_config s2mps14_regmap_config = { | 218 | static const struct regmap_config s2mps14_regmap_config = { |
198 | .reg_bits = 8, | 219 | .reg_bits = 8, |
199 | .val_bits = 8, | 220 | .val_bits = 8, |
@@ -325,6 +346,9 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
325 | case S2MPS11X: | 346 | case S2MPS11X: |
326 | regmap = &s2mps11_regmap_config; | 347 | regmap = &s2mps11_regmap_config; |
327 | break; | 348 | break; |
349 | case S2MPS13X: | ||
350 | regmap = &s2mps13_regmap_config; | ||
351 | break; | ||
328 | case S2MPS14X: | 352 | case S2MPS14X: |
329 | regmap = &s2mps14_regmap_config; | 353 | regmap = &s2mps14_regmap_config; |
330 | break; | 354 | break; |
@@ -378,6 +402,10 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
378 | sec_devs = s2mps11_devs; | 402 | sec_devs = s2mps11_devs; |
379 | num_sec_devs = ARRAY_SIZE(s2mps11_devs); | 403 | num_sec_devs = ARRAY_SIZE(s2mps11_devs); |
380 | break; | 404 | break; |
405 | case S2MPS13X: | ||
406 | sec_devs = s2mps13_devs; | ||
407 | num_sec_devs = ARRAY_SIZE(s2mps13_devs); | ||
408 | break; | ||
381 | case S2MPS14X: | 409 | case S2MPS14X: |
382 | sec_devs = s2mps14_devs; | 410 | sec_devs = s2mps14_devs; |
383 | num_sec_devs = ARRAY_SIZE(s2mps14_devs); | 411 | num_sec_devs = ARRAY_SIZE(s2mps14_devs); |
@@ -432,15 +460,6 @@ static int sec_pmic_suspend(struct device *dev) | |||
432 | */ | 460 | */ |
433 | disable_irq(sec_pmic->irq); | 461 | disable_irq(sec_pmic->irq); |
434 | 462 | ||
435 | switch (sec_pmic->device_type) { | ||
436 | case S2MPS14X: | ||
437 | case S2MPU02: | ||
438 | regulator_suspend_prepare(PM_SUSPEND_MEM); | ||
439 | break; | ||
440 | default: | ||
441 | break; | ||
442 | } | ||
443 | |||
444 | return 0; | 463 | return 0; |
445 | } | 464 | } |
446 | 465 | ||
diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c index f9a57869e3ec..ba86a918c2da 100644 --- a/drivers/mfd/sec-irq.c +++ b/drivers/mfd/sec-irq.c | |||
@@ -389,14 +389,22 @@ static const struct regmap_irq_chip s2mps11_irq_chip = { | |||
389 | .ack_base = S2MPS11_REG_INT1, | 389 | .ack_base = S2MPS11_REG_INT1, |
390 | }; | 390 | }; |
391 | 391 | ||
392 | #define S2MPS1X_IRQ_CHIP_COMMON_DATA \ | ||
393 | .irqs = s2mps14_irqs, \ | ||
394 | .num_irqs = ARRAY_SIZE(s2mps14_irqs), \ | ||
395 | .num_regs = 3, \ | ||
396 | .status_base = S2MPS14_REG_INT1, \ | ||
397 | .mask_base = S2MPS14_REG_INT1M, \ | ||
398 | .ack_base = S2MPS14_REG_INT1 \ | ||
399 | |||
400 | static const struct regmap_irq_chip s2mps13_irq_chip = { | ||
401 | .name = "s2mps13", | ||
402 | S2MPS1X_IRQ_CHIP_COMMON_DATA, | ||
403 | }; | ||
404 | |||
392 | static const struct regmap_irq_chip s2mps14_irq_chip = { | 405 | static const struct regmap_irq_chip s2mps14_irq_chip = { |
393 | .name = "s2mps14", | 406 | .name = "s2mps14", |
394 | .irqs = s2mps14_irqs, | 407 | S2MPS1X_IRQ_CHIP_COMMON_DATA, |
395 | .num_irqs = ARRAY_SIZE(s2mps14_irqs), | ||
396 | .num_regs = 3, | ||
397 | .status_base = S2MPS14_REG_INT1, | ||
398 | .mask_base = S2MPS14_REG_INT1M, | ||
399 | .ack_base = S2MPS14_REG_INT1, | ||
400 | }; | 408 | }; |
401 | 409 | ||
402 | static const struct regmap_irq_chip s2mpu02_irq_chip = { | 410 | static const struct regmap_irq_chip s2mpu02_irq_chip = { |
@@ -452,6 +460,9 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic) | |||
452 | case S2MPS11X: | 460 | case S2MPS11X: |
453 | sec_irq_chip = &s2mps11_irq_chip; | 461 | sec_irq_chip = &s2mps11_irq_chip; |
454 | break; | 462 | break; |
463 | case S2MPS13X: | ||
464 | sec_irq_chip = &s2mps13_irq_chip; | ||
465 | break; | ||
455 | case S2MPS14X: | 466 | case S2MPS14X: |
456 | sec_irq_chip = &s2mps14_irq_chip; | 467 | sec_irq_chip = &s2mps14_irq_chip; |
457 | break; | 468 | break; |
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index ca15878ce5c0..72373b113885 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/list.h> | ||
18 | #include <linux/of.h> | 19 | #include <linux/of.h> |
19 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
20 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
@@ -22,31 +23,94 @@ | |||
22 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
23 | #include <linux/regmap.h> | 24 | #include <linux/regmap.h> |
24 | #include <linux/mfd/syscon.h> | 25 | #include <linux/mfd/syscon.h> |
26 | #include <linux/slab.h> | ||
25 | 27 | ||
26 | static struct platform_driver syscon_driver; | 28 | static struct platform_driver syscon_driver; |
27 | 29 | ||
30 | static DEFINE_SPINLOCK(syscon_list_slock); | ||
31 | static LIST_HEAD(syscon_list); | ||
32 | |||
28 | struct syscon { | 33 | struct syscon { |
34 | struct device_node *np; | ||
29 | struct regmap *regmap; | 35 | struct regmap *regmap; |
36 | struct list_head list; | ||
37 | }; | ||
38 | |||
39 | static struct regmap_config syscon_regmap_config = { | ||
40 | .reg_bits = 32, | ||
41 | .val_bits = 32, | ||
42 | .reg_stride = 4, | ||
30 | }; | 43 | }; |
31 | 44 | ||
32 | static int syscon_match_node(struct device *dev, void *data) | 45 | static struct syscon *of_syscon_register(struct device_node *np) |
33 | { | 46 | { |
34 | struct device_node *dn = data; | 47 | struct syscon *syscon; |
48 | struct regmap *regmap; | ||
49 | void __iomem *base; | ||
50 | int ret; | ||
51 | struct regmap_config syscon_config = syscon_regmap_config; | ||
52 | |||
53 | if (!of_device_is_compatible(np, "syscon")) | ||
54 | return ERR_PTR(-EINVAL); | ||
55 | |||
56 | syscon = kzalloc(sizeof(*syscon), GFP_KERNEL); | ||
57 | if (!syscon) | ||
58 | return ERR_PTR(-ENOMEM); | ||
59 | |||
60 | base = of_iomap(np, 0); | ||
61 | if (!base) { | ||
62 | ret = -ENOMEM; | ||
63 | goto err_map; | ||
64 | } | ||
65 | |||
66 | /* Parse the device's DT node for an endianness specification */ | ||
67 | if (of_property_read_bool(np, "big-endian")) | ||
68 | syscon_config.val_format_endian = REGMAP_ENDIAN_BIG; | ||
69 | else if (of_property_read_bool(np, "little-endian")) | ||
70 | syscon_config.val_format_endian = REGMAP_ENDIAN_LITTLE; | ||
71 | |||
72 | regmap = regmap_init_mmio(NULL, base, &syscon_config); | ||
73 | if (IS_ERR(regmap)) { | ||
74 | pr_err("regmap init failed\n"); | ||
75 | ret = PTR_ERR(regmap); | ||
76 | goto err_regmap; | ||
77 | } | ||
78 | |||
79 | syscon->regmap = regmap; | ||
80 | syscon->np = np; | ||
81 | |||
82 | spin_lock(&syscon_list_slock); | ||
83 | list_add_tail(&syscon->list, &syscon_list); | ||
84 | spin_unlock(&syscon_list_slock); | ||
35 | 85 | ||
36 | return (dev->of_node == dn) ? 1 : 0; | 86 | return syscon; |
87 | |||
88 | err_regmap: | ||
89 | iounmap(base); | ||
90 | err_map: | ||
91 | kfree(syscon); | ||
92 | return ERR_PTR(ret); | ||
37 | } | 93 | } |
38 | 94 | ||
39 | struct regmap *syscon_node_to_regmap(struct device_node *np) | 95 | struct regmap *syscon_node_to_regmap(struct device_node *np) |
40 | { | 96 | { |
41 | struct syscon *syscon; | 97 | struct syscon *entry, *syscon = NULL; |
42 | struct device *dev; | ||
43 | 98 | ||
44 | dev = driver_find_device(&syscon_driver.driver, NULL, np, | 99 | spin_lock(&syscon_list_slock); |
45 | syscon_match_node); | ||
46 | if (!dev) | ||
47 | return ERR_PTR(-EPROBE_DEFER); | ||
48 | 100 | ||
49 | syscon = dev_get_drvdata(dev); | 101 | list_for_each_entry(entry, &syscon_list, list) |
102 | if (entry->np == np) { | ||
103 | syscon = entry; | ||
104 | break; | ||
105 | } | ||
106 | |||
107 | spin_unlock(&syscon_list_slock); | ||
108 | |||
109 | if (!syscon) | ||
110 | syscon = of_syscon_register(np); | ||
111 | |||
112 | if (IS_ERR(syscon)) | ||
113 | return ERR_CAST(syscon); | ||
50 | 114 | ||
51 | return syscon->regmap; | 115 | return syscon->regmap; |
52 | } | 116 | } |
@@ -110,17 +174,6 @@ struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np, | |||
110 | } | 174 | } |
111 | EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle); | 175 | EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle); |
112 | 176 | ||
113 | static const struct of_device_id of_syscon_match[] = { | ||
114 | { .compatible = "syscon", }, | ||
115 | { }, | ||
116 | }; | ||
117 | |||
118 | static struct regmap_config syscon_regmap_config = { | ||
119 | .reg_bits = 32, | ||
120 | .val_bits = 32, | ||
121 | .reg_stride = 4, | ||
122 | }; | ||
123 | |||
124 | static int syscon_probe(struct platform_device *pdev) | 177 | static int syscon_probe(struct platform_device *pdev) |
125 | { | 178 | { |
126 | struct device *dev = &pdev->dev; | 179 | struct device *dev = &pdev->dev; |
@@ -167,7 +220,6 @@ static struct platform_driver syscon_driver = { | |||
167 | .driver = { | 220 | .driver = { |
168 | .name = "syscon", | 221 | .name = "syscon", |
169 | .owner = THIS_MODULE, | 222 | .owner = THIS_MODULE, |
170 | .of_match_table = of_syscon_match, | ||
171 | }, | 223 | }, |
172 | .probe = syscon_probe, | 224 | .probe = syscon_probe, |
173 | .id_table = syscon_ids, | 225 | .id_table = syscon_ids, |
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 9e04a7485981..439d905bb219 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c | |||
@@ -87,7 +87,7 @@ static int t7l66xb_mmc_enable(struct platform_device *mmc) | |||
87 | unsigned long flags; | 87 | unsigned long flags; |
88 | u8 dev_ctl; | 88 | u8 dev_ctl; |
89 | 89 | ||
90 | clk_enable(t7l66xb->clk32k); | 90 | clk_prepare_enable(t7l66xb->clk32k); |
91 | 91 | ||
92 | spin_lock_irqsave(&t7l66xb->lock, flags); | 92 | spin_lock_irqsave(&t7l66xb->lock, flags); |
93 | 93 | ||
@@ -118,7 +118,7 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc) | |||
118 | 118 | ||
119 | spin_unlock_irqrestore(&t7l66xb->lock, flags); | 119 | spin_unlock_irqrestore(&t7l66xb->lock, flags); |
120 | 120 | ||
121 | clk_disable(t7l66xb->clk32k); | 121 | clk_disable_unprepare(t7l66xb->clk32k); |
122 | 122 | ||
123 | return 0; | 123 | return 0; |
124 | } | 124 | } |
@@ -285,7 +285,7 @@ static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state) | |||
285 | 285 | ||
286 | if (pdata && pdata->suspend) | 286 | if (pdata && pdata->suspend) |
287 | pdata->suspend(dev); | 287 | pdata->suspend(dev); |
288 | clk_disable(t7l66xb->clk48m); | 288 | clk_disable_unprepare(t7l66xb->clk48m); |
289 | 289 | ||
290 | return 0; | 290 | return 0; |
291 | } | 291 | } |
@@ -295,7 +295,7 @@ static int t7l66xb_resume(struct platform_device *dev) | |||
295 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); | 295 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); |
296 | struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev); | 296 | struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev); |
297 | 297 | ||
298 | clk_enable(t7l66xb->clk48m); | 298 | clk_prepare_enable(t7l66xb->clk48m); |
299 | if (pdata && pdata->resume) | 299 | if (pdata && pdata->resume) |
300 | pdata->resume(dev); | 300 | pdata->resume(dev); |
301 | 301 | ||
@@ -369,7 +369,7 @@ static int t7l66xb_probe(struct platform_device *dev) | |||
369 | goto err_ioremap; | 369 | goto err_ioremap; |
370 | } | 370 | } |
371 | 371 | ||
372 | clk_enable(t7l66xb->clk48m); | 372 | clk_prepare_enable(t7l66xb->clk48m); |
373 | 373 | ||
374 | if (pdata && pdata->enable) | 374 | if (pdata && pdata->enable) |
375 | pdata->enable(dev); | 375 | pdata->enable(dev); |
@@ -414,9 +414,9 @@ static int t7l66xb_remove(struct platform_device *dev) | |||
414 | int ret; | 414 | int ret; |
415 | 415 | ||
416 | ret = pdata->disable(dev); | 416 | ret = pdata->disable(dev); |
417 | clk_disable(t7l66xb->clk48m); | 417 | clk_disable_unprepare(t7l66xb->clk48m); |
418 | clk_put(t7l66xb->clk48m); | 418 | clk_put(t7l66xb->clk48m); |
419 | clk_disable(t7l66xb->clk32k); | 419 | clk_disable_unprepare(t7l66xb->clk32k); |
420 | clk_put(t7l66xb->clk32k); | 420 | clk_put(t7l66xb->clk32k); |
421 | t7l66xb_detach_irq(dev); | 421 | t7l66xb_detach_irq(dev); |
422 | iounmap(t7l66xb->scr); | 422 | iounmap(t7l66xb->scr); |
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index 0072e668c208..aacb3720065c 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c | |||
@@ -241,10 +241,8 @@ static struct irq_domain_ops tc3589x_irq_ops = { | |||
241 | 241 | ||
242 | static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np) | 242 | static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np) |
243 | { | 243 | { |
244 | int base = tc3589x->irq_base; | ||
245 | |||
246 | tc3589x->domain = irq_domain_add_simple( | 244 | tc3589x->domain = irq_domain_add_simple( |
247 | np, TC3589x_NR_INTERNAL_IRQS, base, | 245 | np, TC3589x_NR_INTERNAL_IRQS, 0, |
248 | &tc3589x_irq_ops, tc3589x); | 246 | &tc3589x_irq_ops, tc3589x); |
249 | 247 | ||
250 | if (!tc3589x->domain) { | 248 | if (!tc3589x->domain) { |
@@ -298,7 +296,7 @@ static int tc3589x_device_init(struct tc3589x *tc3589x) | |||
298 | if (blocks & TC3589x_BLOCK_GPIO) { | 296 | if (blocks & TC3589x_BLOCK_GPIO) { |
299 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, | 297 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, |
300 | ARRAY_SIZE(tc3589x_dev_gpio), NULL, | 298 | ARRAY_SIZE(tc3589x_dev_gpio), NULL, |
301 | tc3589x->irq_base, tc3589x->domain); | 299 | 0, tc3589x->domain); |
302 | if (ret) { | 300 | if (ret) { |
303 | dev_err(tc3589x->dev, "failed to add gpio child\n"); | 301 | dev_err(tc3589x->dev, "failed to add gpio child\n"); |
304 | return ret; | 302 | return ret; |
@@ -309,7 +307,7 @@ static int tc3589x_device_init(struct tc3589x *tc3589x) | |||
309 | if (blocks & TC3589x_BLOCK_KEYPAD) { | 307 | if (blocks & TC3589x_BLOCK_KEYPAD) { |
310 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, | 308 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, |
311 | ARRAY_SIZE(tc3589x_dev_keypad), NULL, | 309 | ARRAY_SIZE(tc3589x_dev_keypad), NULL, |
312 | tc3589x->irq_base, tc3589x->domain); | 310 | 0, tc3589x->domain); |
313 | if (ret) { | 311 | if (ret) { |
314 | dev_err(tc3589x->dev, "failed to keypad child\n"); | 312 | dev_err(tc3589x->dev, "failed to keypad child\n"); |
315 | return ret; | 313 | return ret; |
@@ -404,7 +402,6 @@ static int tc3589x_probe(struct i2c_client *i2c, | |||
404 | tc3589x->dev = &i2c->dev; | 402 | tc3589x->dev = &i2c->dev; |
405 | tc3589x->i2c = i2c; | 403 | tc3589x->i2c = i2c; |
406 | tc3589x->pdata = pdata; | 404 | tc3589x->pdata = pdata; |
407 | tc3589x->irq_base = pdata->irq_base; | ||
408 | 405 | ||
409 | switch (version) { | 406 | switch (version) { |
410 | case TC3589X_TC35893: | 407 | case TC3589X_TC35893: |
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index e71f88000ae5..85fab3729102 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c | |||
@@ -52,7 +52,7 @@ static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state) | |||
52 | 52 | ||
53 | if (pdata && pdata->suspend) | 53 | if (pdata && pdata->suspend) |
54 | pdata->suspend(dev); | 54 | pdata->suspend(dev); |
55 | clk_disable(tc6387xb->clk32k); | 55 | clk_disable_unprepare(tc6387xb->clk32k); |
56 | 56 | ||
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
@@ -62,7 +62,7 @@ static int tc6387xb_resume(struct platform_device *dev) | |||
62 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); | 62 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); |
63 | struct tc6387xb_platform_data *pdata = dev_get_platdata(&dev->dev); | 63 | struct tc6387xb_platform_data *pdata = dev_get_platdata(&dev->dev); |
64 | 64 | ||
65 | clk_enable(tc6387xb->clk32k); | 65 | clk_prepare_enable(tc6387xb->clk32k); |
66 | if (pdata && pdata->resume) | 66 | if (pdata && pdata->resume) |
67 | pdata->resume(dev); | 67 | pdata->resume(dev); |
68 | 68 | ||
@@ -100,7 +100,7 @@ static int tc6387xb_mmc_enable(struct platform_device *mmc) | |||
100 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | 100 | struct platform_device *dev = to_platform_device(mmc->dev.parent); |
101 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); | 101 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); |
102 | 102 | ||
103 | clk_enable(tc6387xb->clk32k); | 103 | clk_prepare_enable(tc6387xb->clk32k); |
104 | 104 | ||
105 | tmio_core_mmc_enable(tc6387xb->scr + 0x200, 0, | 105 | tmio_core_mmc_enable(tc6387xb->scr + 0x200, 0, |
106 | tc6387xb_mmc_resources[0].start & 0xfffe); | 106 | tc6387xb_mmc_resources[0].start & 0xfffe); |
@@ -113,7 +113,7 @@ static int tc6387xb_mmc_disable(struct platform_device *mmc) | |||
113 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | 113 | struct platform_device *dev = to_platform_device(mmc->dev.parent); |
114 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); | 114 | struct tc6387xb *tc6387xb = platform_get_drvdata(dev); |
115 | 115 | ||
116 | clk_disable(tc6387xb->clk32k); | 116 | clk_disable_unprepare(tc6387xb->clk32k); |
117 | 117 | ||
118 | return 0; | 118 | return 0; |
119 | } | 119 | } |
@@ -214,7 +214,7 @@ static int tc6387xb_remove(struct platform_device *dev) | |||
214 | mfd_remove_devices(&dev->dev); | 214 | mfd_remove_devices(&dev->dev); |
215 | iounmap(tc6387xb->scr); | 215 | iounmap(tc6387xb->scr); |
216 | release_resource(&tc6387xb->rscr); | 216 | release_resource(&tc6387xb->rscr); |
217 | clk_disable(tc6387xb->clk32k); | 217 | clk_disable_unprepare(tc6387xb->clk32k); |
218 | clk_put(tc6387xb->clk32k); | 218 | clk_put(tc6387xb->clk32k); |
219 | kfree(tc6387xb); | 219 | kfree(tc6387xb); |
220 | 220 | ||
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 4fac16bcd732..d35f11fbeab7 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
@@ -263,6 +263,17 @@ static int tc6393xb_ohci_disable(struct platform_device *dev) | |||
263 | return 0; | 263 | return 0; |
264 | } | 264 | } |
265 | 265 | ||
266 | static int tc6393xb_ohci_suspend(struct platform_device *dev) | ||
267 | { | ||
268 | struct tc6393xb_platform_data *tcpd = dev_get_platdata(dev->dev.parent); | ||
269 | |||
270 | /* We can't properly store/restore OHCI state, so fail here */ | ||
271 | if (tcpd->resume_restore) | ||
272 | return -EBUSY; | ||
273 | |||
274 | return tc6393xb_ohci_disable(dev); | ||
275 | } | ||
276 | |||
266 | static int tc6393xb_fb_enable(struct platform_device *dev) | 277 | static int tc6393xb_fb_enable(struct platform_device *dev) |
267 | { | 278 | { |
268 | struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); | 279 | struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); |
@@ -403,7 +414,7 @@ static struct mfd_cell tc6393xb_cells[] = { | |||
403 | .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources), | 414 | .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources), |
404 | .resources = tc6393xb_ohci_resources, | 415 | .resources = tc6393xb_ohci_resources, |
405 | .enable = tc6393xb_ohci_enable, | 416 | .enable = tc6393xb_ohci_enable, |
406 | .suspend = tc6393xb_ohci_disable, | 417 | .suspend = tc6393xb_ohci_suspend, |
407 | .resume = tc6393xb_ohci_enable, | 418 | .resume = tc6393xb_ohci_enable, |
408 | .disable = tc6393xb_ohci_disable, | 419 | .disable = tc6393xb_ohci_disable, |
409 | }, | 420 | }, |
@@ -654,7 +665,7 @@ static int tc6393xb_probe(struct platform_device *dev) | |||
654 | goto err_ioremap; | 665 | goto err_ioremap; |
655 | } | 666 | } |
656 | 667 | ||
657 | ret = clk_enable(tc6393xb->clk); | 668 | ret = clk_prepare_enable(tc6393xb->clk); |
658 | if (ret) | 669 | if (ret) |
659 | goto err_clk_enable; | 670 | goto err_clk_enable; |
660 | 671 | ||
@@ -717,7 +728,7 @@ err_gpio_add: | |||
717 | gpiochip_remove(&tc6393xb->gpio); | 728 | gpiochip_remove(&tc6393xb->gpio); |
718 | tcpd->disable(dev); | 729 | tcpd->disable(dev); |
719 | err_enable: | 730 | err_enable: |
720 | clk_disable(tc6393xb->clk); | 731 | clk_disable_unprepare(tc6393xb->clk); |
721 | err_clk_enable: | 732 | err_clk_enable: |
722 | iounmap(tc6393xb->scr); | 733 | iounmap(tc6393xb->scr); |
723 | err_ioremap: | 734 | err_ioremap: |
@@ -748,7 +759,7 @@ static int tc6393xb_remove(struct platform_device *dev) | |||
748 | gpiochip_remove(&tc6393xb->gpio); | 759 | gpiochip_remove(&tc6393xb->gpio); |
749 | 760 | ||
750 | ret = tcpd->disable(dev); | 761 | ret = tcpd->disable(dev); |
751 | clk_disable(tc6393xb->clk); | 762 | clk_disable_unprepare(tc6393xb->clk); |
752 | iounmap(tc6393xb->scr); | 763 | iounmap(tc6393xb->scr); |
753 | release_resource(&tc6393xb->rscr); | 764 | release_resource(&tc6393xb->rscr); |
754 | clk_put(tc6393xb->clk); | 765 | clk_put(tc6393xb->clk); |
@@ -776,7 +787,7 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state) | |||
776 | ioread8(tc6393xb->scr + SCR_GPI_BCR(i)); | 787 | ioread8(tc6393xb->scr + SCR_GPI_BCR(i)); |
777 | } | 788 | } |
778 | ret = tcpd->suspend(dev); | 789 | ret = tcpd->suspend(dev); |
779 | clk_disable(tc6393xb->clk); | 790 | clk_disable_unprepare(tc6393xb->clk); |
780 | 791 | ||
781 | return ret; | 792 | return ret; |
782 | } | 793 | } |
@@ -788,7 +799,7 @@ static int tc6393xb_resume(struct platform_device *dev) | |||
788 | int ret; | 799 | int ret; |
789 | int i; | 800 | int i; |
790 | 801 | ||
791 | clk_enable(tc6393xb->clk); | 802 | clk_prepare_enable(tc6393xb->clk); |
792 | 803 | ||
793 | ret = tcpd->resume(dev); | 804 | ret = tcpd->resume(dev); |
794 | if (ret) | 805 | if (ret) |
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index 1c3e6e2efe41..14b62e11aff4 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c | |||
@@ -76,58 +76,58 @@ static struct mfd_cell tps65090s[] = { | |||
76 | static const struct regmap_irq tps65090_irqs[] = { | 76 | static const struct regmap_irq tps65090_irqs[] = { |
77 | /* INT1 IRQs*/ | 77 | /* INT1 IRQs*/ |
78 | [TPS65090_IRQ_VAC_STATUS_CHANGE] = { | 78 | [TPS65090_IRQ_VAC_STATUS_CHANGE] = { |
79 | .mask = TPS65090_INT1_MASK_VAC_STATUS_CHANGE, | 79 | .mask = TPS65090_INT1_MASK_VAC_STATUS_CHANGE, |
80 | }, | 80 | }, |
81 | [TPS65090_IRQ_VSYS_STATUS_CHANGE] = { | 81 | [TPS65090_IRQ_VSYS_STATUS_CHANGE] = { |
82 | .mask = TPS65090_INT1_MASK_VSYS_STATUS_CHANGE, | 82 | .mask = TPS65090_INT1_MASK_VSYS_STATUS_CHANGE, |
83 | }, | 83 | }, |
84 | [TPS65090_IRQ_BAT_STATUS_CHANGE] = { | 84 | [TPS65090_IRQ_BAT_STATUS_CHANGE] = { |
85 | .mask = TPS65090_INT1_MASK_BAT_STATUS_CHANGE, | 85 | .mask = TPS65090_INT1_MASK_BAT_STATUS_CHANGE, |
86 | }, | 86 | }, |
87 | [TPS65090_IRQ_CHARGING_STATUS_CHANGE] = { | 87 | [TPS65090_IRQ_CHARGING_STATUS_CHANGE] = { |
88 | .mask = TPS65090_INT1_MASK_CHARGING_STATUS_CHANGE, | 88 | .mask = TPS65090_INT1_MASK_CHARGING_STATUS_CHANGE, |
89 | }, | 89 | }, |
90 | [TPS65090_IRQ_CHARGING_COMPLETE] = { | 90 | [TPS65090_IRQ_CHARGING_COMPLETE] = { |
91 | .mask = TPS65090_INT1_MASK_CHARGING_COMPLETE, | 91 | .mask = TPS65090_INT1_MASK_CHARGING_COMPLETE, |
92 | }, | 92 | }, |
93 | [TPS65090_IRQ_OVERLOAD_DCDC1] = { | 93 | [TPS65090_IRQ_OVERLOAD_DCDC1] = { |
94 | .mask = TPS65090_INT1_MASK_OVERLOAD_DCDC1, | 94 | .mask = TPS65090_INT1_MASK_OVERLOAD_DCDC1, |
95 | }, | 95 | }, |
96 | [TPS65090_IRQ_OVERLOAD_DCDC2] = { | 96 | [TPS65090_IRQ_OVERLOAD_DCDC2] = { |
97 | .mask = TPS65090_INT1_MASK_OVERLOAD_DCDC2, | 97 | .mask = TPS65090_INT1_MASK_OVERLOAD_DCDC2, |
98 | }, | 98 | }, |
99 | /* INT2 IRQs*/ | 99 | /* INT2 IRQs*/ |
100 | [TPS65090_IRQ_OVERLOAD_DCDC3] = { | 100 | [TPS65090_IRQ_OVERLOAD_DCDC3] = { |
101 | .reg_offset = 1, | 101 | .reg_offset = 1, |
102 | .mask = TPS65090_INT2_MASK_OVERLOAD_DCDC3, | 102 | .mask = TPS65090_INT2_MASK_OVERLOAD_DCDC3, |
103 | }, | 103 | }, |
104 | [TPS65090_IRQ_OVERLOAD_FET1] = { | 104 | [TPS65090_IRQ_OVERLOAD_FET1] = { |
105 | .reg_offset = 1, | 105 | .reg_offset = 1, |
106 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET1, | 106 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET1, |
107 | }, | 107 | }, |
108 | [TPS65090_IRQ_OVERLOAD_FET2] = { | 108 | [TPS65090_IRQ_OVERLOAD_FET2] = { |
109 | .reg_offset = 1, | 109 | .reg_offset = 1, |
110 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET2, | 110 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET2, |
111 | }, | 111 | }, |
112 | [TPS65090_IRQ_OVERLOAD_FET3] = { | 112 | [TPS65090_IRQ_OVERLOAD_FET3] = { |
113 | .reg_offset = 1, | 113 | .reg_offset = 1, |
114 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET3, | 114 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET3, |
115 | }, | 115 | }, |
116 | [TPS65090_IRQ_OVERLOAD_FET4] = { | 116 | [TPS65090_IRQ_OVERLOAD_FET4] = { |
117 | .reg_offset = 1, | 117 | .reg_offset = 1, |
118 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET4, | 118 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET4, |
119 | }, | 119 | }, |
120 | [TPS65090_IRQ_OVERLOAD_FET5] = { | 120 | [TPS65090_IRQ_OVERLOAD_FET5] = { |
121 | .reg_offset = 1, | 121 | .reg_offset = 1, |
122 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET5, | 122 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET5, |
123 | }, | 123 | }, |
124 | [TPS65090_IRQ_OVERLOAD_FET6] = { | 124 | [TPS65090_IRQ_OVERLOAD_FET6] = { |
125 | .reg_offset = 1, | 125 | .reg_offset = 1, |
126 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET6, | 126 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET6, |
127 | }, | 127 | }, |
128 | [TPS65090_IRQ_OVERLOAD_FET7] = { | 128 | [TPS65090_IRQ_OVERLOAD_FET7] = { |
129 | .reg_offset = 1, | 129 | .reg_offset = 1, |
130 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET7, | 130 | .mask = TPS65090_INT2_MASK_OVERLOAD_FET7, |
131 | }, | 131 | }, |
132 | }; | 132 | }; |
133 | 133 | ||
@@ -176,7 +176,7 @@ MODULE_DEVICE_TABLE(of, tps65090_of_match); | |||
176 | #endif | 176 | #endif |
177 | 177 | ||
178 | static int tps65090_i2c_probe(struct i2c_client *client, | 178 | static int tps65090_i2c_probe(struct i2c_client *client, |
179 | const struct i2c_device_id *id) | 179 | const struct i2c_device_id *id) |
180 | { | 180 | { |
181 | struct tps65090_platform_data *pdata = dev_get_platdata(&client->dev); | 181 | struct tps65090_platform_data *pdata = dev_get_platdata(&client->dev); |
182 | int irq_base = 0; | 182 | int irq_base = 0; |
@@ -210,11 +210,11 @@ static int tps65090_i2c_probe(struct i2c_client *client, | |||
210 | 210 | ||
211 | if (client->irq) { | 211 | if (client->irq) { |
212 | ret = regmap_add_irq_chip(tps65090->rmap, client->irq, | 212 | ret = regmap_add_irq_chip(tps65090->rmap, client->irq, |
213 | IRQF_ONESHOT | IRQF_TRIGGER_LOW, irq_base, | 213 | IRQF_ONESHOT | IRQF_TRIGGER_LOW, irq_base, |
214 | &tps65090_irq_chip, &tps65090->irq_data); | 214 | &tps65090_irq_chip, &tps65090->irq_data); |
215 | if (ret) { | 215 | if (ret) { |
216 | dev_err(&client->dev, | 216 | dev_err(&client->dev, |
217 | "IRQ init failed with err: %d\n", ret); | 217 | "IRQ init failed with err: %d\n", ret); |
218 | return ret; | 218 | return ret; |
219 | } | 219 | } |
220 | } else { | 220 | } else { |
@@ -223,8 +223,8 @@ static int tps65090_i2c_probe(struct i2c_client *client, | |||
223 | } | 223 | } |
224 | 224 | ||
225 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, | 225 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, |
226 | ARRAY_SIZE(tps65090s), NULL, | 226 | ARRAY_SIZE(tps65090s), NULL, |
227 | 0, regmap_irq_get_domain(tps65090->irq_data)); | 227 | 0, regmap_irq_get_domain(tps65090->irq_data)); |
228 | if (ret) { | 228 | if (ret) { |
229 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", | 229 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", |
230 | ret); | 230 | ret); |
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index a8ee52c95f2f..80a919a8ca97 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c | |||
@@ -33,9 +33,11 @@ | |||
33 | static const struct mfd_cell tps65217s[] = { | 33 | static const struct mfd_cell tps65217s[] = { |
34 | { | 34 | { |
35 | .name = "tps65217-pmic", | 35 | .name = "tps65217-pmic", |
36 | .of_compatible = "ti,tps65217-pmic", | ||
36 | }, | 37 | }, |
37 | { | 38 | { |
38 | .name = "tps65217-bl", | 39 | .name = "tps65217-bl", |
40 | .of_compatible = "ti,tps65217-bl", | ||
39 | }, | 41 | }, |
40 | }; | 42 | }; |
41 | 43 | ||
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index 50f9091bcd38..7d63e324e6a8 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c | |||
@@ -831,6 +831,9 @@ static struct twl4030_power_data osc_off_idle = { | |||
831 | 831 | ||
832 | static struct of_device_id twl4030_power_of_match[] = { | 832 | static struct of_device_id twl4030_power_of_match[] = { |
833 | { | 833 | { |
834 | .compatible = "ti,twl4030-power", | ||
835 | }, | ||
836 | { | ||
834 | .compatible = "ti,twl4030-power-reset", | 837 | .compatible = "ti,twl4030-power-reset", |
835 | .data = &omap3_reset, | 838 | .data = &omap3_reset, |
836 | }, | 839 | }, |
diff --git a/drivers/mfd/viperboard.c b/drivers/mfd/viperboard.c index 3c2b8f9e3c84..e6b3c70aeb22 100644 --- a/drivers/mfd/viperboard.c +++ b/drivers/mfd/viperboard.c | |||
@@ -93,9 +93,8 @@ static int vprbrd_probe(struct usb_interface *interface, | |||
93 | version >> 8, version & 0xff, | 93 | version >> 8, version & 0xff, |
94 | vb->usb_dev->bus->busnum, vb->usb_dev->devnum); | 94 | vb->usb_dev->bus->busnum, vb->usb_dev->devnum); |
95 | 95 | ||
96 | ret = mfd_add_devices(&interface->dev, PLATFORM_DEVID_AUTO, | 96 | ret = mfd_add_hotplug_devices(&interface->dev, vprbrd_devs, |
97 | vprbrd_devs, ARRAY_SIZE(vprbrd_devs), NULL, 0, | 97 | ARRAY_SIZE(vprbrd_devs)); |
98 | NULL); | ||
99 | if (ret != 0) { | 98 | if (ret != 0) { |
100 | dev_err(&interface->dev, "Failed to add mfd devices to core."); | 99 | dev_err(&interface->dev, "Failed to add mfd devices to core."); |
101 | goto error; | 100 | goto error; |
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index d6f35bbf795b..b326a82017ee 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c | |||
@@ -336,8 +336,6 @@ static const struct reg_default wm5102_reg_default[] = { | |||
336 | { 0x00000218, 0x01A6 }, /* R536 - Mic Bias Ctrl 1 */ | 336 | { 0x00000218, 0x01A6 }, /* R536 - Mic Bias Ctrl 1 */ |
337 | { 0x00000219, 0x01A6 }, /* R537 - Mic Bias Ctrl 2 */ | 337 | { 0x00000219, 0x01A6 }, /* R537 - Mic Bias Ctrl 2 */ |
338 | { 0x0000021A, 0x01A6 }, /* R538 - Mic Bias Ctrl 3 */ | 338 | { 0x0000021A, 0x01A6 }, /* R538 - Mic Bias Ctrl 3 */ |
339 | { 0x00000225, 0x0400 }, /* R549 - HP Ctrl 1L */ | ||
340 | { 0x00000226, 0x0400 }, /* R550 - HP Ctrl 1R */ | ||
341 | { 0x00000293, 0x0000 }, /* R659 - Accessory Detect Mode 1 */ | 339 | { 0x00000293, 0x0000 }, /* R659 - Accessory Detect Mode 1 */ |
342 | { 0x0000029B, 0x0020 }, /* R667 - Headphone Detect 1 */ | 340 | { 0x0000029B, 0x0020 }, /* R667 - Headphone Detect 1 */ |
343 | { 0x0000029C, 0x0000 }, /* R668 - Headphone Detect 2 */ | 341 | { 0x0000029C, 0x0000 }, /* R668 - Headphone Detect 2 */ |
@@ -1112,6 +1110,8 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) | |||
1112 | case ARIZONA_MIC_BIAS_CTRL_1: | 1110 | case ARIZONA_MIC_BIAS_CTRL_1: |
1113 | case ARIZONA_MIC_BIAS_CTRL_2: | 1111 | case ARIZONA_MIC_BIAS_CTRL_2: |
1114 | case ARIZONA_MIC_BIAS_CTRL_3: | 1112 | case ARIZONA_MIC_BIAS_CTRL_3: |
1113 | case ARIZONA_HP_CTRL_1L: | ||
1114 | case ARIZONA_HP_CTRL_1R: | ||
1115 | case ARIZONA_ACCESSORY_DETECT_MODE_1: | 1115 | case ARIZONA_ACCESSORY_DETECT_MODE_1: |
1116 | case ARIZONA_HEADPHONE_DETECT_1: | 1116 | case ARIZONA_HEADPHONE_DETECT_1: |
1117 | case ARIZONA_HEADPHONE_DETECT_2: | 1117 | case ARIZONA_HEADPHONE_DETECT_2: |
@@ -1949,6 +1949,8 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg) | |||
1949 | case ARIZONA_DSP1_SCRATCH_1: | 1949 | case ARIZONA_DSP1_SCRATCH_1: |
1950 | case ARIZONA_DSP1_SCRATCH_2: | 1950 | case ARIZONA_DSP1_SCRATCH_2: |
1951 | case ARIZONA_DSP1_SCRATCH_3: | 1951 | case ARIZONA_DSP1_SCRATCH_3: |
1952 | case ARIZONA_HP_CTRL_1L: | ||
1953 | case ARIZONA_HP_CTRL_1R: | ||
1952 | case ARIZONA_HEADPHONE_DETECT_2: | 1954 | case ARIZONA_HEADPHONE_DETECT_2: |
1953 | case ARIZONA_HP_DACVAL: | 1955 | case ARIZONA_HP_DACVAL: |
1954 | case ARIZONA_MIC_DETECT_3: | 1956 | case ARIZONA_MIC_DETECT_3: |
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c index 4642b5b816a0..12cad94b4035 100644 --- a/drivers/mfd/wm5110-tables.c +++ b/drivers/mfd/wm5110-tables.c | |||
@@ -895,8 +895,16 @@ static const struct reg_default wm5110_reg_default[] = { | |||
895 | { 0x00000548, 0x1818 }, /* R1352 - AIF2 Frame Ctrl 2 */ | 895 | { 0x00000548, 0x1818 }, /* R1352 - AIF2 Frame Ctrl 2 */ |
896 | { 0x00000549, 0x0000 }, /* R1353 - AIF2 Frame Ctrl 3 */ | 896 | { 0x00000549, 0x0000 }, /* R1353 - AIF2 Frame Ctrl 3 */ |
897 | { 0x0000054A, 0x0001 }, /* R1354 - AIF2 Frame Ctrl 4 */ | 897 | { 0x0000054A, 0x0001 }, /* R1354 - AIF2 Frame Ctrl 4 */ |
898 | { 0x0000054B, 0x0002 }, /* R1355 - AIF2 Frame Ctrl 5 */ | ||
899 | { 0x0000054C, 0x0003 }, /* R1356 - AIF2 Frame Ctrl 6 */ | ||
900 | { 0x0000054D, 0x0004 }, /* R1357 - AIF2 Frame Ctrl 7 */ | ||
901 | { 0x0000054E, 0x0005 }, /* R1358 - AIF2 Frame Ctrl 8 */ | ||
898 | { 0x00000551, 0x0000 }, /* R1361 - AIF2 Frame Ctrl 11 */ | 902 | { 0x00000551, 0x0000 }, /* R1361 - AIF2 Frame Ctrl 11 */ |
899 | { 0x00000552, 0x0001 }, /* R1362 - AIF2 Frame Ctrl 12 */ | 903 | { 0x00000552, 0x0001 }, /* R1362 - AIF2 Frame Ctrl 12 */ |
904 | { 0x00000553, 0x0002 }, /* R1363 - AIF2 Frame Ctrl 13 */ | ||
905 | { 0x00000554, 0x0003 }, /* R1364 - AIF2 Frame Ctrl 14 */ | ||
906 | { 0x00000555, 0x0004 }, /* R1365 - AIF2 Frame Ctrl 15 */ | ||
907 | { 0x00000556, 0x0005 }, /* R1366 - AIF2 Frame Ctrl 16 */ | ||
900 | { 0x00000559, 0x0000 }, /* R1369 - AIF2 Tx Enables */ | 908 | { 0x00000559, 0x0000 }, /* R1369 - AIF2 Tx Enables */ |
901 | { 0x0000055A, 0x0000 }, /* R1370 - AIF2 Rx Enables */ | 909 | { 0x0000055A, 0x0000 }, /* R1370 - AIF2 Rx Enables */ |
902 | { 0x00000580, 0x000C }, /* R1408 - AIF3 BCLK Ctrl */ | 910 | { 0x00000580, 0x000C }, /* R1408 - AIF3 BCLK Ctrl */ |
@@ -1790,6 +1798,8 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) | |||
1790 | case ARIZONA_MIC_BIAS_CTRL_1: | 1798 | case ARIZONA_MIC_BIAS_CTRL_1: |
1791 | case ARIZONA_MIC_BIAS_CTRL_2: | 1799 | case ARIZONA_MIC_BIAS_CTRL_2: |
1792 | case ARIZONA_MIC_BIAS_CTRL_3: | 1800 | case ARIZONA_MIC_BIAS_CTRL_3: |
1801 | case ARIZONA_HP_CTRL_1L: | ||
1802 | case ARIZONA_HP_CTRL_1R: | ||
1793 | case ARIZONA_ACCESSORY_DETECT_MODE_1: | 1803 | case ARIZONA_ACCESSORY_DETECT_MODE_1: |
1794 | case ARIZONA_HEADPHONE_DETECT_1: | 1804 | case ARIZONA_HEADPHONE_DETECT_1: |
1795 | case ARIZONA_HEADPHONE_DETECT_2: | 1805 | case ARIZONA_HEADPHONE_DETECT_2: |
@@ -1934,8 +1944,16 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) | |||
1934 | case ARIZONA_AIF2_FRAME_CTRL_2: | 1944 | case ARIZONA_AIF2_FRAME_CTRL_2: |
1935 | case ARIZONA_AIF2_FRAME_CTRL_3: | 1945 | case ARIZONA_AIF2_FRAME_CTRL_3: |
1936 | case ARIZONA_AIF2_FRAME_CTRL_4: | 1946 | case ARIZONA_AIF2_FRAME_CTRL_4: |
1947 | case ARIZONA_AIF2_FRAME_CTRL_5: | ||
1948 | case ARIZONA_AIF2_FRAME_CTRL_6: | ||
1949 | case ARIZONA_AIF2_FRAME_CTRL_7: | ||
1950 | case ARIZONA_AIF2_FRAME_CTRL_8: | ||
1937 | case ARIZONA_AIF2_FRAME_CTRL_11: | 1951 | case ARIZONA_AIF2_FRAME_CTRL_11: |
1938 | case ARIZONA_AIF2_FRAME_CTRL_12: | 1952 | case ARIZONA_AIF2_FRAME_CTRL_12: |
1953 | case ARIZONA_AIF2_FRAME_CTRL_13: | ||
1954 | case ARIZONA_AIF2_FRAME_CTRL_14: | ||
1955 | case ARIZONA_AIF2_FRAME_CTRL_15: | ||
1956 | case ARIZONA_AIF2_FRAME_CTRL_16: | ||
1939 | case ARIZONA_AIF2_TX_ENABLES: | 1957 | case ARIZONA_AIF2_TX_ENABLES: |
1940 | case ARIZONA_AIF2_RX_ENABLES: | 1958 | case ARIZONA_AIF2_RX_ENABLES: |
1941 | case ARIZONA_AIF3_BCLK_CTRL: | 1959 | case ARIZONA_AIF3_BCLK_CTRL: |
@@ -2825,6 +2843,8 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg) | |||
2825 | case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS: | 2843 | case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS: |
2826 | case ARIZONA_ASYNC_SAMPLE_RATE_2_STATUS: | 2844 | case ARIZONA_ASYNC_SAMPLE_RATE_2_STATUS: |
2827 | case ARIZONA_MIC_DETECT_3: | 2845 | case ARIZONA_MIC_DETECT_3: |
2846 | case ARIZONA_HP_CTRL_1L: | ||
2847 | case ARIZONA_HP_CTRL_1R: | ||
2828 | case ARIZONA_HEADPHONE_DETECT_2: | 2848 | case ARIZONA_HEADPHONE_DETECT_2: |
2829 | case ARIZONA_INPUT_ENABLES_STATUS: | 2849 | case ARIZONA_INPUT_ENABLES_STATUS: |
2830 | case ARIZONA_OUTPUT_STATUS_1: | 2850 | case ARIZONA_OUTPUT_STATUS_1: |
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index 4ab527f5c53b..f5124a8acad8 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c | |||
@@ -308,7 +308,7 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, | |||
308 | goto err; | 308 | goto err; |
309 | } | 309 | } |
310 | 310 | ||
311 | mode = id2 & WM8350_CONF_STS_MASK >> 10; | 311 | mode = (id2 & WM8350_CONF_STS_MASK) >> 10; |
312 | cust_id = id2 & WM8350_CUST_ID_MASK; | 312 | cust_id = id2 & WM8350_CUST_ID_MASK; |
313 | chip_rev = (id2 & WM8350_CHIP_REV_MASK) >> 12; | 313 | chip_rev = (id2 & WM8350_CHIP_REV_MASK) >> 12; |
314 | dev_info(wm8350->dev, | 314 | dev_info(wm8350->dev, |
diff --git a/drivers/mfd/wm8997-tables.c b/drivers/mfd/wm8997-tables.c index 510da3b52324..c0c25d75aacc 100644 --- a/drivers/mfd/wm8997-tables.c +++ b/drivers/mfd/wm8997-tables.c | |||
@@ -670,6 +670,7 @@ static const struct reg_default wm8997_reg_default[] = { | |||
670 | { 0x00000C23, 0x0000 }, /* R3107 - Misc Pad Ctrl 4 */ | 670 | { 0x00000C23, 0x0000 }, /* R3107 - Misc Pad Ctrl 4 */ |
671 | { 0x00000C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 5 */ | 671 | { 0x00000C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 5 */ |
672 | { 0x00000D08, 0xFFFF }, /* R3336 - Interrupt Status 1 Mask */ | 672 | { 0x00000D08, 0xFFFF }, /* R3336 - Interrupt Status 1 Mask */ |
673 | { 0x00000D09, 0xFFFF }, /* R3337 - Interrupt Status 2 Mask */ | ||
673 | { 0x00000D0A, 0xFFFF }, /* R3338 - Interrupt Status 3 Mask */ | 674 | { 0x00000D0A, 0xFFFF }, /* R3338 - Interrupt Status 3 Mask */ |
674 | { 0x00000D0B, 0xFFFF }, /* R3339 - Interrupt Status 4 Mask */ | 675 | { 0x00000D0B, 0xFFFF }, /* R3339 - Interrupt Status 4 Mask */ |
675 | { 0x00000D0C, 0xFEFF }, /* R3340 - Interrupt Status 5 Mask */ | 676 | { 0x00000D0C, 0xFEFF }, /* R3340 - Interrupt Status 5 Mask */ |
@@ -886,6 +887,8 @@ static bool wm8997_readable_register(struct device *dev, unsigned int reg) | |||
886 | case ARIZONA_MIC_BIAS_CTRL_1: | 887 | case ARIZONA_MIC_BIAS_CTRL_1: |
887 | case ARIZONA_MIC_BIAS_CTRL_2: | 888 | case ARIZONA_MIC_BIAS_CTRL_2: |
888 | case ARIZONA_MIC_BIAS_CTRL_3: | 889 | case ARIZONA_MIC_BIAS_CTRL_3: |
890 | case ARIZONA_HP_CTRL_1L: | ||
891 | case ARIZONA_HP_CTRL_1R: | ||
889 | case ARIZONA_ACCESSORY_DETECT_MODE_1: | 892 | case ARIZONA_ACCESSORY_DETECT_MODE_1: |
890 | case ARIZONA_HEADPHONE_DETECT_1: | 893 | case ARIZONA_HEADPHONE_DETECT_1: |
891 | case ARIZONA_HEADPHONE_DETECT_2: | 894 | case ARIZONA_HEADPHONE_DETECT_2: |
@@ -1328,6 +1331,7 @@ static bool wm8997_readable_register(struct device *dev, unsigned int reg) | |||
1328 | case ARIZONA_INTERRUPT_STATUS_4: | 1331 | case ARIZONA_INTERRUPT_STATUS_4: |
1329 | case ARIZONA_INTERRUPT_STATUS_5: | 1332 | case ARIZONA_INTERRUPT_STATUS_5: |
1330 | case ARIZONA_INTERRUPT_STATUS_1_MASK: | 1333 | case ARIZONA_INTERRUPT_STATUS_1_MASK: |
1334 | case ARIZONA_INTERRUPT_STATUS_2_MASK: | ||
1331 | case ARIZONA_INTERRUPT_STATUS_3_MASK: | 1335 | case ARIZONA_INTERRUPT_STATUS_3_MASK: |
1332 | case ARIZONA_INTERRUPT_STATUS_4_MASK: | 1336 | case ARIZONA_INTERRUPT_STATUS_4_MASK: |
1333 | case ARIZONA_INTERRUPT_STATUS_5_MASK: | 1337 | case ARIZONA_INTERRUPT_STATUS_5_MASK: |
@@ -1477,6 +1481,8 @@ static bool wm8997_volatile_register(struct device *dev, unsigned int reg) | |||
1477 | case ARIZONA_SAMPLE_RATE_3_STATUS: | 1481 | case ARIZONA_SAMPLE_RATE_3_STATUS: |
1478 | case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS: | 1482 | case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS: |
1479 | case ARIZONA_MIC_DETECT_3: | 1483 | case ARIZONA_MIC_DETECT_3: |
1484 | case ARIZONA_HP_CTRL_1L: | ||
1485 | case ARIZONA_HP_CTRL_1R: | ||
1480 | case ARIZONA_HEADPHONE_DETECT_2: | 1486 | case ARIZONA_HEADPHONE_DETECT_2: |
1481 | case ARIZONA_INPUT_ENABLES_STATUS: | 1487 | case ARIZONA_INPUT_ENABLES_STATUS: |
1482 | case ARIZONA_OUTPUT_STATUS_1: | 1488 | case ARIZONA_OUTPUT_STATUS_1: |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 1fa4c80ff886..4409d79ed650 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -78,13 +78,16 @@ static int perdev_minors = CONFIG_MMC_BLOCK_MINORS; | |||
78 | 78 | ||
79 | /* | 79 | /* |
80 | * We've only got one major, so number of mmcblk devices is | 80 | * We've only got one major, so number of mmcblk devices is |
81 | * limited to 256 / number of minors per device. | 81 | * limited to (1 << 20) / number of minors per device. It is also |
82 | * currently limited by the size of the static bitmaps below. | ||
82 | */ | 83 | */ |
83 | static int max_devices; | 84 | static int max_devices; |
84 | 85 | ||
85 | /* 256 minors, so at most 256 separate devices */ | 86 | #define MAX_DEVICES 256 |
86 | static DECLARE_BITMAP(dev_use, 256); | 87 | |
87 | static DECLARE_BITMAP(name_use, 256); | 88 | /* TODO: Replace these with struct ida */ |
89 | static DECLARE_BITMAP(dev_use, MAX_DEVICES); | ||
90 | static DECLARE_BITMAP(name_use, MAX_DEVICES); | ||
88 | 91 | ||
89 | /* | 92 | /* |
90 | * There is one mmc_blk_data per slot. | 93 | * There is one mmc_blk_data per slot. |
@@ -112,7 +115,7 @@ struct mmc_blk_data { | |||
112 | 115 | ||
113 | /* | 116 | /* |
114 | * Only set in main mmc_blk_data associated | 117 | * Only set in main mmc_blk_data associated |
115 | * with mmc_card with mmc_set_drvdata, and keeps | 118 | * with mmc_card with dev_set_drvdata, and keeps |
116 | * track of the current selected device partition. | 119 | * track of the current selected device partition. |
117 | */ | 120 | */ |
118 | unsigned int part_curr; | 121 | unsigned int part_curr; |
@@ -260,7 +263,7 @@ static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, | |||
260 | int ret; | 263 | int ret; |
261 | struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); | 264 | struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); |
262 | 265 | ||
263 | ret = snprintf(buf, PAGE_SIZE, "%d", | 266 | ret = snprintf(buf, PAGE_SIZE, "%d\n", |
264 | get_disk_ro(dev_to_disk(dev)) ^ | 267 | get_disk_ro(dev_to_disk(dev)) ^ |
265 | md->read_only); | 268 | md->read_only); |
266 | mmc_blk_put(md); | 269 | mmc_blk_put(md); |
@@ -642,7 +645,7 @@ static inline int mmc_blk_part_switch(struct mmc_card *card, | |||
642 | struct mmc_blk_data *md) | 645 | struct mmc_blk_data *md) |
643 | { | 646 | { |
644 | int ret; | 647 | int ret; |
645 | struct mmc_blk_data *main_md = mmc_get_drvdata(card); | 648 | struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev); |
646 | 649 | ||
647 | if (main_md->part_curr == md->part_type) | 650 | if (main_md->part_curr == md->part_type) |
648 | return 0; | 651 | return 0; |
@@ -1004,7 +1007,8 @@ static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host, | |||
1004 | err = mmc_hw_reset(host); | 1007 | err = mmc_hw_reset(host); |
1005 | /* Ensure we switch back to the correct partition */ | 1008 | /* Ensure we switch back to the correct partition */ |
1006 | if (err != -EOPNOTSUPP) { | 1009 | if (err != -EOPNOTSUPP) { |
1007 | struct mmc_blk_data *main_md = mmc_get_drvdata(host->card); | 1010 | struct mmc_blk_data *main_md = |
1011 | dev_get_drvdata(&host->card->dev); | ||
1008 | int part_err; | 1012 | int part_err; |
1009 | 1013 | ||
1010 | main_md->part_curr = main_md->part_type; | 1014 | main_md->part_curr = main_md->part_type; |
@@ -1308,19 +1312,11 @@ static int mmc_blk_packed_err_check(struct mmc_card *card, | |||
1308 | } | 1312 | } |
1309 | 1313 | ||
1310 | if (status & R1_EXCEPTION_EVENT) { | 1314 | if (status & R1_EXCEPTION_EVENT) { |
1311 | ext_csd = kzalloc(512, GFP_KERNEL); | 1315 | err = mmc_get_ext_csd(card, &ext_csd); |
1312 | if (!ext_csd) { | ||
1313 | pr_err("%s: unable to allocate buffer for ext_csd\n", | ||
1314 | req->rq_disk->disk_name); | ||
1315 | return -ENOMEM; | ||
1316 | } | ||
1317 | |||
1318 | err = mmc_send_ext_csd(card, ext_csd); | ||
1319 | if (err) { | 1316 | if (err) { |
1320 | pr_err("%s: error %d sending ext_csd\n", | 1317 | pr_err("%s: error %d sending ext_csd\n", |
1321 | req->rq_disk->disk_name, err); | 1318 | req->rq_disk->disk_name, err); |
1322 | check = MMC_BLK_ABORT; | 1319 | return MMC_BLK_ABORT; |
1323 | goto free; | ||
1324 | } | 1320 | } |
1325 | 1321 | ||
1326 | if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS] & | 1322 | if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS] & |
@@ -1338,7 +1334,6 @@ static int mmc_blk_packed_err_check(struct mmc_card *card, | |||
1338 | req->rq_disk->disk_name, packed->nr_entries, | 1334 | req->rq_disk->disk_name, packed->nr_entries, |
1339 | packed->blocks, packed->idx_failure); | 1335 | packed->blocks, packed->idx_failure); |
1340 | } | 1336 | } |
1341 | free: | ||
1342 | kfree(ext_csd); | 1337 | kfree(ext_csd); |
1343 | } | 1338 | } |
1344 | 1339 | ||
@@ -2093,7 +2088,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
2093 | 2088 | ||
2094 | /* | 2089 | /* |
2095 | * !subname implies we are creating main mmc_blk_data that will be | 2090 | * !subname implies we are creating main mmc_blk_data that will be |
2096 | * associated with mmc_card with mmc_set_drvdata. Due to device | 2091 | * associated with mmc_card with dev_set_drvdata. Due to device |
2097 | * partitions, devidx will not coincide with a per-physical card | 2092 | * partitions, devidx will not coincide with a per-physical card |
2098 | * index anymore so we keep track of a name index. | 2093 | * index anymore so we keep track of a name index. |
2099 | */ | 2094 | */ |
@@ -2425,8 +2420,9 @@ static const struct mmc_fixup blk_fixups[] = | |||
2425 | END_FIXUP | 2420 | END_FIXUP |
2426 | }; | 2421 | }; |
2427 | 2422 | ||
2428 | static int mmc_blk_probe(struct mmc_card *card) | 2423 | static int mmc_blk_probe(struct device *dev) |
2429 | { | 2424 | { |
2425 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
2430 | struct mmc_blk_data *md, *part_md; | 2426 | struct mmc_blk_data *md, *part_md; |
2431 | char cap_str[10]; | 2427 | char cap_str[10]; |
2432 | 2428 | ||
@@ -2451,7 +2447,7 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
2451 | if (mmc_blk_alloc_parts(card, md)) | 2447 | if (mmc_blk_alloc_parts(card, md)) |
2452 | goto out; | 2448 | goto out; |
2453 | 2449 | ||
2454 | mmc_set_drvdata(card, md); | 2450 | dev_set_drvdata(dev, md); |
2455 | 2451 | ||
2456 | if (mmc_add_disk(md)) | 2452 | if (mmc_add_disk(md)) |
2457 | goto out; | 2453 | goto out; |
@@ -2481,9 +2477,10 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
2481 | return 0; | 2477 | return 0; |
2482 | } | 2478 | } |
2483 | 2479 | ||
2484 | static void mmc_blk_remove(struct mmc_card *card) | 2480 | static int mmc_blk_remove(struct device *dev) |
2485 | { | 2481 | { |
2486 | struct mmc_blk_data *md = mmc_get_drvdata(card); | 2482 | struct mmc_card *card = mmc_dev_to_card(dev); |
2483 | struct mmc_blk_data *md = dev_get_drvdata(dev); | ||
2487 | 2484 | ||
2488 | mmc_blk_remove_parts(card, md); | 2485 | mmc_blk_remove_parts(card, md); |
2489 | pm_runtime_get_sync(&card->dev); | 2486 | pm_runtime_get_sync(&card->dev); |
@@ -2494,13 +2491,15 @@ static void mmc_blk_remove(struct mmc_card *card) | |||
2494 | pm_runtime_disable(&card->dev); | 2491 | pm_runtime_disable(&card->dev); |
2495 | pm_runtime_put_noidle(&card->dev); | 2492 | pm_runtime_put_noidle(&card->dev); |
2496 | mmc_blk_remove_req(md); | 2493 | mmc_blk_remove_req(md); |
2497 | mmc_set_drvdata(card, NULL); | 2494 | dev_set_drvdata(dev, NULL); |
2495 | |||
2496 | return 0; | ||
2498 | } | 2497 | } |
2499 | 2498 | ||
2500 | static int _mmc_blk_suspend(struct mmc_card *card) | 2499 | static int _mmc_blk_suspend(struct device *dev) |
2501 | { | 2500 | { |
2502 | struct mmc_blk_data *part_md; | 2501 | struct mmc_blk_data *part_md; |
2503 | struct mmc_blk_data *md = mmc_get_drvdata(card); | 2502 | struct mmc_blk_data *md = dev_get_drvdata(dev); |
2504 | 2503 | ||
2505 | if (md) { | 2504 | if (md) { |
2506 | mmc_queue_suspend(&md->queue); | 2505 | mmc_queue_suspend(&md->queue); |
@@ -2511,21 +2510,21 @@ static int _mmc_blk_suspend(struct mmc_card *card) | |||
2511 | return 0; | 2510 | return 0; |
2512 | } | 2511 | } |
2513 | 2512 | ||
2514 | static void mmc_blk_shutdown(struct mmc_card *card) | 2513 | static void mmc_blk_shutdown(struct device *dev) |
2515 | { | 2514 | { |
2516 | _mmc_blk_suspend(card); | 2515 | _mmc_blk_suspend(dev); |
2517 | } | 2516 | } |
2518 | 2517 | ||
2519 | #ifdef CONFIG_PM | 2518 | #ifdef CONFIG_PM_SLEEP |
2520 | static int mmc_blk_suspend(struct mmc_card *card) | 2519 | static int mmc_blk_suspend(struct device *dev) |
2521 | { | 2520 | { |
2522 | return _mmc_blk_suspend(card); | 2521 | return _mmc_blk_suspend(dev); |
2523 | } | 2522 | } |
2524 | 2523 | ||
2525 | static int mmc_blk_resume(struct mmc_card *card) | 2524 | static int mmc_blk_resume(struct device *dev) |
2526 | { | 2525 | { |
2527 | struct mmc_blk_data *part_md; | 2526 | struct mmc_blk_data *part_md; |
2528 | struct mmc_blk_data *md = mmc_get_drvdata(card); | 2527 | struct mmc_blk_data *md = dev_get_drvdata(dev); |
2529 | 2528 | ||
2530 | if (md) { | 2529 | if (md) { |
2531 | /* | 2530 | /* |
@@ -2540,19 +2539,15 @@ static int mmc_blk_resume(struct mmc_card *card) | |||
2540 | } | 2539 | } |
2541 | return 0; | 2540 | return 0; |
2542 | } | 2541 | } |
2543 | #else | ||
2544 | #define mmc_blk_suspend NULL | ||
2545 | #define mmc_blk_resume NULL | ||
2546 | #endif | 2542 | #endif |
2547 | 2543 | ||
2548 | static struct mmc_driver mmc_driver = { | 2544 | static SIMPLE_DEV_PM_OPS(mmc_blk_pm_ops, mmc_blk_suspend, mmc_blk_resume); |
2549 | .drv = { | 2545 | |
2550 | .name = "mmcblk", | 2546 | static struct device_driver mmc_driver = { |
2551 | }, | 2547 | .name = "mmcblk", |
2548 | .pm = &mmc_blk_pm_ops, | ||
2552 | .probe = mmc_blk_probe, | 2549 | .probe = mmc_blk_probe, |
2553 | .remove = mmc_blk_remove, | 2550 | .remove = mmc_blk_remove, |
2554 | .suspend = mmc_blk_suspend, | ||
2555 | .resume = mmc_blk_resume, | ||
2556 | .shutdown = mmc_blk_shutdown, | 2551 | .shutdown = mmc_blk_shutdown, |
2557 | }; | 2552 | }; |
2558 | 2553 | ||
@@ -2563,7 +2558,7 @@ static int __init mmc_blk_init(void) | |||
2563 | if (perdev_minors != CONFIG_MMC_BLOCK_MINORS) | 2558 | if (perdev_minors != CONFIG_MMC_BLOCK_MINORS) |
2564 | pr_info("mmcblk: using %d minors per device\n", perdev_minors); | 2559 | pr_info("mmcblk: using %d minors per device\n", perdev_minors); |
2565 | 2560 | ||
2566 | max_devices = 256 / perdev_minors; | 2561 | max_devices = min(MAX_DEVICES, (1 << MINORBITS) / perdev_minors); |
2567 | 2562 | ||
2568 | res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); | 2563 | res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); |
2569 | if (res) | 2564 | if (res) |
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index 0c0fc52d42c5..0a7430f94d29 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/mmc/host.h> | 14 | #include <linux/mmc/host.h> |
15 | #include <linux/mmc/mmc.h> | 15 | #include <linux/mmc/mmc.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/device.h> | ||
17 | 18 | ||
18 | #include <linux/scatterlist.h> | 19 | #include <linux/scatterlist.h> |
19 | #include <linux/swap.h> /* For nr_free_buffer_pages() */ | 20 | #include <linux/swap.h> /* For nr_free_buffer_pages() */ |
@@ -32,6 +33,8 @@ | |||
32 | #define BUFFER_ORDER 2 | 33 | #define BUFFER_ORDER 2 |
33 | #define BUFFER_SIZE (PAGE_SIZE << BUFFER_ORDER) | 34 | #define BUFFER_SIZE (PAGE_SIZE << BUFFER_ORDER) |
34 | 35 | ||
36 | #define TEST_ALIGN_END 8 | ||
37 | |||
35 | /* | 38 | /* |
36 | * Limit the test area size to the maximum MMC HC erase group size. Note that | 39 | * Limit the test area size to the maximum MMC HC erase group size. Note that |
37 | * the maximum SD allocation unit size is just 4MiB. | 40 | * the maximum SD allocation unit size is just 4MiB. |
@@ -1174,7 +1177,7 @@ static int mmc_test_align_write(struct mmc_test_card *test) | |||
1174 | int ret, i; | 1177 | int ret, i; |
1175 | struct scatterlist sg; | 1178 | struct scatterlist sg; |
1176 | 1179 | ||
1177 | for (i = 1;i < 4;i++) { | 1180 | for (i = 1; i < TEST_ALIGN_END; i++) { |
1178 | sg_init_one(&sg, test->buffer + i, 512); | 1181 | sg_init_one(&sg, test->buffer + i, 512); |
1179 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1); | 1182 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1); |
1180 | if (ret) | 1183 | if (ret) |
@@ -1189,7 +1192,7 @@ static int mmc_test_align_read(struct mmc_test_card *test) | |||
1189 | int ret, i; | 1192 | int ret, i; |
1190 | struct scatterlist sg; | 1193 | struct scatterlist sg; |
1191 | 1194 | ||
1192 | for (i = 1;i < 4;i++) { | 1195 | for (i = 1; i < TEST_ALIGN_END; i++) { |
1193 | sg_init_one(&sg, test->buffer + i, 512); | 1196 | sg_init_one(&sg, test->buffer + i, 512); |
1194 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0); | 1197 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0); |
1195 | if (ret) | 1198 | if (ret) |
@@ -1216,7 +1219,7 @@ static int mmc_test_align_multi_write(struct mmc_test_card *test) | |||
1216 | if (size < 1024) | 1219 | if (size < 1024) |
1217 | return RESULT_UNSUP_HOST; | 1220 | return RESULT_UNSUP_HOST; |
1218 | 1221 | ||
1219 | for (i = 1;i < 4;i++) { | 1222 | for (i = 1; i < TEST_ALIGN_END; i++) { |
1220 | sg_init_one(&sg, test->buffer + i, size); | 1223 | sg_init_one(&sg, test->buffer + i, size); |
1221 | ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); | 1224 | ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); |
1222 | if (ret) | 1225 | if (ret) |
@@ -1243,7 +1246,7 @@ static int mmc_test_align_multi_read(struct mmc_test_card *test) | |||
1243 | if (size < 1024) | 1246 | if (size < 1024) |
1244 | return RESULT_UNSUP_HOST; | 1247 | return RESULT_UNSUP_HOST; |
1245 | 1248 | ||
1246 | for (i = 1;i < 4;i++) { | 1249 | for (i = 1; i < TEST_ALIGN_END; i++) { |
1247 | sg_init_one(&sg, test->buffer + i, size); | 1250 | sg_init_one(&sg, test->buffer + i, size); |
1248 | ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); | 1251 | ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); |
1249 | if (ret) | 1252 | if (ret) |
@@ -2997,8 +3000,9 @@ err: | |||
2997 | return ret; | 3000 | return ret; |
2998 | } | 3001 | } |
2999 | 3002 | ||
3000 | static int mmc_test_probe(struct mmc_card *card) | 3003 | static int mmc_test_probe(struct device *dev) |
3001 | { | 3004 | { |
3005 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
3002 | int ret; | 3006 | int ret; |
3003 | 3007 | ||
3004 | if (!mmc_card_mmc(card) && !mmc_card_sd(card)) | 3008 | if (!mmc_card_mmc(card) && !mmc_card_sd(card)) |
@@ -3013,20 +3017,22 @@ static int mmc_test_probe(struct mmc_card *card) | |||
3013 | return 0; | 3017 | return 0; |
3014 | } | 3018 | } |
3015 | 3019 | ||
3016 | static void mmc_test_remove(struct mmc_card *card) | 3020 | static int mmc_test_remove(struct device *dev) |
3017 | { | 3021 | { |
3022 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
3023 | |||
3018 | mmc_test_free_result(card); | 3024 | mmc_test_free_result(card); |
3019 | mmc_test_free_dbgfs_file(card); | 3025 | mmc_test_free_dbgfs_file(card); |
3026 | |||
3027 | return 0; | ||
3020 | } | 3028 | } |
3021 | 3029 | ||
3022 | static void mmc_test_shutdown(struct mmc_card *card) | 3030 | static void mmc_test_shutdown(struct device *dev) |
3023 | { | 3031 | { |
3024 | } | 3032 | } |
3025 | 3033 | ||
3026 | static struct mmc_driver mmc_driver = { | 3034 | static struct device_driver mmc_driver = { |
3027 | .drv = { | 3035 | .name = "mmc_test", |
3028 | .name = "mmc_test", | ||
3029 | }, | ||
3030 | .probe = mmc_test_probe, | 3036 | .probe = mmc_test_probe, |
3031 | .remove = mmc_test_remove, | 3037 | .remove = mmc_test_remove, |
3032 | .shutdown = mmc_test_shutdown, | 3038 | .shutdown = mmc_test_shutdown, |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index cfa6110632c3..236d194c2883 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -232,13 +232,15 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, | |||
232 | if (!mqrq_cur->bounce_buf) { | 232 | if (!mqrq_cur->bounce_buf) { |
233 | pr_warn("%s: unable to allocate bounce cur buffer\n", | 233 | pr_warn("%s: unable to allocate bounce cur buffer\n", |
234 | mmc_card_name(card)); | 234 | mmc_card_name(card)); |
235 | } | 235 | } else { |
236 | mqrq_prev->bounce_buf = kmalloc(bouncesz, GFP_KERNEL); | 236 | mqrq_prev->bounce_buf = |
237 | if (!mqrq_prev->bounce_buf) { | 237 | kmalloc(bouncesz, GFP_KERNEL); |
238 | pr_warn("%s: unable to allocate bounce prev buffer\n", | 238 | if (!mqrq_prev->bounce_buf) { |
239 | mmc_card_name(card)); | 239 | pr_warn("%s: unable to allocate bounce prev buffer\n", |
240 | kfree(mqrq_cur->bounce_buf); | 240 | mmc_card_name(card)); |
241 | mqrq_cur->bounce_buf = NULL; | 241 | kfree(mqrq_cur->bounce_buf); |
242 | mqrq_cur->bounce_buf = NULL; | ||
243 | } | ||
242 | } | 244 | } |
243 | } | 245 | } |
244 | 246 | ||
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 8a1f1240e058..5ca562ccfcf3 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include "sdio_cis.h" | 25 | #include "sdio_cis.h" |
26 | #include "bus.h" | 26 | #include "bus.h" |
27 | 27 | ||
28 | #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) | ||
29 | |||
30 | static ssize_t type_show(struct device *dev, | 28 | static ssize_t type_show(struct device *dev, |
31 | struct device_attribute *attr, char *buf) | 29 | struct device_attribute *attr, char *buf) |
32 | { | 30 | { |
@@ -106,33 +104,14 @@ mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
106 | return retval; | 104 | return retval; |
107 | } | 105 | } |
108 | 106 | ||
109 | static int mmc_bus_probe(struct device *dev) | ||
110 | { | ||
111 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
112 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
113 | |||
114 | return drv->probe(card); | ||
115 | } | ||
116 | |||
117 | static int mmc_bus_remove(struct device *dev) | ||
118 | { | ||
119 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
120 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
121 | |||
122 | drv->remove(card); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static void mmc_bus_shutdown(struct device *dev) | 107 | static void mmc_bus_shutdown(struct device *dev) |
128 | { | 108 | { |
129 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
130 | struct mmc_card *card = mmc_dev_to_card(dev); | 109 | struct mmc_card *card = mmc_dev_to_card(dev); |
131 | struct mmc_host *host = card->host; | 110 | struct mmc_host *host = card->host; |
132 | int ret; | 111 | int ret; |
133 | 112 | ||
134 | if (dev->driver && drv->shutdown) | 113 | if (dev->driver && dev->driver->shutdown) |
135 | drv->shutdown(card); | 114 | dev->driver->shutdown(dev); |
136 | 115 | ||
137 | if (host->bus_ops->shutdown) { | 116 | if (host->bus_ops->shutdown) { |
138 | ret = host->bus_ops->shutdown(host); | 117 | ret = host->bus_ops->shutdown(host); |
@@ -145,16 +124,13 @@ static void mmc_bus_shutdown(struct device *dev) | |||
145 | #ifdef CONFIG_PM_SLEEP | 124 | #ifdef CONFIG_PM_SLEEP |
146 | static int mmc_bus_suspend(struct device *dev) | 125 | static int mmc_bus_suspend(struct device *dev) |
147 | { | 126 | { |
148 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
149 | struct mmc_card *card = mmc_dev_to_card(dev); | 127 | struct mmc_card *card = mmc_dev_to_card(dev); |
150 | struct mmc_host *host = card->host; | 128 | struct mmc_host *host = card->host; |
151 | int ret; | 129 | int ret; |
152 | 130 | ||
153 | if (dev->driver && drv->suspend) { | 131 | ret = pm_generic_suspend(dev); |
154 | ret = drv->suspend(card); | 132 | if (ret) |
155 | if (ret) | 133 | return ret; |
156 | return ret; | ||
157 | } | ||
158 | 134 | ||
159 | ret = host->bus_ops->suspend(host); | 135 | ret = host->bus_ops->suspend(host); |
160 | return ret; | 136 | return ret; |
@@ -162,7 +138,6 @@ static int mmc_bus_suspend(struct device *dev) | |||
162 | 138 | ||
163 | static int mmc_bus_resume(struct device *dev) | 139 | static int mmc_bus_resume(struct device *dev) |
164 | { | 140 | { |
165 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
166 | struct mmc_card *card = mmc_dev_to_card(dev); | 141 | struct mmc_card *card = mmc_dev_to_card(dev); |
167 | struct mmc_host *host = card->host; | 142 | struct mmc_host *host = card->host; |
168 | int ret; | 143 | int ret; |
@@ -172,9 +147,7 @@ static int mmc_bus_resume(struct device *dev) | |||
172 | pr_warn("%s: error %d during resume (card was removed?)\n", | 147 | pr_warn("%s: error %d during resume (card was removed?)\n", |
173 | mmc_hostname(host), ret); | 148 | mmc_hostname(host), ret); |
174 | 149 | ||
175 | if (dev->driver && drv->resume) | 150 | ret = pm_generic_resume(dev); |
176 | ret = drv->resume(card); | ||
177 | |||
178 | return ret; | 151 | return ret; |
179 | } | 152 | } |
180 | #endif | 153 | #endif |
@@ -207,8 +180,6 @@ static struct bus_type mmc_bus_type = { | |||
207 | .dev_groups = mmc_dev_groups, | 180 | .dev_groups = mmc_dev_groups, |
208 | .match = mmc_bus_match, | 181 | .match = mmc_bus_match, |
209 | .uevent = mmc_bus_uevent, | 182 | .uevent = mmc_bus_uevent, |
210 | .probe = mmc_bus_probe, | ||
211 | .remove = mmc_bus_remove, | ||
212 | .shutdown = mmc_bus_shutdown, | 183 | .shutdown = mmc_bus_shutdown, |
213 | .pm = &mmc_bus_pm_ops, | 184 | .pm = &mmc_bus_pm_ops, |
214 | }; | 185 | }; |
@@ -227,24 +198,22 @@ void mmc_unregister_bus(void) | |||
227 | * mmc_register_driver - register a media driver | 198 | * mmc_register_driver - register a media driver |
228 | * @drv: MMC media driver | 199 | * @drv: MMC media driver |
229 | */ | 200 | */ |
230 | int mmc_register_driver(struct mmc_driver *drv) | 201 | int mmc_register_driver(struct device_driver *drv) |
231 | { | 202 | { |
232 | drv->drv.bus = &mmc_bus_type; | 203 | drv->bus = &mmc_bus_type; |
233 | return driver_register(&drv->drv); | 204 | return driver_register(drv); |
234 | } | 205 | } |
235 | |||
236 | EXPORT_SYMBOL(mmc_register_driver); | 206 | EXPORT_SYMBOL(mmc_register_driver); |
237 | 207 | ||
238 | /** | 208 | /** |
239 | * mmc_unregister_driver - unregister a media driver | 209 | * mmc_unregister_driver - unregister a media driver |
240 | * @drv: MMC media driver | 210 | * @drv: MMC media driver |
241 | */ | 211 | */ |
242 | void mmc_unregister_driver(struct mmc_driver *drv) | 212 | void mmc_unregister_driver(struct device_driver *drv) |
243 | { | 213 | { |
244 | drv->drv.bus = &mmc_bus_type; | 214 | drv->bus = &mmc_bus_type; |
245 | driver_unregister(&drv->drv); | 215 | driver_unregister(drv); |
246 | } | 216 | } |
247 | |||
248 | EXPORT_SYMBOL(mmc_unregister_driver); | 217 | EXPORT_SYMBOL(mmc_unregister_driver); |
249 | 218 | ||
250 | static void mmc_release_card(struct device *dev) | 219 | static void mmc_release_card(struct device *dev) |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f26a5f1d926d..9584bffa8b22 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -149,6 +149,14 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | |||
149 | 149 | ||
150 | led_trigger_event(host->led, LED_OFF); | 150 | led_trigger_event(host->led, LED_OFF); |
151 | 151 | ||
152 | if (mrq->sbc) { | ||
153 | pr_debug("%s: req done <CMD%u>: %d: %08x %08x %08x %08x\n", | ||
154 | mmc_hostname(host), mrq->sbc->opcode, | ||
155 | mrq->sbc->error, | ||
156 | mrq->sbc->resp[0], mrq->sbc->resp[1], | ||
157 | mrq->sbc->resp[2], mrq->sbc->resp[3]); | ||
158 | } | ||
159 | |||
152 | pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n", | 160 | pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n", |
153 | mmc_hostname(host), cmd->opcode, err, | 161 | mmc_hostname(host), cmd->opcode, err, |
154 | cmd->resp[0], cmd->resp[1], | 162 | cmd->resp[0], cmd->resp[1], |
@@ -214,6 +222,10 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
214 | 222 | ||
215 | mrq->cmd->error = 0; | 223 | mrq->cmd->error = 0; |
216 | mrq->cmd->mrq = mrq; | 224 | mrq->cmd->mrq = mrq; |
225 | if (mrq->sbc) { | ||
226 | mrq->sbc->error = 0; | ||
227 | mrq->sbc->mrq = mrq; | ||
228 | } | ||
217 | if (mrq->data) { | 229 | if (mrq->data) { |
218 | BUG_ON(mrq->data->blksz > host->max_blk_size); | 230 | BUG_ON(mrq->data->blksz > host->max_blk_size); |
219 | BUG_ON(mrq->data->blocks > host->max_blk_count); | 231 | BUG_ON(mrq->data->blocks > host->max_blk_count); |
@@ -538,8 +550,18 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host, | |||
538 | if (host->card && mmc_card_mmc(host->card) && | 550 | if (host->card && mmc_card_mmc(host->card) && |
539 | ((mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1) || | 551 | ((mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1) || |
540 | (mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1B)) && | 552 | (mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1B)) && |
541 | (host->areq->mrq->cmd->resp[0] & R1_EXCEPTION_EVENT)) | 553 | (host->areq->mrq->cmd->resp[0] & R1_EXCEPTION_EVENT)) { |
554 | |||
555 | /* Cancel the prepared request */ | ||
556 | if (areq) | ||
557 | mmc_post_req(host, areq->mrq, -EINVAL); | ||
558 | |||
542 | mmc_start_bkops(host->card, true); | 559 | mmc_start_bkops(host->card, true); |
560 | |||
561 | /* prepare the request again */ | ||
562 | if (areq) | ||
563 | mmc_pre_req(host, areq->mrq, !host->areq); | ||
564 | } | ||
543 | } | 565 | } |
544 | 566 | ||
545 | if (!err && areq) | 567 | if (!err && areq) |
@@ -709,27 +731,16 @@ int mmc_read_bkops_status(struct mmc_card *card) | |||
709 | int err; | 731 | int err; |
710 | u8 *ext_csd; | 732 | u8 *ext_csd; |
711 | 733 | ||
712 | /* | ||
713 | * In future work, we should consider storing the entire ext_csd. | ||
714 | */ | ||
715 | ext_csd = kmalloc(512, GFP_KERNEL); | ||
716 | if (!ext_csd) { | ||
717 | pr_err("%s: could not allocate buffer to receive the ext_csd.\n", | ||
718 | mmc_hostname(card->host)); | ||
719 | return -ENOMEM; | ||
720 | } | ||
721 | |||
722 | mmc_claim_host(card->host); | 734 | mmc_claim_host(card->host); |
723 | err = mmc_send_ext_csd(card, ext_csd); | 735 | err = mmc_get_ext_csd(card, &ext_csd); |
724 | mmc_release_host(card->host); | 736 | mmc_release_host(card->host); |
725 | if (err) | 737 | if (err) |
726 | goto out; | 738 | return err; |
727 | 739 | ||
728 | card->ext_csd.raw_bkops_status = ext_csd[EXT_CSD_BKOPS_STATUS]; | 740 | card->ext_csd.raw_bkops_status = ext_csd[EXT_CSD_BKOPS_STATUS]; |
729 | card->ext_csd.raw_exception_status = ext_csd[EXT_CSD_EXP_EVENTS_STATUS]; | 741 | card->ext_csd.raw_exception_status = ext_csd[EXT_CSD_EXP_EVENTS_STATUS]; |
730 | out: | ||
731 | kfree(ext_csd); | 742 | kfree(ext_csd); |
732 | return err; | 743 | return 0; |
733 | } | 744 | } |
734 | EXPORT_SYMBOL(mmc_read_bkops_status); | 745 | EXPORT_SYMBOL(mmc_read_bkops_status); |
735 | 746 | ||
@@ -1088,6 +1099,22 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width) | |||
1088 | mmc_host_clk_release(host); | 1099 | mmc_host_clk_release(host); |
1089 | } | 1100 | } |
1090 | 1101 | ||
1102 | /* | ||
1103 | * Set initial state after a power cycle or a hw_reset. | ||
1104 | */ | ||
1105 | void mmc_set_initial_state(struct mmc_host *host) | ||
1106 | { | ||
1107 | if (mmc_host_is_spi(host)) | ||
1108 | host->ios.chip_select = MMC_CS_HIGH; | ||
1109 | else | ||
1110 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
1111 | host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; | ||
1112 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
1113 | host->ios.timing = MMC_TIMING_LEGACY; | ||
1114 | |||
1115 | mmc_set_ios(host); | ||
1116 | } | ||
1117 | |||
1091 | /** | 1118 | /** |
1092 | * mmc_vdd_to_ocrbitnum - Convert a voltage to the OCR bit number | 1119 | * mmc_vdd_to_ocrbitnum - Convert a voltage to the OCR bit number |
1093 | * @vdd: voltage (mV) | 1120 | * @vdd: voltage (mV) |
@@ -1420,18 +1447,20 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr) | |||
1420 | pr_warn("%s: cannot verify signal voltage switch\n", | 1447 | pr_warn("%s: cannot verify signal voltage switch\n", |
1421 | mmc_hostname(host)); | 1448 | mmc_hostname(host)); |
1422 | 1449 | ||
1450 | mmc_host_clk_hold(host); | ||
1451 | |||
1423 | cmd.opcode = SD_SWITCH_VOLTAGE; | 1452 | cmd.opcode = SD_SWITCH_VOLTAGE; |
1424 | cmd.arg = 0; | 1453 | cmd.arg = 0; |
1425 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | 1454 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
1426 | 1455 | ||
1427 | err = mmc_wait_for_cmd(host, &cmd, 0); | 1456 | err = mmc_wait_for_cmd(host, &cmd, 0); |
1428 | if (err) | 1457 | if (err) |
1429 | return err; | 1458 | goto err_command; |
1430 | 1459 | ||
1431 | if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) | 1460 | if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) { |
1432 | return -EIO; | 1461 | err = -EIO; |
1433 | 1462 | goto err_command; | |
1434 | mmc_host_clk_hold(host); | 1463 | } |
1435 | /* | 1464 | /* |
1436 | * The card should drive cmd and dat[0:3] low immediately | 1465 | * The card should drive cmd and dat[0:3] low immediately |
1437 | * after the response of cmd11, but wait 1 ms to be sure | 1466 | * after the response of cmd11, but wait 1 ms to be sure |
@@ -1480,6 +1509,7 @@ power_cycle: | |||
1480 | mmc_power_cycle(host, ocr); | 1509 | mmc_power_cycle(host, ocr); |
1481 | } | 1510 | } |
1482 | 1511 | ||
1512 | err_command: | ||
1483 | mmc_host_clk_release(host); | 1513 | mmc_host_clk_release(host); |
1484 | 1514 | ||
1485 | return err; | 1515 | return err; |
@@ -1526,15 +1556,9 @@ void mmc_power_up(struct mmc_host *host, u32 ocr) | |||
1526 | mmc_host_clk_hold(host); | 1556 | mmc_host_clk_hold(host); |
1527 | 1557 | ||
1528 | host->ios.vdd = fls(ocr) - 1; | 1558 | host->ios.vdd = fls(ocr) - 1; |
1529 | if (mmc_host_is_spi(host)) | ||
1530 | host->ios.chip_select = MMC_CS_HIGH; | ||
1531 | else | ||
1532 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
1533 | host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; | ||
1534 | host->ios.power_mode = MMC_POWER_UP; | 1559 | host->ios.power_mode = MMC_POWER_UP; |
1535 | host->ios.bus_width = MMC_BUS_WIDTH_1; | 1560 | /* Set initial state and call mmc_set_ios */ |
1536 | host->ios.timing = MMC_TIMING_LEGACY; | 1561 | mmc_set_initial_state(host); |
1537 | mmc_set_ios(host); | ||
1538 | 1562 | ||
1539 | /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ | 1563 | /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ |
1540 | if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330) == 0) | 1564 | if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330) == 0) |
@@ -1574,14 +1598,9 @@ void mmc_power_off(struct mmc_host *host) | |||
1574 | host->ios.clock = 0; | 1598 | host->ios.clock = 0; |
1575 | host->ios.vdd = 0; | 1599 | host->ios.vdd = 0; |
1576 | 1600 | ||
1577 | if (!mmc_host_is_spi(host)) { | ||
1578 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
1579 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
1580 | } | ||
1581 | host->ios.power_mode = MMC_POWER_OFF; | 1601 | host->ios.power_mode = MMC_POWER_OFF; |
1582 | host->ios.bus_width = MMC_BUS_WIDTH_1; | 1602 | /* Set initial state and call mmc_set_ios */ |
1583 | host->ios.timing = MMC_TIMING_LEGACY; | 1603 | mmc_set_initial_state(host); |
1584 | mmc_set_ios(host); | ||
1585 | 1604 | ||
1586 | /* | 1605 | /* |
1587 | * Some configurations, such as the 802.11 SDIO card in the OLPC | 1606 | * Some configurations, such as the 802.11 SDIO card in the OLPC |
@@ -2259,30 +2278,16 @@ static int mmc_do_hw_reset(struct mmc_host *host, int check) | |||
2259 | 2278 | ||
2260 | /* If the reset has happened, then a status command will fail */ | 2279 | /* If the reset has happened, then a status command will fail */ |
2261 | if (check) { | 2280 | if (check) { |
2262 | struct mmc_command cmd = {0}; | 2281 | u32 status; |
2263 | int err; | ||
2264 | 2282 | ||
2265 | cmd.opcode = MMC_SEND_STATUS; | 2283 | if (!mmc_send_status(card, &status)) { |
2266 | if (!mmc_host_is_spi(card->host)) | ||
2267 | cmd.arg = card->rca << 16; | ||
2268 | cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; | ||
2269 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | ||
2270 | if (!err) { | ||
2271 | mmc_host_clk_release(host); | 2284 | mmc_host_clk_release(host); |
2272 | return -ENOSYS; | 2285 | return -ENOSYS; |
2273 | } | 2286 | } |
2274 | } | 2287 | } |
2275 | 2288 | ||
2276 | if (mmc_host_is_spi(host)) { | 2289 | /* Set initial state and call mmc_set_ios */ |
2277 | host->ios.chip_select = MMC_CS_HIGH; | 2290 | mmc_set_initial_state(host); |
2278 | host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; | ||
2279 | } else { | ||
2280 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
2281 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
2282 | } | ||
2283 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
2284 | host->ios.timing = MMC_TIMING_LEGACY; | ||
2285 | mmc_set_ios(host); | ||
2286 | 2291 | ||
2287 | mmc_host_clk_release(host); | 2292 | mmc_host_clk_release(host); |
2288 | 2293 | ||
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 443a584660f0..d76597c65e3a 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -49,6 +49,7 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); | |||
49 | void mmc_power_up(struct mmc_host *host, u32 ocr); | 49 | void mmc_power_up(struct mmc_host *host, u32 ocr); |
50 | void mmc_power_off(struct mmc_host *host); | 50 | void mmc_power_off(struct mmc_host *host); |
51 | void mmc_power_cycle(struct mmc_host *host, u32 ocr); | 51 | void mmc_power_cycle(struct mmc_host *host, u32 ocr); |
52 | void mmc_set_initial_state(struct mmc_host *host); | ||
52 | 53 | ||
53 | static inline void mmc_delay(unsigned int ms) | 54 | static inline void mmc_delay(unsigned int ms) |
54 | { | 55 | { |
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 91eb16223246..e9142108a6c6 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c | |||
@@ -291,14 +291,8 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp) | |||
291 | if (!buf) | 291 | if (!buf) |
292 | return -ENOMEM; | 292 | return -ENOMEM; |
293 | 293 | ||
294 | ext_csd = kmalloc(512, GFP_KERNEL); | ||
295 | if (!ext_csd) { | ||
296 | err = -ENOMEM; | ||
297 | goto out_free; | ||
298 | } | ||
299 | |||
300 | mmc_get_card(card); | 294 | mmc_get_card(card); |
301 | err = mmc_send_ext_csd(card, ext_csd); | 295 | err = mmc_get_ext_csd(card, &ext_csd); |
302 | mmc_put_card(card); | 296 | mmc_put_card(card); |
303 | if (err) | 297 | if (err) |
304 | goto out_free; | 298 | goto out_free; |
@@ -314,7 +308,6 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp) | |||
314 | 308 | ||
315 | out_free: | 309 | out_free: |
316 | kfree(buf); | 310 | kfree(buf); |
317 | kfree(ext_csd); | ||
318 | return err; | 311 | return err; |
319 | } | 312 | } |
320 | 313 | ||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index a301a78a2bd1..02ad79229f65 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -177,65 +177,6 @@ static int mmc_decode_csd(struct mmc_card *card) | |||
177 | return 0; | 177 | return 0; |
178 | } | 178 | } |
179 | 179 | ||
180 | /* | ||
181 | * Read extended CSD. | ||
182 | */ | ||
183 | static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd) | ||
184 | { | ||
185 | int err; | ||
186 | u8 *ext_csd; | ||
187 | |||
188 | BUG_ON(!card); | ||
189 | BUG_ON(!new_ext_csd); | ||
190 | |||
191 | *new_ext_csd = NULL; | ||
192 | |||
193 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | ||
194 | return 0; | ||
195 | |||
196 | /* | ||
197 | * As the ext_csd is so large and mostly unused, we don't store the | ||
198 | * raw block in mmc_card. | ||
199 | */ | ||
200 | ext_csd = kmalloc(512, GFP_KERNEL); | ||
201 | if (!ext_csd) { | ||
202 | pr_err("%s: could not allocate a buffer to " | ||
203 | "receive the ext_csd.\n", mmc_hostname(card->host)); | ||
204 | return -ENOMEM; | ||
205 | } | ||
206 | |||
207 | err = mmc_send_ext_csd(card, ext_csd); | ||
208 | if (err) { | ||
209 | kfree(ext_csd); | ||
210 | *new_ext_csd = NULL; | ||
211 | |||
212 | /* If the host or the card can't do the switch, | ||
213 | * fail more gracefully. */ | ||
214 | if ((err != -EINVAL) | ||
215 | && (err != -ENOSYS) | ||
216 | && (err != -EFAULT)) | ||
217 | return err; | ||
218 | |||
219 | /* | ||
220 | * High capacity cards should have this "magic" size | ||
221 | * stored in their CSD. | ||
222 | */ | ||
223 | if (card->csd.capacity == (4096 * 512)) { | ||
224 | pr_err("%s: unable to read EXT_CSD " | ||
225 | "on a possible high capacity card. " | ||
226 | "Card will be ignored.\n", | ||
227 | mmc_hostname(card->host)); | ||
228 | } else { | ||
229 | pr_warn("%s: unable to read EXT_CSD, performance might suffer\n", | ||
230 | mmc_hostname(card->host)); | ||
231 | err = 0; | ||
232 | } | ||
233 | } else | ||
234 | *new_ext_csd = ext_csd; | ||
235 | |||
236 | return err; | ||
237 | } | ||
238 | |||
239 | static void mmc_select_card_type(struct mmc_card *card) | 180 | static void mmc_select_card_type(struct mmc_card *card) |
240 | { | 181 | { |
241 | struct mmc_host *host = card->host; | 182 | struct mmc_host *host = card->host; |
@@ -391,16 +332,11 @@ static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) | |||
391 | /* | 332 | /* |
392 | * Decode extended CSD. | 333 | * Decode extended CSD. |
393 | */ | 334 | */ |
394 | static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | 335 | static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) |
395 | { | 336 | { |
396 | int err = 0, idx; | 337 | int err = 0, idx; |
397 | unsigned int part_size; | 338 | unsigned int part_size; |
398 | 339 | ||
399 | BUG_ON(!card); | ||
400 | |||
401 | if (!ext_csd) | ||
402 | return 0; | ||
403 | |||
404 | /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ | 340 | /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ |
405 | card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; | 341 | card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; |
406 | if (card->csd.structure == 3) { | 342 | if (card->csd.structure == 3) { |
@@ -628,16 +564,56 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
628 | card->ext_csd.data_sector_size = 512; | 564 | card->ext_csd.data_sector_size = 512; |
629 | } | 565 | } |
630 | 566 | ||
567 | /* eMMC v5 or later */ | ||
568 | if (card->ext_csd.rev >= 7) { | ||
569 | memcpy(card->ext_csd.fwrev, &ext_csd[EXT_CSD_FIRMWARE_VERSION], | ||
570 | MMC_FIRMWARE_LEN); | ||
571 | card->ext_csd.ffu_capable = | ||
572 | (ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) && | ||
573 | !(ext_csd[EXT_CSD_FW_CONFIG] & 0x1); | ||
574 | } | ||
631 | out: | 575 | out: |
632 | return err; | 576 | return err; |
633 | } | 577 | } |
634 | 578 | ||
635 | static inline void mmc_free_ext_csd(u8 *ext_csd) | 579 | static int mmc_read_ext_csd(struct mmc_card *card) |
636 | { | 580 | { |
581 | u8 *ext_csd; | ||
582 | int err; | ||
583 | |||
584 | if (!mmc_can_ext_csd(card)) | ||
585 | return 0; | ||
586 | |||
587 | err = mmc_get_ext_csd(card, &ext_csd); | ||
588 | if (err) { | ||
589 | /* If the host or the card can't do the switch, | ||
590 | * fail more gracefully. */ | ||
591 | if ((err != -EINVAL) | ||
592 | && (err != -ENOSYS) | ||
593 | && (err != -EFAULT)) | ||
594 | return err; | ||
595 | |||
596 | /* | ||
597 | * High capacity cards should have this "magic" size | ||
598 | * stored in their CSD. | ||
599 | */ | ||
600 | if (card->csd.capacity == (4096 * 512)) { | ||
601 | pr_err("%s: unable to read EXT_CSD on a possible high capacity card. Card will be ignored.\n", | ||
602 | mmc_hostname(card->host)); | ||
603 | } else { | ||
604 | pr_warn("%s: unable to read EXT_CSD, performance might suffer\n", | ||
605 | mmc_hostname(card->host)); | ||
606 | err = 0; | ||
607 | } | ||
608 | |||
609 | return err; | ||
610 | } | ||
611 | |||
612 | err = mmc_decode_ext_csd(card, ext_csd); | ||
637 | kfree(ext_csd); | 613 | kfree(ext_csd); |
614 | return err; | ||
638 | } | 615 | } |
639 | 616 | ||
640 | |||
641 | static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) | 617 | static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) |
642 | { | 618 | { |
643 | u8 *bw_ext_csd; | 619 | u8 *bw_ext_csd; |
@@ -647,11 +623,8 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) | |||
647 | return 0; | 623 | return 0; |
648 | 624 | ||
649 | err = mmc_get_ext_csd(card, &bw_ext_csd); | 625 | err = mmc_get_ext_csd(card, &bw_ext_csd); |
650 | 626 | if (err) | |
651 | if (err || bw_ext_csd == NULL) { | 627 | return err; |
652 | err = -EINVAL; | ||
653 | goto out; | ||
654 | } | ||
655 | 628 | ||
656 | /* only compare read only fields */ | 629 | /* only compare read only fields */ |
657 | err = !((card->ext_csd.raw_partition_support == | 630 | err = !((card->ext_csd.raw_partition_support == |
@@ -710,8 +683,7 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) | |||
710 | if (err) | 683 | if (err) |
711 | err = -EINVAL; | 684 | err = -EINVAL; |
712 | 685 | ||
713 | out: | 686 | kfree(bw_ext_csd); |
714 | mmc_free_ext_csd(bw_ext_csd); | ||
715 | return err; | 687 | return err; |
716 | } | 688 | } |
717 | 689 | ||
@@ -722,7 +694,7 @@ MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], | |||
722 | MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); | 694 | MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); |
723 | MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9); | 695 | MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9); |
724 | MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9); | 696 | MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9); |
725 | MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev); | 697 | MMC_DEV_ATTR(ffu_capable, "%d\n", card->ext_csd.ffu_capable); |
726 | MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); | 698 | MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); |
727 | MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); | 699 | MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); |
728 | MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); | 700 | MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); |
@@ -735,6 +707,22 @@ MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size); | |||
735 | MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult); | 707 | MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult); |
736 | MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors); | 708 | MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors); |
737 | 709 | ||
710 | static ssize_t mmc_fwrev_show(struct device *dev, | ||
711 | struct device_attribute *attr, | ||
712 | char *buf) | ||
713 | { | ||
714 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
715 | |||
716 | if (card->ext_csd.rev < 7) { | ||
717 | return sprintf(buf, "0x%x\n", card->cid.fwrev); | ||
718 | } else { | ||
719 | return sprintf(buf, "0x%*phN\n", MMC_FIRMWARE_LEN, | ||
720 | card->ext_csd.fwrev); | ||
721 | } | ||
722 | } | ||
723 | |||
724 | static DEVICE_ATTR(fwrev, S_IRUGO, mmc_fwrev_show, NULL); | ||
725 | |||
738 | static struct attribute *mmc_std_attrs[] = { | 726 | static struct attribute *mmc_std_attrs[] = { |
739 | &dev_attr_cid.attr, | 727 | &dev_attr_cid.attr, |
740 | &dev_attr_csd.attr, | 728 | &dev_attr_csd.attr, |
@@ -742,6 +730,7 @@ static struct attribute *mmc_std_attrs[] = { | |||
742 | &dev_attr_erase_size.attr, | 730 | &dev_attr_erase_size.attr, |
743 | &dev_attr_preferred_erase_size.attr, | 731 | &dev_attr_preferred_erase_size.attr, |
744 | &dev_attr_fwrev.attr, | 732 | &dev_attr_fwrev.attr, |
733 | &dev_attr_ffu_capable.attr, | ||
745 | &dev_attr_hwrev.attr, | 734 | &dev_attr_hwrev.attr, |
746 | &dev_attr_manfid.attr, | 735 | &dev_attr_manfid.attr, |
747 | &dev_attr_name.attr, | 736 | &dev_attr_name.attr, |
@@ -774,14 +763,6 @@ static int __mmc_select_powerclass(struct mmc_card *card, | |||
774 | unsigned int pwrclass_val = 0; | 763 | unsigned int pwrclass_val = 0; |
775 | int err = 0; | 764 | int err = 0; |
776 | 765 | ||
777 | /* Power class selection is supported for versions >= 4.0 */ | ||
778 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | ||
779 | return 0; | ||
780 | |||
781 | /* Power class values are defined only for 4/8 bit bus */ | ||
782 | if (bus_width == EXT_CSD_BUS_WIDTH_1) | ||
783 | return 0; | ||
784 | |||
785 | switch (1 << host->ios.vdd) { | 766 | switch (1 << host->ios.vdd) { |
786 | case MMC_VDD_165_195: | 767 | case MMC_VDD_165_195: |
787 | if (host->ios.clock <= MMC_HIGH_26_MAX_DTR) | 768 | if (host->ios.clock <= MMC_HIGH_26_MAX_DTR) |
@@ -844,7 +825,7 @@ static int mmc_select_powerclass(struct mmc_card *card) | |||
844 | int err, ddr; | 825 | int err, ddr; |
845 | 826 | ||
846 | /* Power class selection is supported for versions >= 4.0 */ | 827 | /* Power class selection is supported for versions >= 4.0 */ |
847 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | 828 | if (!mmc_can_ext_csd(card)) |
848 | return 0; | 829 | return 0; |
849 | 830 | ||
850 | bus_width = host->ios.bus_width; | 831 | bus_width = host->ios.bus_width; |
@@ -905,7 +886,7 @@ static int mmc_select_bus_width(struct mmc_card *card) | |||
905 | unsigned idx, bus_width = 0; | 886 | unsigned idx, bus_width = 0; |
906 | int err = 0; | 887 | int err = 0; |
907 | 888 | ||
908 | if ((card->csd.mmca_vsn < CSD_SPEC_VER_4) && | 889 | if (!mmc_can_ext_csd(card) && |
909 | !(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) | 890 | !(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) |
910 | return 0; | 891 | return 0; |
911 | 892 | ||
@@ -998,7 +979,7 @@ static int mmc_select_hs_ddr(struct mmc_card *card) | |||
998 | ext_csd_bits, | 979 | ext_csd_bits, |
999 | card->ext_csd.generic_cmd6_time); | 980 | card->ext_csd.generic_cmd6_time); |
1000 | if (err) { | 981 | if (err) { |
1001 | pr_warn("%s: switch to bus width %d ddr failed\n", | 982 | pr_err("%s: switch to bus width %d ddr failed\n", |
1002 | mmc_hostname(host), 1 << bus_width); | 983 | mmc_hostname(host), 1 << bus_width); |
1003 | return err; | 984 | return err; |
1004 | } | 985 | } |
@@ -1069,7 +1050,7 @@ static int mmc_select_hs400(struct mmc_card *card) | |||
1069 | card->ext_csd.generic_cmd6_time, | 1050 | card->ext_csd.generic_cmd6_time, |
1070 | true, true, true); | 1051 | true, true, true); |
1071 | if (err) { | 1052 | if (err) { |
1072 | pr_warn("%s: switch to high-speed from hs200 failed, err:%d\n", | 1053 | pr_err("%s: switch to high-speed from hs200 failed, err:%d\n", |
1073 | mmc_hostname(host), err); | 1054 | mmc_hostname(host), err); |
1074 | return err; | 1055 | return err; |
1075 | } | 1056 | } |
@@ -1079,7 +1060,7 @@ static int mmc_select_hs400(struct mmc_card *card) | |||
1079 | EXT_CSD_DDR_BUS_WIDTH_8, | 1060 | EXT_CSD_DDR_BUS_WIDTH_8, |
1080 | card->ext_csd.generic_cmd6_time); | 1061 | card->ext_csd.generic_cmd6_time); |
1081 | if (err) { | 1062 | if (err) { |
1082 | pr_warn("%s: switch to bus width for hs400 failed, err:%d\n", | 1063 | pr_err("%s: switch to bus width for hs400 failed, err:%d\n", |
1083 | mmc_hostname(host), err); | 1064 | mmc_hostname(host), err); |
1084 | return err; | 1065 | return err; |
1085 | } | 1066 | } |
@@ -1089,7 +1070,7 @@ static int mmc_select_hs400(struct mmc_card *card) | |||
1089 | card->ext_csd.generic_cmd6_time, | 1070 | card->ext_csd.generic_cmd6_time, |
1090 | true, true, true); | 1071 | true, true, true); |
1091 | if (err) { | 1072 | if (err) { |
1092 | pr_warn("%s: switch to hs400 failed, err:%d\n", | 1073 | pr_err("%s: switch to hs400 failed, err:%d\n", |
1093 | mmc_hostname(host), err); | 1074 | mmc_hostname(host), err); |
1094 | return err; | 1075 | return err; |
1095 | } | 1076 | } |
@@ -1146,8 +1127,7 @@ static int mmc_select_timing(struct mmc_card *card) | |||
1146 | { | 1127 | { |
1147 | int err = 0; | 1128 | int err = 0; |
1148 | 1129 | ||
1149 | if ((card->csd.mmca_vsn < CSD_SPEC_VER_4 && | 1130 | if (!mmc_can_ext_csd(card)) |
1150 | card->ext_csd.hs_max_dtr == 0)) | ||
1151 | goto bus_speed; | 1131 | goto bus_speed; |
1152 | 1132 | ||
1153 | if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) | 1133 | if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) |
@@ -1232,7 +1212,7 @@ static int mmc_hs200_tuning(struct mmc_card *card) | |||
1232 | mmc_host_clk_release(host); | 1212 | mmc_host_clk_release(host); |
1233 | 1213 | ||
1234 | if (err) | 1214 | if (err) |
1235 | pr_warn("%s: tuning execution failed\n", | 1215 | pr_err("%s: tuning execution failed\n", |
1236 | mmc_hostname(host)); | 1216 | mmc_hostname(host)); |
1237 | } | 1217 | } |
1238 | 1218 | ||
@@ -1252,7 +1232,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1252 | int err; | 1232 | int err; |
1253 | u32 cid[4]; | 1233 | u32 cid[4]; |
1254 | u32 rocr; | 1234 | u32 rocr; |
1255 | u8 *ext_csd = NULL; | ||
1256 | 1235 | ||
1257 | BUG_ON(!host); | 1236 | BUG_ON(!host); |
1258 | WARN_ON(!host->claimed); | 1237 | WARN_ON(!host->claimed); |
@@ -1361,14 +1340,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1361 | } | 1340 | } |
1362 | 1341 | ||
1363 | if (!oldcard) { | 1342 | if (!oldcard) { |
1364 | /* | 1343 | /* Read extended CSD. */ |
1365 | * Fetch and process extended CSD. | 1344 | err = mmc_read_ext_csd(card); |
1366 | */ | ||
1367 | |||
1368 | err = mmc_get_ext_csd(card, &ext_csd); | ||
1369 | if (err) | ||
1370 | goto free_card; | ||
1371 | err = mmc_read_ext_csd(card, ext_csd); | ||
1372 | if (err) | 1345 | if (err) |
1373 | goto free_card; | 1346 | goto free_card; |
1374 | 1347 | ||
@@ -1458,18 +1431,18 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1458 | if (mmc_card_hs200(card)) { | 1431 | if (mmc_card_hs200(card)) { |
1459 | err = mmc_hs200_tuning(card); | 1432 | err = mmc_hs200_tuning(card); |
1460 | if (err) | 1433 | if (err) |
1461 | goto err; | 1434 | goto free_card; |
1462 | 1435 | ||
1463 | err = mmc_select_hs400(card); | 1436 | err = mmc_select_hs400(card); |
1464 | if (err) | 1437 | if (err) |
1465 | goto err; | 1438 | goto free_card; |
1466 | } else if (mmc_card_hs(card)) { | 1439 | } else if (mmc_card_hs(card)) { |
1467 | /* Select the desired bus width optionally */ | 1440 | /* Select the desired bus width optionally */ |
1468 | err = mmc_select_bus_width(card); | 1441 | err = mmc_select_bus_width(card); |
1469 | if (!IS_ERR_VALUE(err)) { | 1442 | if (!IS_ERR_VALUE(err)) { |
1470 | err = mmc_select_hs_ddr(card); | 1443 | err = mmc_select_hs_ddr(card); |
1471 | if (err) | 1444 | if (err) |
1472 | goto err; | 1445 | goto free_card; |
1473 | } | 1446 | } |
1474 | } | 1447 | } |
1475 | 1448 | ||
@@ -1545,15 +1518,12 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1545 | if (!oldcard) | 1518 | if (!oldcard) |
1546 | host->card = card; | 1519 | host->card = card; |
1547 | 1520 | ||
1548 | mmc_free_ext_csd(ext_csd); | ||
1549 | return 0; | 1521 | return 0; |
1550 | 1522 | ||
1551 | free_card: | 1523 | free_card: |
1552 | if (!oldcard) | 1524 | if (!oldcard) |
1553 | mmc_remove_card(card); | 1525 | mmc_remove_card(card); |
1554 | err: | 1526 | err: |
1555 | mmc_free_ext_csd(ext_csd); | ||
1556 | |||
1557 | return err; | 1527 | return err; |
1558 | } | 1528 | } |
1559 | 1529 | ||
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 7911e0510a1d..3b044c5b029c 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -264,20 +264,6 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, | |||
264 | struct mmc_command cmd = {0}; | 264 | struct mmc_command cmd = {0}; |
265 | struct mmc_data data = {0}; | 265 | struct mmc_data data = {0}; |
266 | struct scatterlist sg; | 266 | struct scatterlist sg; |
267 | void *data_buf; | ||
268 | int is_on_stack; | ||
269 | |||
270 | is_on_stack = object_is_on_stack(buf); | ||
271 | if (is_on_stack) { | ||
272 | /* | ||
273 | * dma onto stack is unsafe/nonportable, but callers to this | ||
274 | * routine normally provide temporary on-stack buffers ... | ||
275 | */ | ||
276 | data_buf = kmalloc(len, GFP_KERNEL); | ||
277 | if (!data_buf) | ||
278 | return -ENOMEM; | ||
279 | } else | ||
280 | data_buf = buf; | ||
281 | 267 | ||
282 | mrq.cmd = &cmd; | 268 | mrq.cmd = &cmd; |
283 | mrq.data = &data; | 269 | mrq.data = &data; |
@@ -298,7 +284,7 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, | |||
298 | data.sg = &sg; | 284 | data.sg = &sg; |
299 | data.sg_len = 1; | 285 | data.sg_len = 1; |
300 | 286 | ||
301 | sg_init_one(&sg, data_buf, len); | 287 | sg_init_one(&sg, buf, len); |
302 | 288 | ||
303 | if (opcode == MMC_SEND_CSD || opcode == MMC_SEND_CID) { | 289 | if (opcode == MMC_SEND_CSD || opcode == MMC_SEND_CID) { |
304 | /* | 290 | /* |
@@ -312,11 +298,6 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, | |||
312 | 298 | ||
313 | mmc_wait_for_req(host, &mrq); | 299 | mmc_wait_for_req(host, &mrq); |
314 | 300 | ||
315 | if (is_on_stack) { | ||
316 | memcpy(buf, data_buf, len); | ||
317 | kfree(data_buf); | ||
318 | } | ||
319 | |||
320 | if (cmd.error) | 301 | if (cmd.error) |
321 | return cmd.error; | 302 | return cmd.error; |
322 | if (data.error) | 303 | if (data.error) |
@@ -334,7 +315,7 @@ int mmc_send_csd(struct mmc_card *card, u32 *csd) | |||
334 | return mmc_send_cxd_native(card->host, card->rca << 16, | 315 | return mmc_send_cxd_native(card->host, card->rca << 16, |
335 | csd, MMC_SEND_CSD); | 316 | csd, MMC_SEND_CSD); |
336 | 317 | ||
337 | csd_tmp = kmalloc(16, GFP_KERNEL); | 318 | csd_tmp = kzalloc(16, GFP_KERNEL); |
338 | if (!csd_tmp) | 319 | if (!csd_tmp) |
339 | return -ENOMEM; | 320 | return -ENOMEM; |
340 | 321 | ||
@@ -362,7 +343,7 @@ int mmc_send_cid(struct mmc_host *host, u32 *cid) | |||
362 | cid, MMC_SEND_CID); | 343 | cid, MMC_SEND_CID); |
363 | } | 344 | } |
364 | 345 | ||
365 | cid_tmp = kmalloc(16, GFP_KERNEL); | 346 | cid_tmp = kzalloc(16, GFP_KERNEL); |
366 | if (!cid_tmp) | 347 | if (!cid_tmp) |
367 | return -ENOMEM; | 348 | return -ENOMEM; |
368 | 349 | ||
@@ -378,12 +359,35 @@ err: | |||
378 | return ret; | 359 | return ret; |
379 | } | 360 | } |
380 | 361 | ||
381 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) | 362 | int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd) |
382 | { | 363 | { |
383 | return mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD, | 364 | int err; |
384 | ext_csd, 512); | 365 | u8 *ext_csd; |
366 | |||
367 | if (!card || !new_ext_csd) | ||
368 | return -EINVAL; | ||
369 | |||
370 | if (!mmc_can_ext_csd(card)) | ||
371 | return -EOPNOTSUPP; | ||
372 | |||
373 | /* | ||
374 | * As the ext_csd is so large and mostly unused, we don't store the | ||
375 | * raw block in mmc_card. | ||
376 | */ | ||
377 | ext_csd = kzalloc(512, GFP_KERNEL); | ||
378 | if (!ext_csd) | ||
379 | return -ENOMEM; | ||
380 | |||
381 | err = mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD, ext_csd, | ||
382 | 512); | ||
383 | if (err) | ||
384 | kfree(ext_csd); | ||
385 | else | ||
386 | *new_ext_csd = ext_csd; | ||
387 | |||
388 | return err; | ||
385 | } | 389 | } |
386 | EXPORT_SYMBOL_GPL(mmc_send_ext_csd); | 390 | EXPORT_SYMBOL_GPL(mmc_get_ext_csd); |
387 | 391 | ||
388 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) | 392 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) |
389 | { | 393 | { |
@@ -543,6 +547,75 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | |||
543 | } | 547 | } |
544 | EXPORT_SYMBOL_GPL(mmc_switch); | 548 | EXPORT_SYMBOL_GPL(mmc_switch); |
545 | 549 | ||
550 | int mmc_send_tuning(struct mmc_host *host) | ||
551 | { | ||
552 | struct mmc_request mrq = {NULL}; | ||
553 | struct mmc_command cmd = {0}; | ||
554 | struct mmc_data data = {0}; | ||
555 | struct scatterlist sg; | ||
556 | struct mmc_ios *ios = &host->ios; | ||
557 | const u8 *tuning_block_pattern; | ||
558 | int size, err = 0; | ||
559 | u8 *data_buf; | ||
560 | u32 opcode; | ||
561 | |||
562 | if (ios->bus_width == MMC_BUS_WIDTH_8) { | ||
563 | tuning_block_pattern = tuning_blk_pattern_8bit; | ||
564 | size = sizeof(tuning_blk_pattern_8bit); | ||
565 | opcode = MMC_SEND_TUNING_BLOCK_HS200; | ||
566 | } else if (ios->bus_width == MMC_BUS_WIDTH_4) { | ||
567 | tuning_block_pattern = tuning_blk_pattern_4bit; | ||
568 | size = sizeof(tuning_blk_pattern_4bit); | ||
569 | opcode = MMC_SEND_TUNING_BLOCK; | ||
570 | } else | ||
571 | return -EINVAL; | ||
572 | |||
573 | data_buf = kzalloc(size, GFP_KERNEL); | ||
574 | if (!data_buf) | ||
575 | return -ENOMEM; | ||
576 | |||
577 | mrq.cmd = &cmd; | ||
578 | mrq.data = &data; | ||
579 | |||
580 | cmd.opcode = opcode; | ||
581 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
582 | |||
583 | data.blksz = size; | ||
584 | data.blocks = 1; | ||
585 | data.flags = MMC_DATA_READ; | ||
586 | |||
587 | /* | ||
588 | * According to the tuning specs, Tuning process | ||
589 | * is normally shorter 40 executions of CMD19, | ||
590 | * and timeout value should be shorter than 150 ms | ||
591 | */ | ||
592 | data.timeout_ns = 150 * NSEC_PER_MSEC; | ||
593 | |||
594 | data.sg = &sg; | ||
595 | data.sg_len = 1; | ||
596 | sg_init_one(&sg, data_buf, size); | ||
597 | |||
598 | mmc_wait_for_req(host, &mrq); | ||
599 | |||
600 | if (cmd.error) { | ||
601 | err = cmd.error; | ||
602 | goto out; | ||
603 | } | ||
604 | |||
605 | if (data.error) { | ||
606 | err = data.error; | ||
607 | goto out; | ||
608 | } | ||
609 | |||
610 | if (memcmp(data_buf, tuning_block_pattern, size)) | ||
611 | err = -EIO; | ||
612 | |||
613 | out: | ||
614 | kfree(data_buf); | ||
615 | return err; | ||
616 | } | ||
617 | EXPORT_SYMBOL_GPL(mmc_send_tuning); | ||
618 | |||
546 | static int | 619 | static int |
547 | mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, | 620 | mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, |
548 | u8 len) | 621 | u8 len) |
@@ -675,3 +748,8 @@ int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status) | |||
675 | 748 | ||
676 | return 0; | 749 | return 0; |
677 | } | 750 | } |
751 | |||
752 | int mmc_can_ext_csd(struct mmc_card *card) | ||
753 | { | ||
754 | return (card && card->csd.mmca_vsn > CSD_SPEC_VER_3); | ||
755 | } | ||
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index 390dac665b2a..6f4b00ed93de 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h | |||
@@ -20,13 +20,13 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | |||
20 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid); | 20 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid); |
21 | int mmc_set_relative_addr(struct mmc_card *card); | 21 | int mmc_set_relative_addr(struct mmc_card *card); |
22 | int mmc_send_csd(struct mmc_card *card, u32 *csd); | 22 | int mmc_send_csd(struct mmc_card *card, u32 *csd); |
23 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); | ||
24 | int mmc_send_status(struct mmc_card *card, u32 *status); | 23 | int mmc_send_status(struct mmc_card *card, u32 *status); |
25 | int mmc_send_cid(struct mmc_host *host, u32 *cid); | 24 | int mmc_send_cid(struct mmc_host *host, u32 *cid); |
26 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); | 25 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); |
27 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc); | 26 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc); |
28 | int mmc_bus_test(struct mmc_card *card, u8 bus_width); | 27 | int mmc_bus_test(struct mmc_card *card, u8 bus_width); |
29 | int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status); | 28 | int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status); |
29 | int mmc_can_ext_csd(struct mmc_card *card); | ||
30 | 30 | ||
31 | #endif | 31 | #endif |
32 | 32 | ||
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 2439e717655b..fd0750b5a634 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -980,8 +980,12 @@ static int mmc_sdio_resume(struct mmc_host *host) | |||
980 | if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { | 980 | if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { |
981 | sdio_reset(host); | 981 | sdio_reset(host); |
982 | mmc_go_idle(host); | 982 | mmc_go_idle(host); |
983 | err = mmc_sdio_init_card(host, host->card->ocr, host->card, | 983 | mmc_send_if_cond(host, host->card->ocr); |
984 | mmc_card_keep_power(host)); | 984 | err = mmc_send_io_op_cond(host, 0, NULL); |
985 | if (!err) | ||
986 | err = mmc_sdio_init_card(host, host->card->ocr, | ||
987 | host->card, | ||
988 | mmc_card_keep_power(host)); | ||
985 | } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { | 989 | } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { |
986 | /* We may have switched to 1-bit mode during suspend */ | 990 | /* We may have switched to 1-bit mode during suspend */ |
987 | err = sdio_enable_4bit_bus(host->card); | 991 | err = sdio_enable_4bit_bus(host->card); |
@@ -1035,7 +1039,7 @@ static int mmc_sdio_power_restore(struct mmc_host *host) | |||
1035 | 1039 | ||
1036 | sdio_reset(host); | 1040 | sdio_reset(host); |
1037 | mmc_go_idle(host); | 1041 | mmc_go_idle(host); |
1038 | mmc_send_if_cond(host, host->ocr_avail); | 1042 | mmc_send_if_cond(host, host->card->ocr); |
1039 | 1043 | ||
1040 | ret = mmc_send_io_op_cond(host, 0, NULL); | 1044 | ret = mmc_send_io_op_cond(host, 0, NULL); |
1041 | if (ret) | 1045 | if (ret) |
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 6da97b170563..60885316afba 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include "sdio_cis.h" | 26 | #include "sdio_cis.h" |
27 | #include "sdio_bus.h" | 27 | #include "sdio_bus.h" |
28 | 28 | ||
29 | #define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) | ||
30 | |||
29 | /* show configuration fields */ | 31 | /* show configuration fields */ |
30 | #define sdio_config_attr(field, format_string) \ | 32 | #define sdio_config_attr(field, format_string) \ |
31 | static ssize_t \ | 33 | static ssize_t \ |
@@ -196,8 +198,6 @@ static int sdio_bus_remove(struct device *dev) | |||
196 | return ret; | 198 | return ret; |
197 | } | 199 | } |
198 | 200 | ||
199 | #ifdef CONFIG_PM | ||
200 | |||
201 | static const struct dev_pm_ops sdio_bus_pm_ops = { | 201 | static const struct dev_pm_ops sdio_bus_pm_ops = { |
202 | SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume) | 202 | SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume) |
203 | SET_RUNTIME_PM_OPS( | 203 | SET_RUNTIME_PM_OPS( |
@@ -207,14 +207,6 @@ static const struct dev_pm_ops sdio_bus_pm_ops = { | |||
207 | ) | 207 | ) |
208 | }; | 208 | }; |
209 | 209 | ||
210 | #define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops) | ||
211 | |||
212 | #else /* !CONFIG_PM */ | ||
213 | |||
214 | #define SDIO_PM_OPS_PTR NULL | ||
215 | |||
216 | #endif /* !CONFIG_PM */ | ||
217 | |||
218 | static struct bus_type sdio_bus_type = { | 210 | static struct bus_type sdio_bus_type = { |
219 | .name = "sdio", | 211 | .name = "sdio", |
220 | .dev_groups = sdio_dev_groups, | 212 | .dev_groups = sdio_dev_groups, |
@@ -222,7 +214,7 @@ static struct bus_type sdio_bus_type = { | |||
222 | .uevent = sdio_bus_uevent, | 214 | .uevent = sdio_bus_uevent, |
223 | .probe = sdio_bus_probe, | 215 | .probe = sdio_bus_probe, |
224 | .remove = sdio_bus_remove, | 216 | .remove = sdio_bus_remove, |
225 | .pm = SDIO_PM_OPS_PTR, | 217 | .pm = &sdio_bus_pm_ops, |
226 | }; | 218 | }; |
227 | 219 | ||
228 | int sdio_register_bus(void) | 220 | int sdio_register_bus(void) |
@@ -295,7 +287,7 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card) | |||
295 | static void sdio_acpi_set_handle(struct sdio_func *func) | 287 | static void sdio_acpi_set_handle(struct sdio_func *func) |
296 | { | 288 | { |
297 | struct mmc_host *host = func->card->host; | 289 | struct mmc_host *host = func->card->host; |
298 | u64 addr = (host->slotno << 16) | func->num; | 290 | u64 addr = ((u64)host->slotno << 16) | func->num; |
299 | 291 | ||
300 | acpi_preset_companion(&func->dev, ACPI_COMPANION(host->parent), addr); | 292 | acpi_preset_companion(&func->dev, ACPI_COMPANION(host->parent), addr); |
301 | } | 293 | } |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 13860656104b..2d6fbdd11803 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -580,7 +580,7 @@ config SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND | |||
580 | config MMC_DW | 580 | config MMC_DW |
581 | tristate "Synopsys DesignWare Memory Card Interface" | 581 | tristate "Synopsys DesignWare Memory Card Interface" |
582 | depends on HAS_DMA | 582 | depends on HAS_DMA |
583 | depends on ARC || ARM || MIPS || COMPILE_TEST | 583 | depends on ARC || ARM || ARM64 || MIPS || COMPILE_TEST |
584 | help | 584 | help |
585 | This selects support for the Synopsys DesignWare Mobile Storage IP | 585 | This selects support for the Synopsys DesignWare Mobile Storage IP |
586 | block, this provides host support for SD and MMC interfaces, in both | 586 | block, this provides host support for SD and MMC interfaces, in both |
@@ -748,3 +748,8 @@ config MMC_SUNXI | |||
748 | help | 748 | help |
749 | This selects support for the SD/MMC Host Controller on | 749 | This selects support for the SD/MMC Host Controller on |
750 | Allwinner sunxi SoCs. | 750 | Allwinner sunxi SoCs. |
751 | |||
752 | config MMC_TOSHIBA_PCI | ||
753 | tristate "Toshiba Type A SD/MMC Card Interface Driver" | ||
754 | depends on PCI | ||
755 | help | ||
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index b09ecfb88269..f7b0a77cf419 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
@@ -55,6 +55,7 @@ obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o | |||
55 | obj-$(CONFIG_MMC_MOXART) += moxart-mmc.o | 55 | obj-$(CONFIG_MMC_MOXART) += moxart-mmc.o |
56 | obj-$(CONFIG_MMC_SUNXI) += sunxi-mmc.o | 56 | obj-$(CONFIG_MMC_SUNXI) += sunxi-mmc.o |
57 | obj-$(CONFIG_MMC_USDHI6ROL0) += usdhi6rol0.o | 57 | obj-$(CONFIG_MMC_USDHI6ROL0) += usdhi6rol0.o |
58 | obj-$(CONFIG_MMC_TOSHIBA_PCI) += toshsd.o | ||
58 | 59 | ||
59 | obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o | 60 | obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o |
60 | obj-$(CONFIG_MMC_REALTEK_USB) += rtsx_usb_sdmmc.o | 61 | obj-$(CONFIG_MMC_REALTEK_USB) += rtsx_usb_sdmmc.o |
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 77250d4b1979..62aba9af19f4 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -30,13 +30,16 @@ | |||
30 | #include <linux/stat.h> | 30 | #include <linux/stat.h> |
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/platform_data/atmel.h> | 32 | #include <linux/platform_data/atmel.h> |
33 | #include <linux/platform_data/mmc-atmel-mci.h> | ||
33 | 34 | ||
34 | #include <linux/mmc/host.h> | 35 | #include <linux/mmc/host.h> |
35 | #include <linux/mmc/sdio.h> | 36 | #include <linux/mmc/sdio.h> |
36 | 37 | ||
37 | #include <mach/atmel-mci.h> | ||
38 | #include <linux/atmel-mci.h> | 38 | #include <linux/atmel-mci.h> |
39 | #include <linux/atmel_pdc.h> | 39 | #include <linux/atmel_pdc.h> |
40 | #include <linux/pm.h> | ||
41 | #include <linux/pm_runtime.h> | ||
42 | #include <linux/pinctrl/consumer.h> | ||
40 | 43 | ||
41 | #include <asm/cacheflush.h> | 44 | #include <asm/cacheflush.h> |
42 | #include <asm/io.h> | 45 | #include <asm/io.h> |
@@ -44,6 +47,8 @@ | |||
44 | 47 | ||
45 | #include "atmel-mci-regs.h" | 48 | #include "atmel-mci-regs.h" |
46 | 49 | ||
50 | #define AUTOSUSPEND_DELAY 50 | ||
51 | |||
47 | #define ATMCI_DATA_ERROR_FLAGS (ATMCI_DCRCE | ATMCI_DTOE | ATMCI_OVRE | ATMCI_UNRE) | 52 | #define ATMCI_DATA_ERROR_FLAGS (ATMCI_DCRCE | ATMCI_DTOE | ATMCI_OVRE | ATMCI_UNRE) |
48 | #define ATMCI_DMA_THRESHOLD 16 | 53 | #define ATMCI_DMA_THRESHOLD 16 |
49 | 54 | ||
@@ -386,20 +391,19 @@ static int atmci_regs_show(struct seq_file *s, void *v) | |||
386 | if (!buf) | 391 | if (!buf) |
387 | return -ENOMEM; | 392 | return -ENOMEM; |
388 | 393 | ||
394 | pm_runtime_get_sync(&host->pdev->dev); | ||
395 | |||
389 | /* | 396 | /* |
390 | * Grab a more or less consistent snapshot. Note that we're | 397 | * Grab a more or less consistent snapshot. Note that we're |
391 | * not disabling interrupts, so IMR and SR may not be | 398 | * not disabling interrupts, so IMR and SR may not be |
392 | * consistent. | 399 | * consistent. |
393 | */ | 400 | */ |
394 | ret = clk_prepare_enable(host->mck); | ||
395 | if (ret) | ||
396 | goto out; | ||
397 | |||
398 | spin_lock_bh(&host->lock); | 401 | spin_lock_bh(&host->lock); |
399 | memcpy_fromio(buf, host->regs, ATMCI_REGS_SIZE); | 402 | memcpy_fromio(buf, host->regs, ATMCI_REGS_SIZE); |
400 | spin_unlock_bh(&host->lock); | 403 | spin_unlock_bh(&host->lock); |
401 | 404 | ||
402 | clk_disable_unprepare(host->mck); | 405 | pm_runtime_mark_last_busy(&host->pdev->dev); |
406 | pm_runtime_put_autosuspend(&host->pdev->dev); | ||
403 | 407 | ||
404 | seq_printf(s, "MR:\t0x%08x%s%s ", | 408 | seq_printf(s, "MR:\t0x%08x%s%s ", |
405 | buf[ATMCI_MR / 4], | 409 | buf[ATMCI_MR / 4], |
@@ -449,7 +453,6 @@ static int atmci_regs_show(struct seq_file *s, void *v) | |||
449 | val & ATMCI_CFG_LSYNC ? " LSYNC" : ""); | 453 | val & ATMCI_CFG_LSYNC ? " LSYNC" : ""); |
450 | } | 454 | } |
451 | 455 | ||
452 | out: | ||
453 | kfree(buf); | 456 | kfree(buf); |
454 | 457 | ||
455 | return ret; | 458 | return ret; |
@@ -560,6 +563,9 @@ atmci_of_init(struct platform_device *pdev) | |||
560 | pdata->slot[slot_id].detect_is_active_high = | 563 | pdata->slot[slot_id].detect_is_active_high = |
561 | of_property_read_bool(cnp, "cd-inverted"); | 564 | of_property_read_bool(cnp, "cd-inverted"); |
562 | 565 | ||
566 | pdata->slot[slot_id].non_removable = | ||
567 | of_property_read_bool(cnp, "non-removable"); | ||
568 | |||
563 | pdata->slot[slot_id].wp_pin = | 569 | pdata->slot[slot_id].wp_pin = |
564 | of_get_named_gpio(cnp, "wp-gpios", 0); | 570 | of_get_named_gpio(cnp, "wp-gpios", 0); |
565 | } | 571 | } |
@@ -1252,6 +1258,8 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1252 | WARN_ON(slot->mrq); | 1258 | WARN_ON(slot->mrq); |
1253 | dev_dbg(&host->pdev->dev, "MRQ: cmd %u\n", mrq->cmd->opcode); | 1259 | dev_dbg(&host->pdev->dev, "MRQ: cmd %u\n", mrq->cmd->opcode); |
1254 | 1260 | ||
1261 | pm_runtime_get_sync(&host->pdev->dev); | ||
1262 | |||
1255 | /* | 1263 | /* |
1256 | * We may "know" the card is gone even though there's still an | 1264 | * We may "know" the card is gone even though there's still an |
1257 | * electrical connection. If so, we really need to communicate | 1265 | * electrical connection. If so, we really need to communicate |
@@ -1281,7 +1289,8 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1281 | struct atmel_mci_slot *slot = mmc_priv(mmc); | 1289 | struct atmel_mci_slot *slot = mmc_priv(mmc); |
1282 | struct atmel_mci *host = slot->host; | 1290 | struct atmel_mci *host = slot->host; |
1283 | unsigned int i; | 1291 | unsigned int i; |
1284 | bool unprepare_clk; | 1292 | |
1293 | pm_runtime_get_sync(&host->pdev->dev); | ||
1285 | 1294 | ||
1286 | slot->sdc_reg &= ~ATMCI_SDCBUS_MASK; | 1295 | slot->sdc_reg &= ~ATMCI_SDCBUS_MASK; |
1287 | switch (ios->bus_width) { | 1296 | switch (ios->bus_width) { |
@@ -1297,13 +1306,8 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1297 | unsigned int clock_min = ~0U; | 1306 | unsigned int clock_min = ~0U; |
1298 | u32 clkdiv; | 1307 | u32 clkdiv; |
1299 | 1308 | ||
1300 | clk_prepare(host->mck); | ||
1301 | unprepare_clk = true; | ||
1302 | |||
1303 | spin_lock_bh(&host->lock); | 1309 | spin_lock_bh(&host->lock); |
1304 | if (!host->mode_reg) { | 1310 | if (!host->mode_reg) { |
1305 | clk_enable(host->mck); | ||
1306 | unprepare_clk = false; | ||
1307 | atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); | 1311 | atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); |
1308 | atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN); | 1312 | atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN); |
1309 | if (host->caps.has_cfg_reg) | 1313 | if (host->caps.has_cfg_reg) |
@@ -1371,8 +1375,6 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1371 | } else { | 1375 | } else { |
1372 | bool any_slot_active = false; | 1376 | bool any_slot_active = false; |
1373 | 1377 | ||
1374 | unprepare_clk = false; | ||
1375 | |||
1376 | spin_lock_bh(&host->lock); | 1378 | spin_lock_bh(&host->lock); |
1377 | slot->clock = 0; | 1379 | slot->clock = 0; |
1378 | for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { | 1380 | for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { |
@@ -1385,17 +1387,12 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1385 | atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS); | 1387 | atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS); |
1386 | if (host->mode_reg) { | 1388 | if (host->mode_reg) { |
1387 | atmci_readl(host, ATMCI_MR); | 1389 | atmci_readl(host, ATMCI_MR); |
1388 | clk_disable(host->mck); | ||
1389 | unprepare_clk = true; | ||
1390 | } | 1390 | } |
1391 | host->mode_reg = 0; | 1391 | host->mode_reg = 0; |
1392 | } | 1392 | } |
1393 | spin_unlock_bh(&host->lock); | 1393 | spin_unlock_bh(&host->lock); |
1394 | } | 1394 | } |
1395 | 1395 | ||
1396 | if (unprepare_clk) | ||
1397 | clk_unprepare(host->mck); | ||
1398 | |||
1399 | switch (ios->power_mode) { | 1396 | switch (ios->power_mode) { |
1400 | case MMC_POWER_OFF: | 1397 | case MMC_POWER_OFF: |
1401 | if (!IS_ERR(mmc->supply.vmmc)) | 1398 | if (!IS_ERR(mmc->supply.vmmc)) |
@@ -1421,6 +1418,9 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1421 | */ | 1418 | */ |
1422 | break; | 1419 | break; |
1423 | } | 1420 | } |
1421 | |||
1422 | pm_runtime_mark_last_busy(&host->pdev->dev); | ||
1423 | pm_runtime_put_autosuspend(&host->pdev->dev); | ||
1424 | } | 1424 | } |
1425 | 1425 | ||
1426 | static int atmci_get_ro(struct mmc_host *mmc) | 1426 | static int atmci_get_ro(struct mmc_host *mmc) |
@@ -1512,6 +1512,9 @@ static void atmci_request_end(struct atmel_mci *host, struct mmc_request *mrq) | |||
1512 | spin_unlock(&host->lock); | 1512 | spin_unlock(&host->lock); |
1513 | mmc_request_done(prev_mmc, mrq); | 1513 | mmc_request_done(prev_mmc, mrq); |
1514 | spin_lock(&host->lock); | 1514 | spin_lock(&host->lock); |
1515 | |||
1516 | pm_runtime_mark_last_busy(&host->pdev->dev); | ||
1517 | pm_runtime_put_autosuspend(&host->pdev->dev); | ||
1515 | } | 1518 | } |
1516 | 1519 | ||
1517 | static void atmci_command_complete(struct atmel_mci *host, | 1520 | static void atmci_command_complete(struct atmel_mci *host, |
@@ -2137,7 +2140,7 @@ static irqreturn_t atmci_detect_interrupt(int irq, void *dev_id) | |||
2137 | return IRQ_HANDLED; | 2140 | return IRQ_HANDLED; |
2138 | } | 2141 | } |
2139 | 2142 | ||
2140 | static int __init atmci_init_slot(struct atmel_mci *host, | 2143 | static int atmci_init_slot(struct atmel_mci *host, |
2141 | struct mci_slot_pdata *slot_data, unsigned int id, | 2144 | struct mci_slot_pdata *slot_data, unsigned int id, |
2142 | u32 sdc_reg, u32 sdio_irq) | 2145 | u32 sdc_reg, u32 sdio_irq) |
2143 | { | 2146 | { |
@@ -2206,8 +2209,12 @@ static int __init atmci_init_slot(struct atmel_mci *host, | |||
2206 | } | 2209 | } |
2207 | } | 2210 | } |
2208 | 2211 | ||
2209 | if (!gpio_is_valid(slot->detect_pin)) | 2212 | if (!gpio_is_valid(slot->detect_pin)) { |
2210 | mmc->caps |= MMC_CAP_NEEDS_POLL; | 2213 | if (slot_data->non_removable) |
2214 | mmc->caps |= MMC_CAP_NONREMOVABLE; | ||
2215 | else | ||
2216 | mmc->caps |= MMC_CAP_NEEDS_POLL; | ||
2217 | } | ||
2211 | 2218 | ||
2212 | if (gpio_is_valid(slot->wp_pin)) { | 2219 | if (gpio_is_valid(slot->wp_pin)) { |
2213 | if (devm_gpio_request(&host->pdev->dev, slot->wp_pin, | 2220 | if (devm_gpio_request(&host->pdev->dev, slot->wp_pin, |
@@ -2265,55 +2272,25 @@ static void atmci_cleanup_slot(struct atmel_mci_slot *slot, | |||
2265 | mmc_free_host(slot->mmc); | 2272 | mmc_free_host(slot->mmc); |
2266 | } | 2273 | } |
2267 | 2274 | ||
2268 | static bool atmci_filter(struct dma_chan *chan, void *pdata) | 2275 | static int atmci_configure_dma(struct atmel_mci *host) |
2269 | { | 2276 | { |
2270 | struct mci_platform_data *sl_pdata = pdata; | 2277 | host->dma.chan = dma_request_slave_channel_reason(&host->pdev->dev, |
2271 | struct mci_dma_data *sl; | 2278 | "rxtx"); |
2272 | 2279 | if (IS_ERR(host->dma.chan)) | |
2273 | if (!sl_pdata) | 2280 | return PTR_ERR(host->dma.chan); |
2274 | return false; | 2281 | |
2282 | dev_info(&host->pdev->dev, "using %s for DMA transfers\n", | ||
2283 | dma_chan_name(host->dma.chan)); | ||
2284 | |||
2285 | host->dma_conf.src_addr = host->mapbase + ATMCI_RDR; | ||
2286 | host->dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
2287 | host->dma_conf.src_maxburst = 1; | ||
2288 | host->dma_conf.dst_addr = host->mapbase + ATMCI_TDR; | ||
2289 | host->dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
2290 | host->dma_conf.dst_maxburst = 1; | ||
2291 | host->dma_conf.device_fc = false; | ||
2275 | 2292 | ||
2276 | sl = sl_pdata->dma_slave; | 2293 | return 0; |
2277 | if (sl && find_slave_dev(sl) == chan->device->dev) { | ||
2278 | chan->private = slave_data_ptr(sl); | ||
2279 | return true; | ||
2280 | } else { | ||
2281 | return false; | ||
2282 | } | ||
2283 | } | ||
2284 | |||
2285 | static bool atmci_configure_dma(struct atmel_mci *host) | ||
2286 | { | ||
2287 | struct mci_platform_data *pdata; | ||
2288 | dma_cap_mask_t mask; | ||
2289 | |||
2290 | if (host == NULL) | ||
2291 | return false; | ||
2292 | |||
2293 | pdata = host->pdev->dev.platform_data; | ||
2294 | |||
2295 | dma_cap_zero(mask); | ||
2296 | dma_cap_set(DMA_SLAVE, mask); | ||
2297 | |||
2298 | host->dma.chan = dma_request_slave_channel_compat(mask, atmci_filter, pdata, | ||
2299 | &host->pdev->dev, "rxtx"); | ||
2300 | if (!host->dma.chan) { | ||
2301 | dev_warn(&host->pdev->dev, "no DMA channel available\n"); | ||
2302 | return false; | ||
2303 | } else { | ||
2304 | dev_info(&host->pdev->dev, | ||
2305 | "using %s for DMA transfers\n", | ||
2306 | dma_chan_name(host->dma.chan)); | ||
2307 | |||
2308 | host->dma_conf.src_addr = host->mapbase + ATMCI_RDR; | ||
2309 | host->dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
2310 | host->dma_conf.src_maxburst = 1; | ||
2311 | host->dma_conf.dst_addr = host->mapbase + ATMCI_TDR; | ||
2312 | host->dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
2313 | host->dma_conf.dst_maxburst = 1; | ||
2314 | host->dma_conf.device_fc = false; | ||
2315 | return true; | ||
2316 | } | ||
2317 | } | 2294 | } |
2318 | 2295 | ||
2319 | /* | 2296 | /* |
@@ -2321,7 +2298,7 @@ static bool atmci_configure_dma(struct atmel_mci *host) | |||
2321 | * HSMCI provides DMA support and a new config register but no more supports | 2298 | * HSMCI provides DMA support and a new config register but no more supports |
2322 | * PDC. | 2299 | * PDC. |
2323 | */ | 2300 | */ |
2324 | static void __init atmci_get_cap(struct atmel_mci *host) | 2301 | static void atmci_get_cap(struct atmel_mci *host) |
2325 | { | 2302 | { |
2326 | unsigned int version; | 2303 | unsigned int version; |
2327 | 2304 | ||
@@ -2370,7 +2347,7 @@ static void __init atmci_get_cap(struct atmel_mci *host) | |||
2370 | } | 2347 | } |
2371 | } | 2348 | } |
2372 | 2349 | ||
2373 | static int __init atmci_probe(struct platform_device *pdev) | 2350 | static int atmci_probe(struct platform_device *pdev) |
2374 | { | 2351 | { |
2375 | struct mci_platform_data *pdata; | 2352 | struct mci_platform_data *pdata; |
2376 | struct atmel_mci *host; | 2353 | struct atmel_mci *host; |
@@ -2417,19 +2394,23 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
2417 | 2394 | ||
2418 | atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); | 2395 | atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); |
2419 | host->bus_hz = clk_get_rate(host->mck); | 2396 | host->bus_hz = clk_get_rate(host->mck); |
2420 | clk_disable_unprepare(host->mck); | ||
2421 | 2397 | ||
2422 | host->mapbase = regs->start; | 2398 | host->mapbase = regs->start; |
2423 | 2399 | ||
2424 | tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)host); | 2400 | tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)host); |
2425 | 2401 | ||
2426 | ret = request_irq(irq, atmci_interrupt, 0, dev_name(&pdev->dev), host); | 2402 | ret = request_irq(irq, atmci_interrupt, 0, dev_name(&pdev->dev), host); |
2427 | if (ret) | 2403 | if (ret) { |
2404 | clk_disable_unprepare(host->mck); | ||
2428 | return ret; | 2405 | return ret; |
2406 | } | ||
2429 | 2407 | ||
2430 | /* Get MCI capabilities and set operations according to it */ | 2408 | /* Get MCI capabilities and set operations according to it */ |
2431 | atmci_get_cap(host); | 2409 | atmci_get_cap(host); |
2432 | if (atmci_configure_dma(host)) { | 2410 | ret = atmci_configure_dma(host); |
2411 | if (ret == -EPROBE_DEFER) | ||
2412 | goto err_dma_probe_defer; | ||
2413 | if (ret == 0) { | ||
2433 | host->prepare_data = &atmci_prepare_data_dma; | 2414 | host->prepare_data = &atmci_prepare_data_dma; |
2434 | host->submit_data = &atmci_submit_data_dma; | 2415 | host->submit_data = &atmci_submit_data_dma; |
2435 | host->stop_transfer = &atmci_stop_transfer_dma; | 2416 | host->stop_transfer = &atmci_stop_transfer_dma; |
@@ -2449,6 +2430,12 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
2449 | 2430 | ||
2450 | setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); | 2431 | setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); |
2451 | 2432 | ||
2433 | pm_runtime_get_noresume(&pdev->dev); | ||
2434 | pm_runtime_set_active(&pdev->dev); | ||
2435 | pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_DELAY); | ||
2436 | pm_runtime_use_autosuspend(&pdev->dev); | ||
2437 | pm_runtime_enable(&pdev->dev); | ||
2438 | |||
2452 | /* We need at least one slot to succeed */ | 2439 | /* We need at least one slot to succeed */ |
2453 | nr_slots = 0; | 2440 | nr_slots = 0; |
2454 | ret = -ENODEV; | 2441 | ret = -ENODEV; |
@@ -2491,6 +2478,9 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
2491 | "Atmel MCI controller at 0x%08lx irq %d, %u slots\n", | 2478 | "Atmel MCI controller at 0x%08lx irq %d, %u slots\n", |
2492 | host->mapbase, irq, nr_slots); | 2479 | host->mapbase, irq, nr_slots); |
2493 | 2480 | ||
2481 | pm_runtime_mark_last_busy(&host->pdev->dev); | ||
2482 | pm_runtime_put_autosuspend(&pdev->dev); | ||
2483 | |||
2494 | return 0; | 2484 | return 0; |
2495 | 2485 | ||
2496 | err_dma_alloc: | 2486 | err_dma_alloc: |
@@ -2499,18 +2489,26 @@ err_dma_alloc: | |||
2499 | atmci_cleanup_slot(host->slot[i], i); | 2489 | atmci_cleanup_slot(host->slot[i], i); |
2500 | } | 2490 | } |
2501 | err_init_slot: | 2491 | err_init_slot: |
2492 | clk_disable_unprepare(host->mck); | ||
2493 | |||
2494 | pm_runtime_disable(&pdev->dev); | ||
2495 | pm_runtime_put_noidle(&pdev->dev); | ||
2496 | |||
2502 | del_timer_sync(&host->timer); | 2497 | del_timer_sync(&host->timer); |
2503 | if (host->dma.chan) | 2498 | if (!IS_ERR(host->dma.chan)) |
2504 | dma_release_channel(host->dma.chan); | 2499 | dma_release_channel(host->dma.chan); |
2500 | err_dma_probe_defer: | ||
2505 | free_irq(irq, host); | 2501 | free_irq(irq, host); |
2506 | return ret; | 2502 | return ret; |
2507 | } | 2503 | } |
2508 | 2504 | ||
2509 | static int __exit atmci_remove(struct platform_device *pdev) | 2505 | static int atmci_remove(struct platform_device *pdev) |
2510 | { | 2506 | { |
2511 | struct atmel_mci *host = platform_get_drvdata(pdev); | 2507 | struct atmel_mci *host = platform_get_drvdata(pdev); |
2512 | unsigned int i; | 2508 | unsigned int i; |
2513 | 2509 | ||
2510 | pm_runtime_get_sync(&pdev->dev); | ||
2511 | |||
2514 | if (host->buffer) | 2512 | if (host->buffer) |
2515 | dma_free_coherent(&pdev->dev, host->buf_size, | 2513 | dma_free_coherent(&pdev->dev, host->buf_size, |
2516 | host->buffer, host->buf_phys_addr); | 2514 | host->buffer, host->buf_phys_addr); |
@@ -2520,41 +2518,62 @@ static int __exit atmci_remove(struct platform_device *pdev) | |||
2520 | atmci_cleanup_slot(host->slot[i], i); | 2518 | atmci_cleanup_slot(host->slot[i], i); |
2521 | } | 2519 | } |
2522 | 2520 | ||
2523 | clk_prepare_enable(host->mck); | ||
2524 | atmci_writel(host, ATMCI_IDR, ~0UL); | 2521 | atmci_writel(host, ATMCI_IDR, ~0UL); |
2525 | atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS); | 2522 | atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS); |
2526 | atmci_readl(host, ATMCI_SR); | 2523 | atmci_readl(host, ATMCI_SR); |
2527 | clk_disable_unprepare(host->mck); | ||
2528 | 2524 | ||
2529 | del_timer_sync(&host->timer); | 2525 | del_timer_sync(&host->timer); |
2530 | if (host->dma.chan) | 2526 | if (!IS_ERR(host->dma.chan)) |
2531 | dma_release_channel(host->dma.chan); | 2527 | dma_release_channel(host->dma.chan); |
2532 | 2528 | ||
2533 | free_irq(platform_get_irq(pdev, 0), host); | 2529 | free_irq(platform_get_irq(pdev, 0), host); |
2534 | 2530 | ||
2531 | clk_disable_unprepare(host->mck); | ||
2532 | |||
2533 | pm_runtime_disable(&pdev->dev); | ||
2534 | pm_runtime_put_noidle(&pdev->dev); | ||
2535 | |||
2535 | return 0; | 2536 | return 0; |
2536 | } | 2537 | } |
2537 | 2538 | ||
2538 | static struct platform_driver atmci_driver = { | 2539 | #ifdef CONFIG_PM |
2539 | .remove = __exit_p(atmci_remove), | 2540 | static int atmci_runtime_suspend(struct device *dev) |
2540 | .driver = { | ||
2541 | .name = "atmel_mci", | ||
2542 | .of_match_table = of_match_ptr(atmci_dt_ids), | ||
2543 | }, | ||
2544 | }; | ||
2545 | |||
2546 | static int __init atmci_init(void) | ||
2547 | { | 2541 | { |
2548 | return platform_driver_probe(&atmci_driver, atmci_probe); | 2542 | struct atmel_mci *host = dev_get_drvdata(dev); |
2543 | |||
2544 | clk_disable_unprepare(host->mck); | ||
2545 | |||
2546 | pinctrl_pm_select_sleep_state(dev); | ||
2547 | |||
2548 | return 0; | ||
2549 | } | 2549 | } |
2550 | 2550 | ||
2551 | static void __exit atmci_exit(void) | 2551 | static int atmci_runtime_resume(struct device *dev) |
2552 | { | 2552 | { |
2553 | platform_driver_unregister(&atmci_driver); | 2553 | struct atmel_mci *host = dev_get_drvdata(dev); |
2554 | |||
2555 | pinctrl_pm_select_default_state(dev); | ||
2556 | |||
2557 | return clk_prepare_enable(host->mck); | ||
2554 | } | 2558 | } |
2559 | #endif | ||
2555 | 2560 | ||
2556 | late_initcall(atmci_init); /* try to load after dma driver when built-in */ | 2561 | static const struct dev_pm_ops atmci_dev_pm_ops = { |
2557 | module_exit(atmci_exit); | 2562 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
2563 | pm_runtime_force_resume) | ||
2564 | SET_PM_RUNTIME_PM_OPS(atmci_runtime_suspend, atmci_runtime_resume, NULL) | ||
2565 | }; | ||
2566 | |||
2567 | static struct platform_driver atmci_driver = { | ||
2568 | .probe = atmci_probe, | ||
2569 | .remove = atmci_remove, | ||
2570 | .driver = { | ||
2571 | .name = "atmel_mci", | ||
2572 | .of_match_table = of_match_ptr(atmci_dt_ids), | ||
2573 | .pm = &atmci_dev_pm_ops, | ||
2574 | }, | ||
2575 | }; | ||
2576 | module_platform_driver(atmci_driver); | ||
2558 | 2577 | ||
2559 | MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver"); | 2578 | MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver"); |
2560 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); | 2579 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); |
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index 0fbc53ac7eae..509365cb22c6 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #define NUM_PINS(x) (x + 2) | 25 | #define NUM_PINS(x) (x + 2) |
26 | 26 | ||
27 | #define SDMMC_CLKSEL 0x09C | 27 | #define SDMMC_CLKSEL 0x09C |
28 | #define SDMMC_CLKSEL64 0x0A8 | ||
28 | #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0) | 29 | #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0) |
29 | #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) | 30 | #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) |
30 | #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) | 31 | #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) |
@@ -65,6 +66,8 @@ enum dw_mci_exynos_type { | |||
65 | DW_MCI_TYPE_EXYNOS5250, | 66 | DW_MCI_TYPE_EXYNOS5250, |
66 | DW_MCI_TYPE_EXYNOS5420, | 67 | DW_MCI_TYPE_EXYNOS5420, |
67 | DW_MCI_TYPE_EXYNOS5420_SMU, | 68 | DW_MCI_TYPE_EXYNOS5420_SMU, |
69 | DW_MCI_TYPE_EXYNOS7, | ||
70 | DW_MCI_TYPE_EXYNOS7_SMU, | ||
68 | }; | 71 | }; |
69 | 72 | ||
70 | /* Exynos implementation specific driver private data */ | 73 | /* Exynos implementation specific driver private data */ |
@@ -95,6 +98,12 @@ static struct dw_mci_exynos_compatible { | |||
95 | }, { | 98 | }, { |
96 | .compatible = "samsung,exynos5420-dw-mshc-smu", | 99 | .compatible = "samsung,exynos5420-dw-mshc-smu", |
97 | .ctrl_type = DW_MCI_TYPE_EXYNOS5420_SMU, | 100 | .ctrl_type = DW_MCI_TYPE_EXYNOS5420_SMU, |
101 | }, { | ||
102 | .compatible = "samsung,exynos7-dw-mshc", | ||
103 | .ctrl_type = DW_MCI_TYPE_EXYNOS7, | ||
104 | }, { | ||
105 | .compatible = "samsung,exynos7-dw-mshc-smu", | ||
106 | .ctrl_type = DW_MCI_TYPE_EXYNOS7_SMU, | ||
98 | }, | 107 | }, |
99 | }; | 108 | }; |
100 | 109 | ||
@@ -102,7 +111,8 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) | |||
102 | { | 111 | { |
103 | struct dw_mci_exynos_priv_data *priv = host->priv; | 112 | struct dw_mci_exynos_priv_data *priv = host->priv; |
104 | 113 | ||
105 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5420_SMU) { | 114 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5420_SMU || |
115 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) { | ||
106 | mci_writel(host, MPSBEGIN0, 0); | 116 | mci_writel(host, MPSBEGIN0, 0); |
107 | mci_writel(host, MPSEND0, DWMCI_BLOCK_NUM); | 117 | mci_writel(host, MPSEND0, DWMCI_BLOCK_NUM); |
108 | mci_writel(host, MPSCTRL0, DWMCI_MPSCTRL_SECURE_WRITE_BIT | | 118 | mci_writel(host, MPSCTRL0, DWMCI_MPSCTRL_SECURE_WRITE_BIT | |
@@ -153,11 +163,22 @@ static int dw_mci_exynos_resume(struct device *dev) | |||
153 | static int dw_mci_exynos_resume_noirq(struct device *dev) | 163 | static int dw_mci_exynos_resume_noirq(struct device *dev) |
154 | { | 164 | { |
155 | struct dw_mci *host = dev_get_drvdata(dev); | 165 | struct dw_mci *host = dev_get_drvdata(dev); |
166 | struct dw_mci_exynos_priv_data *priv = host->priv; | ||
156 | u32 clksel; | 167 | u32 clksel; |
157 | 168 | ||
158 | clksel = mci_readl(host, CLKSEL); | 169 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || |
159 | if (clksel & SDMMC_CLKSEL_WAKEUP_INT) | 170 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) |
160 | mci_writel(host, CLKSEL, clksel); | 171 | clksel = mci_readl(host, CLKSEL64); |
172 | else | ||
173 | clksel = mci_readl(host, CLKSEL); | ||
174 | |||
175 | if (clksel & SDMMC_CLKSEL_WAKEUP_INT) { | ||
176 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || | ||
177 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) | ||
178 | mci_writel(host, CLKSEL64, clksel); | ||
179 | else | ||
180 | mci_writel(host, CLKSEL, clksel); | ||
181 | } | ||
161 | 182 | ||
162 | return 0; | 183 | return 0; |
163 | } | 184 | } |
@@ -169,6 +190,7 @@ static int dw_mci_exynos_resume_noirq(struct device *dev) | |||
169 | 190 | ||
170 | static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) | 191 | static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) |
171 | { | 192 | { |
193 | struct dw_mci_exynos_priv_data *priv = host->priv; | ||
172 | /* | 194 | /* |
173 | * Exynos4412 and Exynos5250 extends the use of CMD register with the | 195 | * Exynos4412 and Exynos5250 extends the use of CMD register with the |
174 | * use of bit 29 (which is reserved on standard MSHC controllers) for | 196 | * use of bit 29 (which is reserved on standard MSHC controllers) for |
@@ -176,8 +198,14 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) | |||
176 | * HOLD register should be bypassed in case there is no phase shift | 198 | * HOLD register should be bypassed in case there is no phase shift |
177 | * applied on CMD/DATA that is sent to the card. | 199 | * applied on CMD/DATA that is sent to the card. |
178 | */ | 200 | */ |
179 | if (SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL))) | 201 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || |
180 | *cmdr |= SDMMC_CMD_USE_HOLD_REG; | 202 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) { |
203 | if (SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL64))) | ||
204 | *cmdr |= SDMMC_CMD_USE_HOLD_REG; | ||
205 | } else { | ||
206 | if (SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL))) | ||
207 | *cmdr |= SDMMC_CMD_USE_HOLD_REG; | ||
208 | } | ||
181 | } | 209 | } |
182 | 210 | ||
183 | static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) | 211 | static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) |
@@ -188,12 +216,20 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) | |||
188 | u8 div = priv->ciu_div + 1; | 216 | u8 div = priv->ciu_div + 1; |
189 | 217 | ||
190 | if (ios->timing == MMC_TIMING_MMC_DDR52) { | 218 | if (ios->timing == MMC_TIMING_MMC_DDR52) { |
191 | mci_writel(host, CLKSEL, priv->ddr_timing); | 219 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || |
220 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) | ||
221 | mci_writel(host, CLKSEL64, priv->ddr_timing); | ||
222 | else | ||
223 | mci_writel(host, CLKSEL, priv->ddr_timing); | ||
192 | /* Should be double rate for DDR mode */ | 224 | /* Should be double rate for DDR mode */ |
193 | if (ios->bus_width == MMC_BUS_WIDTH_8) | 225 | if (ios->bus_width == MMC_BUS_WIDTH_8) |
194 | wanted <<= 1; | 226 | wanted <<= 1; |
195 | } else { | 227 | } else { |
196 | mci_writel(host, CLKSEL, priv->sdr_timing); | 228 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || |
229 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) | ||
230 | mci_writel(host, CLKSEL64, priv->sdr_timing); | ||
231 | else | ||
232 | mci_writel(host, CLKSEL, priv->sdr_timing); | ||
197 | } | 233 | } |
198 | 234 | ||
199 | /* Don't care if wanted clock is zero */ | 235 | /* Don't care if wanted clock is zero */ |
@@ -265,26 +301,51 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host) | |||
265 | 301 | ||
266 | static inline u8 dw_mci_exynos_get_clksmpl(struct dw_mci *host) | 302 | static inline u8 dw_mci_exynos_get_clksmpl(struct dw_mci *host) |
267 | { | 303 | { |
268 | return SDMMC_CLKSEL_CCLK_SAMPLE(mci_readl(host, CLKSEL)); | 304 | struct dw_mci_exynos_priv_data *priv = host->priv; |
305 | |||
306 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || | ||
307 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) | ||
308 | return SDMMC_CLKSEL_CCLK_SAMPLE(mci_readl(host, CLKSEL64)); | ||
309 | else | ||
310 | return SDMMC_CLKSEL_CCLK_SAMPLE(mci_readl(host, CLKSEL)); | ||
269 | } | 311 | } |
270 | 312 | ||
271 | static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample) | 313 | static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample) |
272 | { | 314 | { |
273 | u32 clksel; | 315 | u32 clksel; |
274 | clksel = mci_readl(host, CLKSEL); | 316 | struct dw_mci_exynos_priv_data *priv = host->priv; |
317 | |||
318 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || | ||
319 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) | ||
320 | clksel = mci_readl(host, CLKSEL64); | ||
321 | else | ||
322 | clksel = mci_readl(host, CLKSEL); | ||
275 | clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample); | 323 | clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample); |
276 | mci_writel(host, CLKSEL, clksel); | 324 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || |
325 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) | ||
326 | mci_writel(host, CLKSEL64, clksel); | ||
327 | else | ||
328 | mci_writel(host, CLKSEL, clksel); | ||
277 | } | 329 | } |
278 | 330 | ||
279 | static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host) | 331 | static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host) |
280 | { | 332 | { |
333 | struct dw_mci_exynos_priv_data *priv = host->priv; | ||
281 | u32 clksel; | 334 | u32 clksel; |
282 | u8 sample; | 335 | u8 sample; |
283 | 336 | ||
284 | clksel = mci_readl(host, CLKSEL); | 337 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || |
338 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) | ||
339 | clksel = mci_readl(host, CLKSEL64); | ||
340 | else | ||
341 | clksel = mci_readl(host, CLKSEL); | ||
285 | sample = (clksel + 1) & 0x7; | 342 | sample = (clksel + 1) & 0x7; |
286 | clksel = (clksel & ~0x7) | sample; | 343 | clksel = (clksel & ~0x7) | sample; |
287 | mci_writel(host, CLKSEL, clksel); | 344 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || |
345 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) | ||
346 | mci_writel(host, CLKSEL64, clksel); | ||
347 | else | ||
348 | mci_writel(host, CLKSEL, clksel); | ||
288 | return sample; | 349 | return sample; |
289 | } | 350 | } |
290 | 351 | ||
@@ -411,6 +472,10 @@ static const struct of_device_id dw_mci_exynos_match[] = { | |||
411 | .data = &exynos_drv_data, }, | 472 | .data = &exynos_drv_data, }, |
412 | { .compatible = "samsung,exynos5420-dw-mshc-smu", | 473 | { .compatible = "samsung,exynos5420-dw-mshc-smu", |
413 | .data = &exynos_drv_data, }, | 474 | .data = &exynos_drv_data, }, |
475 | { .compatible = "samsung,exynos7-dw-mshc", | ||
476 | .data = &exynos_drv_data, }, | ||
477 | { .compatible = "samsung,exynos7-dw-mshc-smu", | ||
478 | .data = &exynos_drv_data, }, | ||
414 | {}, | 479 | {}, |
415 | }; | 480 | }; |
416 | MODULE_DEVICE_TABLE(of, dw_mci_exynos_match); | 481 | MODULE_DEVICE_TABLE(of, dw_mci_exynos_match); |
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index 8b6572162ed9..ec6dbcdec693 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c | |||
@@ -35,6 +35,10 @@ static const struct dw_mci_drv_data socfpga_drv_data = { | |||
35 | .prepare_command = dw_mci_pltfm_prepare_command, | 35 | .prepare_command = dw_mci_pltfm_prepare_command, |
36 | }; | 36 | }; |
37 | 37 | ||
38 | static const struct dw_mci_drv_data pistachio_drv_data = { | ||
39 | .prepare_command = dw_mci_pltfm_prepare_command, | ||
40 | }; | ||
41 | |||
38 | int dw_mci_pltfm_register(struct platform_device *pdev, | 42 | int dw_mci_pltfm_register(struct platform_device *pdev, |
39 | const struct dw_mci_drv_data *drv_data) | 43 | const struct dw_mci_drv_data *drv_data) |
40 | { | 44 | { |
@@ -90,6 +94,8 @@ static const struct of_device_id dw_mci_pltfm_match[] = { | |||
90 | { .compatible = "snps,dw-mshc", }, | 94 | { .compatible = "snps,dw-mshc", }, |
91 | { .compatible = "altr,socfpga-dw-mshc", | 95 | { .compatible = "altr,socfpga-dw-mshc", |
92 | .data = &socfpga_drv_data }, | 96 | .data = &socfpga_drv_data }, |
97 | { .compatible = "img,pistachio-dw-mshc", | ||
98 | .data = &pistachio_drv_data }, | ||
93 | {}, | 99 | {}, |
94 | }; | 100 | }; |
95 | MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); | 101 | MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); |
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index f0c2cb1a210d..5650ac488cf3 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c | |||
@@ -37,6 +37,9 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) | |||
37 | unsigned int cclkin; | 37 | unsigned int cclkin; |
38 | u32 bus_hz; | 38 | u32 bus_hz; |
39 | 39 | ||
40 | if (ios->clock == 0) | ||
41 | return; | ||
42 | |||
40 | /* | 43 | /* |
41 | * cclkin: source clock of mmc controller | 44 | * cclkin: source clock of mmc controller |
42 | * bus_hz: card interface clock generated by CLKGEN | 45 | * bus_hz: card interface clock generated by CLKGEN |
@@ -65,14 +68,24 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) | |||
65 | } | 68 | } |
66 | } | 69 | } |
67 | 70 | ||
71 | static int dw_mci_rockchip_init(struct dw_mci *host) | ||
72 | { | ||
73 | /* It is slot 8 on Rockchip SoCs */ | ||
74 | host->sdio_id0 = 8; | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
68 | static const struct dw_mci_drv_data rk2928_drv_data = { | 79 | static const struct dw_mci_drv_data rk2928_drv_data = { |
69 | .prepare_command = dw_mci_rockchip_prepare_command, | 80 | .prepare_command = dw_mci_rockchip_prepare_command, |
81 | .init = dw_mci_rockchip_init, | ||
70 | }; | 82 | }; |
71 | 83 | ||
72 | static const struct dw_mci_drv_data rk3288_drv_data = { | 84 | static const struct dw_mci_drv_data rk3288_drv_data = { |
73 | .prepare_command = dw_mci_rockchip_prepare_command, | 85 | .prepare_command = dw_mci_rockchip_prepare_command, |
74 | .set_ios = dw_mci_rk3288_set_ios, | 86 | .set_ios = dw_mci_rk3288_set_ios, |
75 | .setup_clock = dw_mci_rk3288_setup_clock, | 87 | .setup_clock = dw_mci_rk3288_setup_clock, |
88 | .init = dw_mci_rockchip_init, | ||
76 | }; | 89 | }; |
77 | 90 | ||
78 | static const struct of_device_id dw_mci_rockchip_match[] = { | 91 | static const struct of_device_id dw_mci_rockchip_match[] = { |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 69f0cc68d5b2..67c04518ec4c 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/mmc/dw_mmc.h> | 34 | #include <linux/mmc/dw_mmc.h> |
35 | #include <linux/bitops.h> | 35 | #include <linux/bitops.h> |
36 | #include <linux/regulator/consumer.h> | 36 | #include <linux/regulator/consumer.h> |
37 | #include <linux/workqueue.h> | ||
38 | #include <linux/of.h> | 37 | #include <linux/of.h> |
39 | #include <linux/of_gpio.h> | 38 | #include <linux/of_gpio.h> |
40 | #include <linux/mmc/slot-gpio.h> | 39 | #include <linux/mmc/slot-gpio.h> |
@@ -62,6 +61,24 @@ | |||
62 | SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \ | 61 | SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \ |
63 | SDMMC_IDMAC_INT_TI) | 62 | SDMMC_IDMAC_INT_TI) |
64 | 63 | ||
64 | struct idmac_desc_64addr { | ||
65 | u32 des0; /* Control Descriptor */ | ||
66 | |||
67 | u32 des1; /* Reserved */ | ||
68 | |||
69 | u32 des2; /*Buffer sizes */ | ||
70 | #define IDMAC_64ADDR_SET_BUFFER1_SIZE(d, s) \ | ||
71 | ((d)->des2 = ((d)->des2 & 0x03ffe000) | ((s) & 0x1fff)) | ||
72 | |||
73 | u32 des3; /* Reserved */ | ||
74 | |||
75 | u32 des4; /* Lower 32-bits of Buffer Address Pointer 1*/ | ||
76 | u32 des5; /* Upper 32-bits of Buffer Address Pointer 1*/ | ||
77 | |||
78 | u32 des6; /* Lower 32-bits of Next Descriptor Address */ | ||
79 | u32 des7; /* Upper 32-bits of Next Descriptor Address */ | ||
80 | }; | ||
81 | |||
65 | struct idmac_desc { | 82 | struct idmac_desc { |
66 | u32 des0; /* Control Descriptor */ | 83 | u32 des0; /* Control Descriptor */ |
67 | #define IDMAC_DES0_DIC BIT(1) | 84 | #define IDMAC_DES0_DIC BIT(1) |
@@ -83,6 +100,7 @@ struct idmac_desc { | |||
83 | #endif /* CONFIG_MMC_DW_IDMAC */ | 100 | #endif /* CONFIG_MMC_DW_IDMAC */ |
84 | 101 | ||
85 | static bool dw_mci_reset(struct dw_mci *host); | 102 | static bool dw_mci_reset(struct dw_mci *host); |
103 | static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset); | ||
86 | 104 | ||
87 | #if defined(CONFIG_DEBUG_FS) | 105 | #if defined(CONFIG_DEBUG_FS) |
88 | static int dw_mci_req_show(struct seq_file *s, void *v) | 106 | static int dw_mci_req_show(struct seq_file *s, void *v) |
@@ -414,30 +432,66 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, | |||
414 | unsigned int sg_len) | 432 | unsigned int sg_len) |
415 | { | 433 | { |
416 | int i; | 434 | int i; |
417 | struct idmac_desc *desc = host->sg_cpu; | 435 | if (host->dma_64bit_address == 1) { |
436 | struct idmac_desc_64addr *desc = host->sg_cpu; | ||
418 | 437 | ||
419 | for (i = 0; i < sg_len; i++, desc++) { | 438 | for (i = 0; i < sg_len; i++, desc++) { |
420 | unsigned int length = sg_dma_len(&data->sg[i]); | 439 | unsigned int length = sg_dma_len(&data->sg[i]); |
421 | u32 mem_addr = sg_dma_address(&data->sg[i]); | 440 | u64 mem_addr = sg_dma_address(&data->sg[i]); |
422 | 441 | ||
423 | /* Set the OWN bit and disable interrupts for this descriptor */ | 442 | /* |
424 | desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | IDMAC_DES0_CH; | 443 | * Set the OWN bit and disable interrupts for this |
444 | * descriptor | ||
445 | */ | ||
446 | desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | | ||
447 | IDMAC_DES0_CH; | ||
448 | /* Buffer length */ | ||
449 | IDMAC_64ADDR_SET_BUFFER1_SIZE(desc, length); | ||
450 | |||
451 | /* Physical address to DMA to/from */ | ||
452 | desc->des4 = mem_addr & 0xffffffff; | ||
453 | desc->des5 = mem_addr >> 32; | ||
454 | } | ||
425 | 455 | ||
426 | /* Buffer length */ | 456 | /* Set first descriptor */ |
427 | IDMAC_SET_BUFFER1_SIZE(desc, length); | 457 | desc = host->sg_cpu; |
458 | desc->des0 |= IDMAC_DES0_FD; | ||
428 | 459 | ||
429 | /* Physical address to DMA to/from */ | 460 | /* Set last descriptor */ |
430 | desc->des2 = mem_addr; | 461 | desc = host->sg_cpu + (i - 1) * |
431 | } | 462 | sizeof(struct idmac_desc_64addr); |
463 | desc->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC); | ||
464 | desc->des0 |= IDMAC_DES0_LD; | ||
432 | 465 | ||
433 | /* Set first descriptor */ | 466 | } else { |
434 | desc = host->sg_cpu; | 467 | struct idmac_desc *desc = host->sg_cpu; |
435 | desc->des0 |= IDMAC_DES0_FD; | 468 | |
469 | for (i = 0; i < sg_len; i++, desc++) { | ||
470 | unsigned int length = sg_dma_len(&data->sg[i]); | ||
471 | u32 mem_addr = sg_dma_address(&data->sg[i]); | ||
472 | |||
473 | /* | ||
474 | * Set the OWN bit and disable interrupts for this | ||
475 | * descriptor | ||
476 | */ | ||
477 | desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | | ||
478 | IDMAC_DES0_CH; | ||
479 | /* Buffer length */ | ||
480 | IDMAC_SET_BUFFER1_SIZE(desc, length); | ||
436 | 481 | ||
437 | /* Set last descriptor */ | 482 | /* Physical address to DMA to/from */ |
438 | desc = host->sg_cpu + (i - 1) * sizeof(struct idmac_desc); | 483 | desc->des2 = mem_addr; |
439 | desc->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC); | 484 | } |
440 | desc->des0 |= IDMAC_DES0_LD; | 485 | |
486 | /* Set first descriptor */ | ||
487 | desc = host->sg_cpu; | ||
488 | desc->des0 |= IDMAC_DES0_FD; | ||
489 | |||
490 | /* Set last descriptor */ | ||
491 | desc = host->sg_cpu + (i - 1) * sizeof(struct idmac_desc); | ||
492 | desc->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC); | ||
493 | desc->des0 |= IDMAC_DES0_LD; | ||
494 | } | ||
441 | 495 | ||
442 | wmb(); | 496 | wmb(); |
443 | } | 497 | } |
@@ -448,6 +502,10 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) | |||
448 | 502 | ||
449 | dw_mci_translate_sglist(host, host->data, sg_len); | 503 | dw_mci_translate_sglist(host, host->data, sg_len); |
450 | 504 | ||
505 | /* Make sure to reset DMA in case we did PIO before this */ | ||
506 | dw_mci_ctrl_reset(host, SDMMC_CTRL_DMA_RESET); | ||
507 | dw_mci_idmac_reset(host); | ||
508 | |||
451 | /* Select IDMAC interface */ | 509 | /* Select IDMAC interface */ |
452 | temp = mci_readl(host, CTRL); | 510 | temp = mci_readl(host, CTRL); |
453 | temp |= SDMMC_CTRL_USE_IDMAC; | 511 | temp |= SDMMC_CTRL_USE_IDMAC; |
@@ -466,29 +524,71 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) | |||
466 | 524 | ||
467 | static int dw_mci_idmac_init(struct dw_mci *host) | 525 | static int dw_mci_idmac_init(struct dw_mci *host) |
468 | { | 526 | { |
469 | struct idmac_desc *p; | ||
470 | int i; | 527 | int i; |
471 | 528 | ||
472 | /* Number of descriptors in the ring buffer */ | 529 | if (host->dma_64bit_address == 1) { |
473 | host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); | 530 | struct idmac_desc_64addr *p; |
531 | /* Number of descriptors in the ring buffer */ | ||
532 | host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc_64addr); | ||
533 | |||
534 | /* Forward link the descriptor list */ | ||
535 | for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; | ||
536 | i++, p++) { | ||
537 | p->des6 = (host->sg_dma + | ||
538 | (sizeof(struct idmac_desc_64addr) * | ||
539 | (i + 1))) & 0xffffffff; | ||
540 | |||
541 | p->des7 = (u64)(host->sg_dma + | ||
542 | (sizeof(struct idmac_desc_64addr) * | ||
543 | (i + 1))) >> 32; | ||
544 | /* Initialize reserved and buffer size fields to "0" */ | ||
545 | p->des1 = 0; | ||
546 | p->des2 = 0; | ||
547 | p->des3 = 0; | ||
548 | } | ||
549 | |||
550 | /* Set the last descriptor as the end-of-ring descriptor */ | ||
551 | p->des6 = host->sg_dma & 0xffffffff; | ||
552 | p->des7 = (u64)host->sg_dma >> 32; | ||
553 | p->des0 = IDMAC_DES0_ER; | ||
554 | |||
555 | } else { | ||
556 | struct idmac_desc *p; | ||
557 | /* Number of descriptors in the ring buffer */ | ||
558 | host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); | ||
474 | 559 | ||
475 | /* Forward link the descriptor list */ | 560 | /* Forward link the descriptor list */ |
476 | for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++) | 561 | for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++) |
477 | p->des3 = host->sg_dma + (sizeof(struct idmac_desc) * (i + 1)); | 562 | p->des3 = host->sg_dma + (sizeof(struct idmac_desc) * |
563 | (i + 1)); | ||
478 | 564 | ||
479 | /* Set the last descriptor as the end-of-ring descriptor */ | 565 | /* Set the last descriptor as the end-of-ring descriptor */ |
480 | p->des3 = host->sg_dma; | 566 | p->des3 = host->sg_dma; |
481 | p->des0 = IDMAC_DES0_ER; | 567 | p->des0 = IDMAC_DES0_ER; |
568 | } | ||
482 | 569 | ||
483 | dw_mci_idmac_reset(host); | 570 | dw_mci_idmac_reset(host); |
484 | 571 | ||
485 | /* Mask out interrupts - get Tx & Rx complete only */ | 572 | if (host->dma_64bit_address == 1) { |
486 | mci_writel(host, IDSTS, IDMAC_INT_CLR); | 573 | /* Mask out interrupts - get Tx & Rx complete only */ |
487 | mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI | | 574 | mci_writel(host, IDSTS64, IDMAC_INT_CLR); |
488 | SDMMC_IDMAC_INT_TI); | 575 | mci_writel(host, IDINTEN64, SDMMC_IDMAC_INT_NI | |
576 | SDMMC_IDMAC_INT_RI | SDMMC_IDMAC_INT_TI); | ||
577 | |||
578 | /* Set the descriptor base address */ | ||
579 | mci_writel(host, DBADDRL, host->sg_dma & 0xffffffff); | ||
580 | mci_writel(host, DBADDRU, (u64)host->sg_dma >> 32); | ||
581 | |||
582 | } else { | ||
583 | /* Mask out interrupts - get Tx & Rx complete only */ | ||
584 | mci_writel(host, IDSTS, IDMAC_INT_CLR); | ||
585 | mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | | ||
586 | SDMMC_IDMAC_INT_RI | SDMMC_IDMAC_INT_TI); | ||
587 | |||
588 | /* Set the descriptor base address */ | ||
589 | mci_writel(host, DBADDR, host->sg_dma); | ||
590 | } | ||
489 | 591 | ||
490 | /* Set the descriptor base address */ | ||
491 | mci_writel(host, DBADDR, host->sg_dma); | ||
492 | return 0; | 592 | return 0; |
493 | } | 593 | } |
494 | 594 | ||
@@ -626,6 +726,13 @@ static void dw_mci_ctrl_rd_thld(struct dw_mci *host, struct mmc_data *data) | |||
626 | 726 | ||
627 | WARN_ON(!(data->flags & MMC_DATA_READ)); | 727 | WARN_ON(!(data->flags & MMC_DATA_READ)); |
628 | 728 | ||
729 | /* | ||
730 | * CDTHRCTL doesn't exist prior to 240A (in fact that register offset is | ||
731 | * in the FIFO region, so we really shouldn't access it). | ||
732 | */ | ||
733 | if (host->verid < DW_MMC_240A) | ||
734 | return; | ||
735 | |||
629 | if (host->timing != MMC_TIMING_MMC_HS200 && | 736 | if (host->timing != MMC_TIMING_MMC_HS200 && |
630 | host->timing != MMC_TIMING_UHS_SDR104) | 737 | host->timing != MMC_TIMING_UHS_SDR104) |
631 | goto disable; | 738 | goto disable; |
@@ -819,7 +926,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) | |||
819 | 926 | ||
820 | /* enable clock; only low power if no SDIO */ | 927 | /* enable clock; only low power if no SDIO */ |
821 | clk_en_a = SDMMC_CLKEN_ENABLE << slot->id; | 928 | clk_en_a = SDMMC_CLKEN_ENABLE << slot->id; |
822 | if (!(mci_readl(host, INTMASK) & SDMMC_INT_SDIO(slot->id))) | 929 | if (!(mci_readl(host, INTMASK) & SDMMC_INT_SDIO(slot->sdio_id))) |
823 | clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id; | 930 | clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id; |
824 | mci_writel(host, CLKENA, clk_en_a); | 931 | mci_writel(host, CLKENA, clk_en_a); |
825 | 932 | ||
@@ -1075,7 +1182,7 @@ static int dw_mci_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1075 | ret = regulator_set_voltage(mmc->supply.vqmmc, min_uv, max_uv); | 1182 | ret = regulator_set_voltage(mmc->supply.vqmmc, min_uv, max_uv); |
1076 | 1183 | ||
1077 | if (ret) { | 1184 | if (ret) { |
1078 | dev_err(&mmc->class_dev, | 1185 | dev_dbg(&mmc->class_dev, |
1079 | "Regulator set error %d: %d - %d\n", | 1186 | "Regulator set error %d: %d - %d\n", |
1080 | ret, min_uv, max_uv); | 1187 | ret, min_uv, max_uv); |
1081 | return ret; | 1188 | return ret; |
@@ -1180,10 +1287,10 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb) | |||
1180 | dw_mci_disable_low_power(slot); | 1287 | dw_mci_disable_low_power(slot); |
1181 | 1288 | ||
1182 | mci_writel(host, INTMASK, | 1289 | mci_writel(host, INTMASK, |
1183 | (int_mask | SDMMC_INT_SDIO(slot->id))); | 1290 | (int_mask | SDMMC_INT_SDIO(slot->sdio_id))); |
1184 | } else { | 1291 | } else { |
1185 | mci_writel(host, INTMASK, | 1292 | mci_writel(host, INTMASK, |
1186 | (int_mask & ~SDMMC_INT_SDIO(slot->id))); | 1293 | (int_mask & ~SDMMC_INT_SDIO(slot->sdio_id))); |
1187 | } | 1294 | } |
1188 | } | 1295 | } |
1189 | 1296 | ||
@@ -1954,6 +2061,23 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) | |||
1954 | tasklet_schedule(&host->tasklet); | 2061 | tasklet_schedule(&host->tasklet); |
1955 | } | 2062 | } |
1956 | 2063 | ||
2064 | static void dw_mci_handle_cd(struct dw_mci *host) | ||
2065 | { | ||
2066 | int i; | ||
2067 | |||
2068 | for (i = 0; i < host->num_slots; i++) { | ||
2069 | struct dw_mci_slot *slot = host->slot[i]; | ||
2070 | |||
2071 | if (!slot) | ||
2072 | continue; | ||
2073 | |||
2074 | if (slot->mmc->ops->card_event) | ||
2075 | slot->mmc->ops->card_event(slot->mmc); | ||
2076 | mmc_detect_change(slot->mmc, | ||
2077 | msecs_to_jiffies(host->pdata->detect_delay_ms)); | ||
2078 | } | ||
2079 | } | ||
2080 | |||
1957 | static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | 2081 | static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) |
1958 | { | 2082 | { |
1959 | struct dw_mci *host = dev_id; | 2083 | struct dw_mci *host = dev_id; |
@@ -2029,14 +2153,15 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | |||
2029 | 2153 | ||
2030 | if (pending & SDMMC_INT_CD) { | 2154 | if (pending & SDMMC_INT_CD) { |
2031 | mci_writel(host, RINTSTS, SDMMC_INT_CD); | 2155 | mci_writel(host, RINTSTS, SDMMC_INT_CD); |
2032 | queue_work(host->card_workqueue, &host->card_work); | 2156 | dw_mci_handle_cd(host); |
2033 | } | 2157 | } |
2034 | 2158 | ||
2035 | /* Handle SDIO Interrupts */ | 2159 | /* Handle SDIO Interrupts */ |
2036 | for (i = 0; i < host->num_slots; i++) { | 2160 | for (i = 0; i < host->num_slots; i++) { |
2037 | struct dw_mci_slot *slot = host->slot[i]; | 2161 | struct dw_mci_slot *slot = host->slot[i]; |
2038 | if (pending & SDMMC_INT_SDIO(i)) { | 2162 | if (pending & SDMMC_INT_SDIO(slot->sdio_id)) { |
2039 | mci_writel(host, RINTSTS, SDMMC_INT_SDIO(i)); | 2163 | mci_writel(host, RINTSTS, |
2164 | SDMMC_INT_SDIO(slot->sdio_id)); | ||
2040 | mmc_signal_sdio_irq(slot->mmc); | 2165 | mmc_signal_sdio_irq(slot->mmc); |
2041 | } | 2166 | } |
2042 | } | 2167 | } |
@@ -2045,99 +2170,28 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | |||
2045 | 2170 | ||
2046 | #ifdef CONFIG_MMC_DW_IDMAC | 2171 | #ifdef CONFIG_MMC_DW_IDMAC |
2047 | /* Handle DMA interrupts */ | 2172 | /* Handle DMA interrupts */ |
2048 | pending = mci_readl(host, IDSTS); | 2173 | if (host->dma_64bit_address == 1) { |
2049 | if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) { | 2174 | pending = mci_readl(host, IDSTS64); |
2050 | mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI); | 2175 | if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) { |
2051 | mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI); | 2176 | mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_TI | |
2052 | host->dma_ops->complete(host); | 2177 | SDMMC_IDMAC_INT_RI); |
2178 | mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI); | ||
2179 | host->dma_ops->complete(host); | ||
2180 | } | ||
2181 | } else { | ||
2182 | pending = mci_readl(host, IDSTS); | ||
2183 | if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) { | ||
2184 | mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI | | ||
2185 | SDMMC_IDMAC_INT_RI); | ||
2186 | mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI); | ||
2187 | host->dma_ops->complete(host); | ||
2188 | } | ||
2053 | } | 2189 | } |
2054 | #endif | 2190 | #endif |
2055 | 2191 | ||
2056 | return IRQ_HANDLED; | 2192 | return IRQ_HANDLED; |
2057 | } | 2193 | } |
2058 | 2194 | ||
2059 | static void dw_mci_work_routine_card(struct work_struct *work) | ||
2060 | { | ||
2061 | struct dw_mci *host = container_of(work, struct dw_mci, card_work); | ||
2062 | int i; | ||
2063 | |||
2064 | for (i = 0; i < host->num_slots; i++) { | ||
2065 | struct dw_mci_slot *slot = host->slot[i]; | ||
2066 | struct mmc_host *mmc = slot->mmc; | ||
2067 | struct mmc_request *mrq; | ||
2068 | int present; | ||
2069 | |||
2070 | present = dw_mci_get_cd(mmc); | ||
2071 | while (present != slot->last_detect_state) { | ||
2072 | dev_dbg(&slot->mmc->class_dev, "card %s\n", | ||
2073 | present ? "inserted" : "removed"); | ||
2074 | |||
2075 | spin_lock_bh(&host->lock); | ||
2076 | |||
2077 | /* Card change detected */ | ||
2078 | slot->last_detect_state = present; | ||
2079 | |||
2080 | /* Clean up queue if present */ | ||
2081 | mrq = slot->mrq; | ||
2082 | if (mrq) { | ||
2083 | if (mrq == host->mrq) { | ||
2084 | host->data = NULL; | ||
2085 | host->cmd = NULL; | ||
2086 | |||
2087 | switch (host->state) { | ||
2088 | case STATE_IDLE: | ||
2089 | case STATE_WAITING_CMD11_DONE: | ||
2090 | break; | ||
2091 | case STATE_SENDING_CMD11: | ||
2092 | case STATE_SENDING_CMD: | ||
2093 | mrq->cmd->error = -ENOMEDIUM; | ||
2094 | if (!mrq->data) | ||
2095 | break; | ||
2096 | /* fall through */ | ||
2097 | case STATE_SENDING_DATA: | ||
2098 | mrq->data->error = -ENOMEDIUM; | ||
2099 | dw_mci_stop_dma(host); | ||
2100 | break; | ||
2101 | case STATE_DATA_BUSY: | ||
2102 | case STATE_DATA_ERROR: | ||
2103 | if (mrq->data->error == -EINPROGRESS) | ||
2104 | mrq->data->error = -ENOMEDIUM; | ||
2105 | /* fall through */ | ||
2106 | case STATE_SENDING_STOP: | ||
2107 | if (mrq->stop) | ||
2108 | mrq->stop->error = -ENOMEDIUM; | ||
2109 | break; | ||
2110 | } | ||
2111 | |||
2112 | dw_mci_request_end(host, mrq); | ||
2113 | } else { | ||
2114 | list_del(&slot->queue_node); | ||
2115 | mrq->cmd->error = -ENOMEDIUM; | ||
2116 | if (mrq->data) | ||
2117 | mrq->data->error = -ENOMEDIUM; | ||
2118 | if (mrq->stop) | ||
2119 | mrq->stop->error = -ENOMEDIUM; | ||
2120 | |||
2121 | spin_unlock(&host->lock); | ||
2122 | mmc_request_done(slot->mmc, mrq); | ||
2123 | spin_lock(&host->lock); | ||
2124 | } | ||
2125 | } | ||
2126 | |||
2127 | /* Power down slot */ | ||
2128 | if (present == 0) | ||
2129 | dw_mci_reset(host); | ||
2130 | |||
2131 | spin_unlock_bh(&host->lock); | ||
2132 | |||
2133 | present = dw_mci_get_cd(mmc); | ||
2134 | } | ||
2135 | |||
2136 | mmc_detect_change(slot->mmc, | ||
2137 | msecs_to_jiffies(host->pdata->detect_delay_ms)); | ||
2138 | } | ||
2139 | } | ||
2140 | |||
2141 | #ifdef CONFIG_OF | 2195 | #ifdef CONFIG_OF |
2142 | /* given a slot id, find out the device node representing that slot */ | 2196 | /* given a slot id, find out the device node representing that slot */ |
2143 | static struct device_node *dw_mci_of_find_slot_node(struct device *dev, u8 slot) | 2197 | static struct device_node *dw_mci_of_find_slot_node(struct device *dev, u8 slot) |
@@ -2206,6 +2260,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
2206 | 2260 | ||
2207 | slot = mmc_priv(mmc); | 2261 | slot = mmc_priv(mmc); |
2208 | slot->id = id; | 2262 | slot->id = id; |
2263 | slot->sdio_id = host->sdio_id0 + id; | ||
2209 | slot->mmc = mmc; | 2264 | slot->mmc = mmc; |
2210 | slot->host = host; | 2265 | slot->host = host; |
2211 | host->slot[id] = slot; | 2266 | host->slot[id] = slot; |
@@ -2289,9 +2344,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
2289 | dw_mci_init_debugfs(slot); | 2344 | dw_mci_init_debugfs(slot); |
2290 | #endif | 2345 | #endif |
2291 | 2346 | ||
2292 | /* Card initially undetected */ | ||
2293 | slot->last_detect_state = 0; | ||
2294 | |||
2295 | return 0; | 2347 | return 0; |
2296 | 2348 | ||
2297 | err_host_allocated: | 2349 | err_host_allocated: |
@@ -2309,6 +2361,22 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id) | |||
2309 | 2361 | ||
2310 | static void dw_mci_init_dma(struct dw_mci *host) | 2362 | static void dw_mci_init_dma(struct dw_mci *host) |
2311 | { | 2363 | { |
2364 | int addr_config; | ||
2365 | /* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */ | ||
2366 | addr_config = (mci_readl(host, HCON) >> 27) & 0x01; | ||
2367 | |||
2368 | if (addr_config == 1) { | ||
2369 | /* host supports IDMAC in 64-bit address mode */ | ||
2370 | host->dma_64bit_address = 1; | ||
2371 | dev_info(host->dev, "IDMAC supports 64-bit address mode.\n"); | ||
2372 | if (!dma_set_mask(host->dev, DMA_BIT_MASK(64))) | ||
2373 | dma_set_coherent_mask(host->dev, DMA_BIT_MASK(64)); | ||
2374 | } else { | ||
2375 | /* host supports IDMAC in 32-bit address mode */ | ||
2376 | host->dma_64bit_address = 0; | ||
2377 | dev_info(host->dev, "IDMAC supports 32-bit address mode.\n"); | ||
2378 | } | ||
2379 | |||
2312 | /* Alloc memory for sg translation */ | 2380 | /* Alloc memory for sg translation */ |
2313 | host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE, | 2381 | host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE, |
2314 | &host->sg_dma, GFP_KERNEL); | 2382 | &host->sg_dma, GFP_KERNEL); |
@@ -2672,17 +2740,10 @@ int dw_mci_probe(struct dw_mci *host) | |||
2672 | host->data_offset = DATA_240A_OFFSET; | 2740 | host->data_offset = DATA_240A_OFFSET; |
2673 | 2741 | ||
2674 | tasklet_init(&host->tasklet, dw_mci_tasklet_func, (unsigned long)host); | 2742 | tasklet_init(&host->tasklet, dw_mci_tasklet_func, (unsigned long)host); |
2675 | host->card_workqueue = alloc_workqueue("dw-mci-card", | ||
2676 | WQ_MEM_RECLAIM, 1); | ||
2677 | if (!host->card_workqueue) { | ||
2678 | ret = -ENOMEM; | ||
2679 | goto err_dmaunmap; | ||
2680 | } | ||
2681 | INIT_WORK(&host->card_work, dw_mci_work_routine_card); | ||
2682 | ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt, | 2743 | ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt, |
2683 | host->irq_flags, "dw-mci", host); | 2744 | host->irq_flags, "dw-mci", host); |
2684 | if (ret) | 2745 | if (ret) |
2685 | goto err_workqueue; | 2746 | goto err_dmaunmap; |
2686 | 2747 | ||
2687 | if (host->pdata->num_slots) | 2748 | if (host->pdata->num_slots) |
2688 | host->num_slots = host->pdata->num_slots; | 2749 | host->num_slots = host->pdata->num_slots; |
@@ -2718,7 +2779,7 @@ int dw_mci_probe(struct dw_mci *host) | |||
2718 | } else { | 2779 | } else { |
2719 | dev_dbg(host->dev, "attempted to initialize %d slots, " | 2780 | dev_dbg(host->dev, "attempted to initialize %d slots, " |
2720 | "but failed on all\n", host->num_slots); | 2781 | "but failed on all\n", host->num_slots); |
2721 | goto err_workqueue; | 2782 | goto err_dmaunmap; |
2722 | } | 2783 | } |
2723 | 2784 | ||
2724 | if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) | 2785 | if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) |
@@ -2726,9 +2787,6 @@ int dw_mci_probe(struct dw_mci *host) | |||
2726 | 2787 | ||
2727 | return 0; | 2788 | return 0; |
2728 | 2789 | ||
2729 | err_workqueue: | ||
2730 | destroy_workqueue(host->card_workqueue); | ||
2731 | |||
2732 | err_dmaunmap: | 2790 | err_dmaunmap: |
2733 | if (host->use_dma && host->dma_ops->exit) | 2791 | if (host->use_dma && host->dma_ops->exit) |
2734 | host->dma_ops->exit(host); | 2792 | host->dma_ops->exit(host); |
@@ -2762,8 +2820,6 @@ void dw_mci_remove(struct dw_mci *host) | |||
2762 | mci_writel(host, CLKENA, 0); | 2820 | mci_writel(host, CLKENA, 0); |
2763 | mci_writel(host, CLKSRC, 0); | 2821 | mci_writel(host, CLKSRC, 0); |
2764 | 2822 | ||
2765 | destroy_workqueue(host->card_workqueue); | ||
2766 | |||
2767 | if (host->use_dma && host->dma_ops->exit) | 2823 | if (host->use_dma && host->dma_ops->exit) |
2768 | host->dma_ops->exit(host); | 2824 | host->dma_ops->exit(host); |
2769 | 2825 | ||
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 01b99e8a9190..0d0f7a271d63 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h | |||
@@ -55,6 +55,17 @@ | |||
55 | #define SDMMC_BUFADDR 0x098 | 55 | #define SDMMC_BUFADDR 0x098 |
56 | #define SDMMC_CDTHRCTL 0x100 | 56 | #define SDMMC_CDTHRCTL 0x100 |
57 | #define SDMMC_DATA(x) (x) | 57 | #define SDMMC_DATA(x) (x) |
58 | /* | ||
59 | * Registers to support idmac 64-bit address mode | ||
60 | */ | ||
61 | #define SDMMC_DBADDRL 0x088 | ||
62 | #define SDMMC_DBADDRU 0x08c | ||
63 | #define SDMMC_IDSTS64 0x090 | ||
64 | #define SDMMC_IDINTEN64 0x094 | ||
65 | #define SDMMC_DSCADDRL 0x098 | ||
66 | #define SDMMC_DSCADDRU 0x09c | ||
67 | #define SDMMC_BUFADDRL 0x0A0 | ||
68 | #define SDMMC_BUFADDRU 0x0A4 | ||
58 | 69 | ||
59 | /* | 70 | /* |
60 | * Data offset is difference according to Version | 71 | * Data offset is difference according to Version |
@@ -214,7 +225,7 @@ extern int dw_mci_resume(struct dw_mci *host); | |||
214 | * with CONFIG_MMC_CLKGATE. | 225 | * with CONFIG_MMC_CLKGATE. |
215 | * @flags: Random state bits associated with the slot. | 226 | * @flags: Random state bits associated with the slot. |
216 | * @id: Number of this slot. | 227 | * @id: Number of this slot. |
217 | * @last_detect_state: Most recently observed card detect state. | 228 | * @sdio_id: Number of this slot in the SDIO interrupt registers. |
218 | */ | 229 | */ |
219 | struct dw_mci_slot { | 230 | struct dw_mci_slot { |
220 | struct mmc_host *mmc; | 231 | struct mmc_host *mmc; |
@@ -234,7 +245,7 @@ struct dw_mci_slot { | |||
234 | #define DW_MMC_CARD_PRESENT 0 | 245 | #define DW_MMC_CARD_PRESENT 0 |
235 | #define DW_MMC_CARD_NEED_INIT 1 | 246 | #define DW_MMC_CARD_NEED_INIT 1 |
236 | int id; | 247 | int id; |
237 | int last_detect_state; | 248 | int sdio_id; |
238 | }; | 249 | }; |
239 | 250 | ||
240 | struct dw_mci_tuning_data { | 251 | struct dw_mci_tuning_data { |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 43af791e2e45..53bf7a4b5839 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -736,8 +736,15 @@ static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq, | |||
736 | chan = host->dma_tx_channel; | 736 | chan = host->dma_tx_channel; |
737 | dmaengine_terminate_all(chan); | 737 | dmaengine_terminate_all(chan); |
738 | 738 | ||
739 | if (host->dma_desc_current == next->dma_desc) | ||
740 | host->dma_desc_current = NULL; | ||
741 | |||
742 | if (host->dma_current == next->dma_chan) | ||
743 | host->dma_current = NULL; | ||
744 | |||
739 | next->dma_desc = NULL; | 745 | next->dma_desc = NULL; |
740 | next->dma_chan = NULL; | 746 | next->dma_chan = NULL; |
747 | data->host_cookie = 0; | ||
741 | } | 748 | } |
742 | } | 749 | } |
743 | 750 | ||
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 9405ecdaf6cf..90c60fd4ff6e 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c | |||
@@ -1360,7 +1360,7 @@ msmsdcc_probe(struct platform_device *pdev) | |||
1360 | if (ret) | 1360 | if (ret) |
1361 | goto cmd_irq_free; | 1361 | goto cmd_irq_free; |
1362 | 1362 | ||
1363 | mmc_set_drvdata(pdev, mmc); | 1363 | platform_set_drvdata(pdev, mmc); |
1364 | mmc_add_host(mmc); | 1364 | mmc_add_host(mmc); |
1365 | 1365 | ||
1366 | pr_info("%s: Qualcomm MSM SDCC at 0x%016llx irq %d,%d dma %d\n", | 1366 | pr_info("%s: Qualcomm MSM SDCC at 0x%016llx irq %d,%d dma %d\n", |
@@ -1419,7 +1419,7 @@ ioremap_free: | |||
1419 | static int | 1419 | static int |
1420 | msmsdcc_suspend(struct platform_device *dev, pm_message_t state) | 1420 | msmsdcc_suspend(struct platform_device *dev, pm_message_t state) |
1421 | { | 1421 | { |
1422 | struct mmc_host *mmc = mmc_get_drvdata(dev); | 1422 | struct mmc_host *mmc = platform_get_drvdata(dev); |
1423 | 1423 | ||
1424 | if (mmc) { | 1424 | if (mmc) { |
1425 | struct msmsdcc_host *host = mmc_priv(mmc); | 1425 | struct msmsdcc_host *host = mmc_priv(mmc); |
@@ -1437,7 +1437,7 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state) | |||
1437 | static int | 1437 | static int |
1438 | msmsdcc_resume(struct platform_device *dev) | 1438 | msmsdcc_resume(struct platform_device *dev) |
1439 | { | 1439 | { |
1440 | struct mmc_host *mmc = mmc_get_drvdata(dev); | 1440 | struct mmc_host *mmc = platform_get_drvdata(dev); |
1441 | 1441 | ||
1442 | if (mmc) { | 1442 | if (mmc) { |
1443 | struct msmsdcc_host *host = mmc_priv(mmc); | 1443 | struct msmsdcc_host *host = mmc_priv(mmc); |
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index 6b4c5ad3b393..4f8618f4522d 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c | |||
@@ -111,10 +111,15 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data) | |||
111 | mvsd_write(MVSD_BLK_COUNT, data->blocks); | 111 | mvsd_write(MVSD_BLK_COUNT, data->blocks); |
112 | mvsd_write(MVSD_BLK_SIZE, data->blksz); | 112 | mvsd_write(MVSD_BLK_SIZE, data->blksz); |
113 | 113 | ||
114 | if (nodma || (data->blksz | data->sg->offset) & 3) { | 114 | if (nodma || (data->blksz | data->sg->offset) & 3 || |
115 | ((!(data->flags & MMC_DATA_READ) && data->sg->offset & 0x3f))) { | ||
115 | /* | 116 | /* |
116 | * We cannot do DMA on a buffer which offset or size | 117 | * We cannot do DMA on a buffer which offset or size |
117 | * is not aligned on a 4-byte boundary. | 118 | * is not aligned on a 4-byte boundary. |
119 | * | ||
120 | * It also appears the host to card DMA can corrupt | ||
121 | * data when the buffer is not aligned on a 64 byte | ||
122 | * boundary. | ||
118 | */ | 123 | */ |
119 | host->pio_size = data->blocks * data->blksz; | 124 | host->pio_size = data->blocks * data->blksz; |
120 | host->pio_ptr = sg_virt(data->sg); | 125 | host->pio_ptr = sg_virt(data->sg); |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index ad111422ad55..5316d9b9e7b4 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -373,13 +373,9 @@ static void mxcmci_dma_callback(void *data) | |||
373 | del_timer(&host->watchdog); | 373 | del_timer(&host->watchdog); |
374 | 374 | ||
375 | stat = mxcmci_readl(host, MMC_REG_STATUS); | 375 | stat = mxcmci_readl(host, MMC_REG_STATUS); |
376 | mxcmci_writel(host, stat & ~STATUS_DATA_TRANS_DONE, MMC_REG_STATUS); | ||
377 | 376 | ||
378 | dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat); | 377 | dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat); |
379 | 378 | ||
380 | if (stat & STATUS_READ_OP_DONE) | ||
381 | mxcmci_writel(host, STATUS_READ_OP_DONE, MMC_REG_STATUS); | ||
382 | |||
383 | mxcmci_data_done(host, stat); | 379 | mxcmci_data_done(host, stat); |
384 | } | 380 | } |
385 | 381 | ||
@@ -743,10 +739,8 @@ static irqreturn_t mxcmci_irq(int irq, void *devid) | |||
743 | sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio; | 739 | sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio; |
744 | spin_unlock_irqrestore(&host->lock, flags); | 740 | spin_unlock_irqrestore(&host->lock, flags); |
745 | 741 | ||
746 | if (mxcmci_use_dma(host) && | 742 | if (mxcmci_use_dma(host) && (stat & (STATUS_WRITE_OP_DONE))) |
747 | (stat & (STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE))) | 743 | mxcmci_writel(host, STATUS_WRITE_OP_DONE, MMC_REG_STATUS); |
748 | mxcmci_writel(host, STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE, | ||
749 | MMC_REG_STATUS); | ||
750 | 744 | ||
751 | if (sdio_irq) { | 745 | if (sdio_irq) { |
752 | mxcmci_writel(host, STATUS_SDIO_INT_ACTIVE, MMC_REG_STATUS); | 746 | mxcmci_writel(host, STATUS_SDIO_INT_ACTIVE, MMC_REG_STATUS); |
@@ -756,8 +750,7 @@ static irqreturn_t mxcmci_irq(int irq, void *devid) | |||
756 | if (stat & STATUS_END_CMD_RESP) | 750 | if (stat & STATUS_END_CMD_RESP) |
757 | mxcmci_cmd_done(host, stat); | 751 | mxcmci_cmd_done(host, stat); |
758 | 752 | ||
759 | if (mxcmci_use_dma(host) && | 753 | if (mxcmci_use_dma(host) && (stat & STATUS_WRITE_OP_DONE)) { |
760 | (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) { | ||
761 | del_timer(&host->watchdog); | 754 | del_timer(&host->watchdog); |
762 | mxcmci_data_done(host, stat); | 755 | mxcmci_data_done(host, stat); |
763 | } | 756 | } |
@@ -1084,12 +1077,14 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
1084 | dat3_card_detect = true; | 1077 | dat3_card_detect = true; |
1085 | 1078 | ||
1086 | ret = mmc_regulator_get_supply(mmc); | 1079 | ret = mmc_regulator_get_supply(mmc); |
1087 | if (ret) { | 1080 | if (ret == -EPROBE_DEFER) |
1088 | if (pdata && ret != -EPROBE_DEFER) | 1081 | goto out_free; |
1089 | mmc->ocr_avail = pdata->ocr_avail ? : | 1082 | |
1090 | MMC_VDD_32_33 | MMC_VDD_33_34; | 1083 | if (!mmc->ocr_avail) { |
1084 | if (pdata && pdata->ocr_avail) | ||
1085 | mmc->ocr_avail = pdata->ocr_avail; | ||
1091 | else | 1086 | else |
1092 | goto out_free; | 1087 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
1093 | } | 1088 | } |
1094 | 1089 | ||
1095 | if (dat3_card_detect) | 1090 | if (dat3_card_detect) |
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index cd74e5143c36..60c4ca97a727 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -581,10 +581,9 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
581 | struct regulator *reg_vmmc; | 581 | struct regulator *reg_vmmc; |
582 | struct mxs_ssp *ssp; | 582 | struct mxs_ssp *ssp; |
583 | 583 | ||
584 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
585 | irq_err = platform_get_irq(pdev, 0); | 584 | irq_err = platform_get_irq(pdev, 0); |
586 | if (!iores || irq_err < 0) | 585 | if (irq_err < 0) |
587 | return -EINVAL; | 586 | return irq_err; |
588 | 587 | ||
589 | mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev); | 588 | mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev); |
590 | if (!mmc) | 589 | if (!mmc) |
@@ -593,6 +592,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
593 | host = mmc_priv(mmc); | 592 | host = mmc_priv(mmc); |
594 | ssp = &host->ssp; | 593 | ssp = &host->ssp; |
595 | ssp->dev = &pdev->dev; | 594 | ssp->dev = &pdev->dev; |
595 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
596 | ssp->base = devm_ioremap_resource(&pdev->dev, iores); | 596 | ssp->base = devm_ioremap_resource(&pdev->dev, iores); |
597 | if (IS_ERR(ssp->base)) { | 597 | if (IS_ERR(ssp->base)) { |
598 | ret = PTR_ERR(ssp->base); | 598 | ret = PTR_ERR(ssp->base); |
@@ -619,7 +619,9 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
619 | ret = PTR_ERR(ssp->clk); | 619 | ret = PTR_ERR(ssp->clk); |
620 | goto out_mmc_free; | 620 | goto out_mmc_free; |
621 | } | 621 | } |
622 | clk_prepare_enable(ssp->clk); | 622 | ret = clk_prepare_enable(ssp->clk); |
623 | if (ret) | ||
624 | goto out_mmc_free; | ||
623 | 625 | ||
624 | ret = mxs_mmc_reset(host); | 626 | ret = mxs_mmc_reset(host); |
625 | if (ret) { | 627 | if (ret) { |
@@ -660,7 +662,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
660 | platform_set_drvdata(pdev, mmc); | 662 | platform_set_drvdata(pdev, mmc); |
661 | 663 | ||
662 | ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0, | 664 | ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0, |
663 | DRIVER_NAME, host); | 665 | dev_name(&pdev->dev), host); |
664 | if (ret) | 666 | if (ret) |
665 | goto out_free_dma; | 667 | goto out_free_dma; |
666 | 668 | ||
@@ -702,7 +704,7 @@ static int mxs_mmc_remove(struct platform_device *pdev) | |||
702 | return 0; | 704 | return 0; |
703 | } | 705 | } |
704 | 706 | ||
705 | #ifdef CONFIG_PM | 707 | #ifdef CONFIG_PM_SLEEP |
706 | static int mxs_mmc_suspend(struct device *dev) | 708 | static int mxs_mmc_suspend(struct device *dev) |
707 | { | 709 | { |
708 | struct mmc_host *mmc = dev_get_drvdata(dev); | 710 | struct mmc_host *mmc = dev_get_drvdata(dev); |
@@ -719,25 +721,19 @@ static int mxs_mmc_resume(struct device *dev) | |||
719 | struct mxs_mmc_host *host = mmc_priv(mmc); | 721 | struct mxs_mmc_host *host = mmc_priv(mmc); |
720 | struct mxs_ssp *ssp = &host->ssp; | 722 | struct mxs_ssp *ssp = &host->ssp; |
721 | 723 | ||
722 | clk_prepare_enable(ssp->clk); | 724 | return clk_prepare_enable(ssp->clk); |
723 | return 0; | ||
724 | } | 725 | } |
725 | |||
726 | static const struct dev_pm_ops mxs_mmc_pm_ops = { | ||
727 | .suspend = mxs_mmc_suspend, | ||
728 | .resume = mxs_mmc_resume, | ||
729 | }; | ||
730 | #endif | 726 | #endif |
731 | 727 | ||
728 | static SIMPLE_DEV_PM_OPS(mxs_mmc_pm_ops, mxs_mmc_suspend, mxs_mmc_resume); | ||
729 | |||
732 | static struct platform_driver mxs_mmc_driver = { | 730 | static struct platform_driver mxs_mmc_driver = { |
733 | .probe = mxs_mmc_probe, | 731 | .probe = mxs_mmc_probe, |
734 | .remove = mxs_mmc_remove, | 732 | .remove = mxs_mmc_remove, |
735 | .id_table = mxs_ssp_ids, | 733 | .id_table = mxs_ssp_ids, |
736 | .driver = { | 734 | .driver = { |
737 | .name = DRIVER_NAME, | 735 | .name = DRIVER_NAME, |
738 | #ifdef CONFIG_PM | ||
739 | .pm = &mxs_mmc_pm_ops, | 736 | .pm = &mxs_mmc_pm_ops, |
740 | #endif | ||
741 | .of_match_table = mxs_mmc_dt_ids, | 737 | .of_match_table = mxs_mmc_dt_ids, |
742 | }, | 738 | }, |
743 | }; | 739 | }; |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index df27bb4fc098..7c71dcdcba8b 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <linux/regulator/consumer.h> | 42 | #include <linux/regulator/consumer.h> |
43 | #include <linux/pinctrl/consumer.h> | 43 | #include <linux/pinctrl/consumer.h> |
44 | #include <linux/pm_runtime.h> | 44 | #include <linux/pm_runtime.h> |
45 | #include <linux/platform_data/mmc-omap.h> | 45 | #include <linux/platform_data/hsmmc-omap.h> |
46 | 46 | ||
47 | /* OMAP HSMMC Host Controller Registers */ | 47 | /* OMAP HSMMC Host Controller Registers */ |
48 | #define OMAP_HSMMC_SYSSTATUS 0x0014 | 48 | #define OMAP_HSMMC_SYSSTATUS 0x0014 |
@@ -155,7 +155,7 @@ | |||
155 | * omap.c controller driver. Luckily this is not currently done on any known | 155 | * omap.c controller driver. Luckily this is not currently done on any known |
156 | * omap_hsmmc.c device. | 156 | * omap_hsmmc.c device. |
157 | */ | 157 | */ |
158 | #define mmc_slot(host) (host->pdata->slots[host->slot_id]) | 158 | #define mmc_pdata(host) host->pdata |
159 | 159 | ||
160 | /* | 160 | /* |
161 | * MMC Host controller read/write API's | 161 | * MMC Host controller read/write API's |
@@ -207,7 +207,6 @@ struct omap_hsmmc_host { | |||
207 | int use_dma, dma_ch; | 207 | int use_dma, dma_ch; |
208 | struct dma_chan *tx_chan; | 208 | struct dma_chan *tx_chan; |
209 | struct dma_chan *rx_chan; | 209 | struct dma_chan *rx_chan; |
210 | int slot_id; | ||
211 | int response_busy; | 210 | int response_busy; |
212 | int context_loss; | 211 | int context_loss; |
213 | int protect_card; | 212 | int protect_card; |
@@ -220,7 +219,26 @@ struct omap_hsmmc_host { | |||
220 | #define HSMMC_SDIO_IRQ_ENABLED (1 << 1) /* SDIO irq enabled */ | 219 | #define HSMMC_SDIO_IRQ_ENABLED (1 << 1) /* SDIO irq enabled */ |
221 | #define HSMMC_WAKE_IRQ_ENABLED (1 << 2) | 220 | #define HSMMC_WAKE_IRQ_ENABLED (1 << 2) |
222 | struct omap_hsmmc_next next_data; | 221 | struct omap_hsmmc_next next_data; |
223 | struct omap_mmc_platform_data *pdata; | 222 | struct omap_hsmmc_platform_data *pdata; |
223 | |||
224 | /* To handle board related suspend/resume functionality for MMC */ | ||
225 | int (*suspend)(struct device *dev); | ||
226 | int (*resume)(struct device *dev); | ||
227 | |||
228 | /* return MMC cover switch state, can be NULL if not supported. | ||
229 | * | ||
230 | * possible return values: | ||
231 | * 0 - closed | ||
232 | * 1 - open | ||
233 | */ | ||
234 | int (*get_cover_state)(struct device *dev); | ||
235 | |||
236 | /* Card detection IRQs */ | ||
237 | int card_detect_irq; | ||
238 | |||
239 | int (*card_detect)(struct device *dev); | ||
240 | int (*get_ro)(struct device *dev); | ||
241 | |||
224 | }; | 242 | }; |
225 | 243 | ||
226 | struct omap_mmc_of_data { | 244 | struct omap_mmc_of_data { |
@@ -230,50 +248,48 @@ struct omap_mmc_of_data { | |||
230 | 248 | ||
231 | static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host); | 249 | static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host); |
232 | 250 | ||
233 | static int omap_hsmmc_card_detect(struct device *dev, int slot) | 251 | static int omap_hsmmc_card_detect(struct device *dev) |
234 | { | 252 | { |
235 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 253 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
236 | struct omap_mmc_platform_data *mmc = host->pdata; | 254 | struct omap_hsmmc_platform_data *mmc = host->pdata; |
237 | 255 | ||
238 | /* NOTE: assumes card detect signal is active-low */ | 256 | /* NOTE: assumes card detect signal is active-low */ |
239 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | 257 | return !gpio_get_value_cansleep(mmc->switch_pin); |
240 | } | 258 | } |
241 | 259 | ||
242 | static int omap_hsmmc_get_wp(struct device *dev, int slot) | 260 | static int omap_hsmmc_get_wp(struct device *dev) |
243 | { | 261 | { |
244 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 262 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
245 | struct omap_mmc_platform_data *mmc = host->pdata; | 263 | struct omap_hsmmc_platform_data *mmc = host->pdata; |
246 | 264 | ||
247 | /* NOTE: assumes write protect signal is active-high */ | 265 | /* NOTE: assumes write protect signal is active-high */ |
248 | return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); | 266 | return gpio_get_value_cansleep(mmc->gpio_wp); |
249 | } | 267 | } |
250 | 268 | ||
251 | static int omap_hsmmc_get_cover_state(struct device *dev, int slot) | 269 | static int omap_hsmmc_get_cover_state(struct device *dev) |
252 | { | 270 | { |
253 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 271 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
254 | struct omap_mmc_platform_data *mmc = host->pdata; | 272 | struct omap_hsmmc_platform_data *mmc = host->pdata; |
255 | 273 | ||
256 | /* NOTE: assumes card detect signal is active-low */ | 274 | /* NOTE: assumes card detect signal is active-low */ |
257 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | 275 | return !gpio_get_value_cansleep(mmc->switch_pin); |
258 | } | 276 | } |
259 | 277 | ||
260 | #ifdef CONFIG_PM | 278 | #ifdef CONFIG_PM |
261 | 279 | ||
262 | static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) | 280 | static int omap_hsmmc_suspend_cdirq(struct device *dev) |
263 | { | 281 | { |
264 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 282 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
265 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
266 | 283 | ||
267 | disable_irq(mmc->slots[0].card_detect_irq); | 284 | disable_irq(host->card_detect_irq); |
268 | return 0; | 285 | return 0; |
269 | } | 286 | } |
270 | 287 | ||
271 | static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) | 288 | static int omap_hsmmc_resume_cdirq(struct device *dev) |
272 | { | 289 | { |
273 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 290 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
274 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
275 | 291 | ||
276 | enable_irq(mmc->slots[0].card_detect_irq); | 292 | enable_irq(host->card_detect_irq); |
277 | return 0; | 293 | return 0; |
278 | } | 294 | } |
279 | 295 | ||
@@ -286,8 +302,7 @@ static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) | |||
286 | 302 | ||
287 | #ifdef CONFIG_REGULATOR | 303 | #ifdef CONFIG_REGULATOR |
288 | 304 | ||
289 | static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, | 305 | static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) |
290 | int vdd) | ||
291 | { | 306 | { |
292 | struct omap_hsmmc_host *host = | 307 | struct omap_hsmmc_host *host = |
293 | platform_get_drvdata(to_platform_device(dev)); | 308 | platform_get_drvdata(to_platform_device(dev)); |
@@ -300,8 +315,8 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, | |||
300 | if (!host->vcc) | 315 | if (!host->vcc) |
301 | return 0; | 316 | return 0; |
302 | 317 | ||
303 | if (mmc_slot(host).before_set_reg) | 318 | if (mmc_pdata(host)->before_set_reg) |
304 | mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); | 319 | mmc_pdata(host)->before_set_reg(dev, power_on, vdd); |
305 | 320 | ||
306 | if (host->pbias) { | 321 | if (host->pbias) { |
307 | if (host->pbias_enabled == 1) { | 322 | if (host->pbias_enabled == 1) { |
@@ -363,8 +378,8 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, | |||
363 | } | 378 | } |
364 | } | 379 | } |
365 | 380 | ||
366 | if (mmc_slot(host).after_set_reg) | 381 | if (mmc_pdata(host)->after_set_reg) |
367 | mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); | 382 | mmc_pdata(host)->after_set_reg(dev, power_on, vdd); |
368 | 383 | ||
369 | error_set_power: | 384 | error_set_power: |
370 | return ret; | 385 | return ret; |
@@ -383,18 +398,18 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
383 | } else { | 398 | } else { |
384 | host->vcc = reg; | 399 | host->vcc = reg; |
385 | ocr_value = mmc_regulator_get_ocrmask(reg); | 400 | ocr_value = mmc_regulator_get_ocrmask(reg); |
386 | if (!mmc_slot(host).ocr_mask) { | 401 | if (!mmc_pdata(host)->ocr_mask) { |
387 | mmc_slot(host).ocr_mask = ocr_value; | 402 | mmc_pdata(host)->ocr_mask = ocr_value; |
388 | } else { | 403 | } else { |
389 | if (!(mmc_slot(host).ocr_mask & ocr_value)) { | 404 | if (!(mmc_pdata(host)->ocr_mask & ocr_value)) { |
390 | dev_err(host->dev, "ocrmask %x is not supported\n", | 405 | dev_err(host->dev, "ocrmask %x is not supported\n", |
391 | mmc_slot(host).ocr_mask); | 406 | mmc_pdata(host)->ocr_mask); |
392 | mmc_slot(host).ocr_mask = 0; | 407 | mmc_pdata(host)->ocr_mask = 0; |
393 | return -EINVAL; | 408 | return -EINVAL; |
394 | } | 409 | } |
395 | } | 410 | } |
396 | } | 411 | } |
397 | mmc_slot(host).set_power = omap_hsmmc_set_power; | 412 | mmc_pdata(host)->set_power = omap_hsmmc_set_power; |
398 | 413 | ||
399 | /* Allow an aux regulator */ | 414 | /* Allow an aux regulator */ |
400 | reg = devm_regulator_get_optional(host->dev, "vmmc_aux"); | 415 | reg = devm_regulator_get_optional(host->dev, "vmmc_aux"); |
@@ -404,7 +419,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
404 | host->pbias = IS_ERR(reg) ? NULL : reg; | 419 | host->pbias = IS_ERR(reg) ? NULL : reg; |
405 | 420 | ||
406 | /* For eMMC do not power off when not in sleep state */ | 421 | /* For eMMC do not power off when not in sleep state */ |
407 | if (mmc_slot(host).no_regulator_off_init) | 422 | if (mmc_pdata(host)->no_regulator_off_init) |
408 | return 0; | 423 | return 0; |
409 | /* | 424 | /* |
410 | * To disable boot_on regulator, enable regulator | 425 | * To disable boot_on regulator, enable regulator |
@@ -412,10 +427,10 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
412 | */ | 427 | */ |
413 | if ((host->vcc && regulator_is_enabled(host->vcc) > 0) || | 428 | if ((host->vcc && regulator_is_enabled(host->vcc) > 0) || |
414 | (host->vcc_aux && regulator_is_enabled(host->vcc_aux))) { | 429 | (host->vcc_aux && regulator_is_enabled(host->vcc_aux))) { |
415 | int vdd = ffs(mmc_slot(host).ocr_mask) - 1; | 430 | int vdd = ffs(mmc_pdata(host)->ocr_mask) - 1; |
416 | 431 | ||
417 | mmc_slot(host).set_power(host->dev, host->slot_id, 1, vdd); | 432 | mmc_pdata(host)->set_power(host->dev, 1, vdd); |
418 | mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); | 433 | mmc_pdata(host)->set_power(host->dev, 0, 0); |
419 | } | 434 | } |
420 | 435 | ||
421 | return 0; | 436 | return 0; |
@@ -423,7 +438,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
423 | 438 | ||
424 | static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) | 439 | static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) |
425 | { | 440 | { |
426 | mmc_slot(host).set_power = NULL; | 441 | mmc_pdata(host)->set_power = NULL; |
427 | } | 442 | } |
428 | 443 | ||
429 | static inline int omap_hsmmc_have_reg(void) | 444 | static inline int omap_hsmmc_have_reg(void) |
@@ -449,55 +464,59 @@ static inline int omap_hsmmc_have_reg(void) | |||
449 | 464 | ||
450 | #endif | 465 | #endif |
451 | 466 | ||
452 | static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata) | 467 | static int omap_hsmmc_gpio_init(struct omap_hsmmc_host *host, |
468 | struct omap_hsmmc_platform_data *pdata) | ||
453 | { | 469 | { |
454 | int ret; | 470 | int ret; |
455 | 471 | ||
456 | if (gpio_is_valid(pdata->slots[0].switch_pin)) { | 472 | if (gpio_is_valid(pdata->switch_pin)) { |
457 | if (pdata->slots[0].cover) | 473 | if (pdata->cover) |
458 | pdata->slots[0].get_cover_state = | 474 | host->get_cover_state = |
459 | omap_hsmmc_get_cover_state; | 475 | omap_hsmmc_get_cover_state; |
460 | else | 476 | else |
461 | pdata->slots[0].card_detect = omap_hsmmc_card_detect; | 477 | host->card_detect = omap_hsmmc_card_detect; |
462 | pdata->slots[0].card_detect_irq = | 478 | host->card_detect_irq = |
463 | gpio_to_irq(pdata->slots[0].switch_pin); | 479 | gpio_to_irq(pdata->switch_pin); |
464 | ret = gpio_request(pdata->slots[0].switch_pin, "mmc_cd"); | 480 | ret = gpio_request(pdata->switch_pin, "mmc_cd"); |
465 | if (ret) | 481 | if (ret) |
466 | return ret; | 482 | return ret; |
467 | ret = gpio_direction_input(pdata->slots[0].switch_pin); | 483 | ret = gpio_direction_input(pdata->switch_pin); |
468 | if (ret) | 484 | if (ret) |
469 | goto err_free_sp; | 485 | goto err_free_sp; |
470 | } else | 486 | } else { |
471 | pdata->slots[0].switch_pin = -EINVAL; | 487 | pdata->switch_pin = -EINVAL; |
488 | } | ||
472 | 489 | ||
473 | if (gpio_is_valid(pdata->slots[0].gpio_wp)) { | 490 | if (gpio_is_valid(pdata->gpio_wp)) { |
474 | pdata->slots[0].get_ro = omap_hsmmc_get_wp; | 491 | host->get_ro = omap_hsmmc_get_wp; |
475 | ret = gpio_request(pdata->slots[0].gpio_wp, "mmc_wp"); | 492 | ret = gpio_request(pdata->gpio_wp, "mmc_wp"); |
476 | if (ret) | 493 | if (ret) |
477 | goto err_free_cd; | 494 | goto err_free_cd; |
478 | ret = gpio_direction_input(pdata->slots[0].gpio_wp); | 495 | ret = gpio_direction_input(pdata->gpio_wp); |
479 | if (ret) | 496 | if (ret) |
480 | goto err_free_wp; | 497 | goto err_free_wp; |
481 | } else | 498 | } else { |
482 | pdata->slots[0].gpio_wp = -EINVAL; | 499 | pdata->gpio_wp = -EINVAL; |
500 | } | ||
483 | 501 | ||
484 | return 0; | 502 | return 0; |
485 | 503 | ||
486 | err_free_wp: | 504 | err_free_wp: |
487 | gpio_free(pdata->slots[0].gpio_wp); | 505 | gpio_free(pdata->gpio_wp); |
488 | err_free_cd: | 506 | err_free_cd: |
489 | if (gpio_is_valid(pdata->slots[0].switch_pin)) | 507 | if (gpio_is_valid(pdata->switch_pin)) |
490 | err_free_sp: | 508 | err_free_sp: |
491 | gpio_free(pdata->slots[0].switch_pin); | 509 | gpio_free(pdata->switch_pin); |
492 | return ret; | 510 | return ret; |
493 | } | 511 | } |
494 | 512 | ||
495 | static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata) | 513 | static void omap_hsmmc_gpio_free(struct omap_hsmmc_host *host, |
514 | struct omap_hsmmc_platform_data *pdata) | ||
496 | { | 515 | { |
497 | if (gpio_is_valid(pdata->slots[0].gpio_wp)) | 516 | if (gpio_is_valid(pdata->gpio_wp)) |
498 | gpio_free(pdata->slots[0].gpio_wp); | 517 | gpio_free(pdata->gpio_wp); |
499 | if (gpio_is_valid(pdata->slots[0].switch_pin)) | 518 | if (gpio_is_valid(pdata->switch_pin)) |
500 | gpio_free(pdata->slots[0].switch_pin); | 519 | gpio_free(pdata->switch_pin); |
501 | } | 520 | } |
502 | 521 | ||
503 | /* | 522 | /* |
@@ -607,8 +626,9 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host) | |||
607 | * in capabilities register | 626 | * in capabilities register |
608 | * - MMC/SD clock coming out of controller > 25MHz | 627 | * - MMC/SD clock coming out of controller > 25MHz |
609 | */ | 628 | */ |
610 | if ((mmc_slot(host).features & HSMMC_HAS_HSPE_SUPPORT) && | 629 | if ((mmc_pdata(host)->features & HSMMC_HAS_HSPE_SUPPORT) && |
611 | (ios->timing != MMC_TIMING_MMC_DDR52) && | 630 | (ios->timing != MMC_TIMING_MMC_DDR52) && |
631 | (ios->timing != MMC_TIMING_UHS_DDR50) && | ||
612 | ((OMAP_HSMMC_READ(host->base, CAPA) & HSS) == HSS)) { | 632 | ((OMAP_HSMMC_READ(host->base, CAPA) & HSS) == HSS)) { |
613 | regval = OMAP_HSMMC_READ(host->base, HCTL); | 633 | regval = OMAP_HSMMC_READ(host->base, HCTL); |
614 | if (clkdiv && (clk_get_rate(host->fclk)/clkdiv) > 25000000) | 634 | if (clkdiv && (clk_get_rate(host->fclk)/clkdiv) > 25000000) |
@@ -628,7 +648,8 @@ static void omap_hsmmc_set_bus_width(struct omap_hsmmc_host *host) | |||
628 | u32 con; | 648 | u32 con; |
629 | 649 | ||
630 | con = OMAP_HSMMC_READ(host->base, CON); | 650 | con = OMAP_HSMMC_READ(host->base, CON); |
631 | if (ios->timing == MMC_TIMING_MMC_DDR52) | 651 | if (ios->timing == MMC_TIMING_MMC_DDR52 || |
652 | ios->timing == MMC_TIMING_UHS_DDR50) | ||
632 | con |= DDR; /* configure in DDR mode */ | 653 | con |= DDR; /* configure in DDR mode */ |
633 | else | 654 | else |
634 | con &= ~DDR; | 655 | con &= ~DDR; |
@@ -791,8 +812,8 @@ int omap_hsmmc_cover_is_closed(struct omap_hsmmc_host *host) | |||
791 | { | 812 | { |
792 | int r = 1; | 813 | int r = 1; |
793 | 814 | ||
794 | if (mmc_slot(host).get_cover_state) | 815 | if (host->get_cover_state) |
795 | r = mmc_slot(host).get_cover_state(host->dev, host->slot_id); | 816 | r = host->get_cover_state(host->dev); |
796 | return r; | 817 | return r; |
797 | } | 818 | } |
798 | 819 | ||
@@ -816,7 +837,7 @@ omap_hsmmc_show_slot_name(struct device *dev, struct device_attribute *attr, | |||
816 | struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev); | 837 | struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev); |
817 | struct omap_hsmmc_host *host = mmc_priv(mmc); | 838 | struct omap_hsmmc_host *host = mmc_priv(mmc); |
818 | 839 | ||
819 | return sprintf(buf, "%s\n", mmc_slot(host).name); | 840 | return sprintf(buf, "%s\n", mmc_pdata(host)->name); |
820 | } | 841 | } |
821 | 842 | ||
822 | static DEVICE_ATTR(slot_name, S_IRUGO, omap_hsmmc_show_slot_name, NULL); | 843 | static DEVICE_ATTR(slot_name, S_IRUGO, omap_hsmmc_show_slot_name, NULL); |
@@ -1061,7 +1082,7 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, | |||
1061 | * OMAP4 ES2 and greater has an updated reset logic. | 1082 | * OMAP4 ES2 and greater has an updated reset logic. |
1062 | * Monitor a 0->1 transition first | 1083 | * Monitor a 0->1 transition first |
1063 | */ | 1084 | */ |
1064 | if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) { | 1085 | if (mmc_pdata(host)->features & HSMMC_HAS_UPDATED_RESET) { |
1065 | while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit)) | 1086 | while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit)) |
1066 | && (i++ < limit)) | 1087 | && (i++ < limit)) |
1067 | udelay(1); | 1088 | udelay(1); |
@@ -1210,12 +1231,11 @@ static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd) | |||
1210 | clk_disable_unprepare(host->dbclk); | 1231 | clk_disable_unprepare(host->dbclk); |
1211 | 1232 | ||
1212 | /* Turn the power off */ | 1233 | /* Turn the power off */ |
1213 | ret = mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); | 1234 | ret = mmc_pdata(host)->set_power(host->dev, 0, 0); |
1214 | 1235 | ||
1215 | /* Turn the power ON with given VDD 1.8 or 3.0v */ | 1236 | /* Turn the power ON with given VDD 1.8 or 3.0v */ |
1216 | if (!ret) | 1237 | if (!ret) |
1217 | ret = mmc_slot(host).set_power(host->dev, host->slot_id, 1, | 1238 | ret = mmc_pdata(host)->set_power(host->dev, 1, vdd); |
1218 | vdd); | ||
1219 | pm_runtime_get_sync(host->dev); | 1239 | pm_runtime_get_sync(host->dev); |
1220 | if (host->dbclk) | 1240 | if (host->dbclk) |
1221 | clk_prepare_enable(host->dbclk); | 1241 | clk_prepare_enable(host->dbclk); |
@@ -1259,11 +1279,11 @@ err: | |||
1259 | /* Protect the card while the cover is open */ | 1279 | /* Protect the card while the cover is open */ |
1260 | static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host) | 1280 | static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host) |
1261 | { | 1281 | { |
1262 | if (!mmc_slot(host).get_cover_state) | 1282 | if (!host->get_cover_state) |
1263 | return; | 1283 | return; |
1264 | 1284 | ||
1265 | host->reqs_blocked = 0; | 1285 | host->reqs_blocked = 0; |
1266 | if (mmc_slot(host).get_cover_state(host->dev, host->slot_id)) { | 1286 | if (host->get_cover_state(host->dev)) { |
1267 | if (host->protect_card) { | 1287 | if (host->protect_card) { |
1268 | dev_info(host->dev, "%s: cover is closed, " | 1288 | dev_info(host->dev, "%s: cover is closed, " |
1269 | "card is now accessible\n", | 1289 | "card is now accessible\n", |
@@ -1286,13 +1306,12 @@ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host) | |||
1286 | static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id) | 1306 | static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id) |
1287 | { | 1307 | { |
1288 | struct omap_hsmmc_host *host = dev_id; | 1308 | struct omap_hsmmc_host *host = dev_id; |
1289 | struct omap_mmc_slot_data *slot = &mmc_slot(host); | ||
1290 | int carddetect; | 1309 | int carddetect; |
1291 | 1310 | ||
1292 | sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); | 1311 | sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); |
1293 | 1312 | ||
1294 | if (slot->card_detect) | 1313 | if (host->card_detect) |
1295 | carddetect = slot->card_detect(host->dev, host->slot_id); | 1314 | carddetect = host->card_detect(host->dev); |
1296 | else { | 1315 | else { |
1297 | omap_hsmmc_protect_card(host); | 1316 | omap_hsmmc_protect_card(host); |
1298 | carddetect = -ENOSYS; | 1317 | carddetect = -ENOSYS; |
@@ -1618,12 +1637,10 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1618 | if (ios->power_mode != host->power_mode) { | 1637 | if (ios->power_mode != host->power_mode) { |
1619 | switch (ios->power_mode) { | 1638 | switch (ios->power_mode) { |
1620 | case MMC_POWER_OFF: | 1639 | case MMC_POWER_OFF: |
1621 | mmc_slot(host).set_power(host->dev, host->slot_id, | 1640 | mmc_pdata(host)->set_power(host->dev, 0, 0); |
1622 | 0, 0); | ||
1623 | break; | 1641 | break; |
1624 | case MMC_POWER_UP: | 1642 | case MMC_POWER_UP: |
1625 | mmc_slot(host).set_power(host->dev, host->slot_id, | 1643 | mmc_pdata(host)->set_power(host->dev, 1, ios->vdd); |
1626 | 1, ios->vdd); | ||
1627 | break; | 1644 | break; |
1628 | case MMC_POWER_ON: | 1645 | case MMC_POWER_ON: |
1629 | do_send_init_stream = 1; | 1646 | do_send_init_stream = 1; |
@@ -1668,26 +1685,26 @@ static int omap_hsmmc_get_cd(struct mmc_host *mmc) | |||
1668 | { | 1685 | { |
1669 | struct omap_hsmmc_host *host = mmc_priv(mmc); | 1686 | struct omap_hsmmc_host *host = mmc_priv(mmc); |
1670 | 1687 | ||
1671 | if (!mmc_slot(host).card_detect) | 1688 | if (!host->card_detect) |
1672 | return -ENOSYS; | 1689 | return -ENOSYS; |
1673 | return mmc_slot(host).card_detect(host->dev, host->slot_id); | 1690 | return host->card_detect(host->dev); |
1674 | } | 1691 | } |
1675 | 1692 | ||
1676 | static int omap_hsmmc_get_ro(struct mmc_host *mmc) | 1693 | static int omap_hsmmc_get_ro(struct mmc_host *mmc) |
1677 | { | 1694 | { |
1678 | struct omap_hsmmc_host *host = mmc_priv(mmc); | 1695 | struct omap_hsmmc_host *host = mmc_priv(mmc); |
1679 | 1696 | ||
1680 | if (!mmc_slot(host).get_ro) | 1697 | if (!host->get_ro) |
1681 | return -ENOSYS; | 1698 | return -ENOSYS; |
1682 | return mmc_slot(host).get_ro(host->dev, 0); | 1699 | return host->get_ro(host->dev); |
1683 | } | 1700 | } |
1684 | 1701 | ||
1685 | static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card) | 1702 | static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card) |
1686 | { | 1703 | { |
1687 | struct omap_hsmmc_host *host = mmc_priv(mmc); | 1704 | struct omap_hsmmc_host *host = mmc_priv(mmc); |
1688 | 1705 | ||
1689 | if (mmc_slot(host).init_card) | 1706 | if (mmc_pdata(host)->init_card) |
1690 | mmc_slot(host).init_card(card); | 1707 | mmc_pdata(host)->init_card(card); |
1691 | } | 1708 | } |
1692 | 1709 | ||
1693 | static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | 1710 | static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable) |
@@ -1957,9 +1974,9 @@ static const struct of_device_id omap_mmc_of_match[] = { | |||
1957 | }; | 1974 | }; |
1958 | MODULE_DEVICE_TABLE(of, omap_mmc_of_match); | 1975 | MODULE_DEVICE_TABLE(of, omap_mmc_of_match); |
1959 | 1976 | ||
1960 | static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) | 1977 | static struct omap_hsmmc_platform_data *of_get_hsmmc_pdata(struct device *dev) |
1961 | { | 1978 | { |
1962 | struct omap_mmc_platform_data *pdata; | 1979 | struct omap_hsmmc_platform_data *pdata; |
1963 | struct device_node *np = dev->of_node; | 1980 | struct device_node *np = dev->of_node; |
1964 | u32 bus_width, max_freq; | 1981 | u32 bus_width, max_freq; |
1965 | int cd_gpio, wp_gpio; | 1982 | int cd_gpio, wp_gpio; |
@@ -1976,40 +1993,38 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) | |||
1976 | if (of_find_property(np, "ti,dual-volt", NULL)) | 1993 | if (of_find_property(np, "ti,dual-volt", NULL)) |
1977 | pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; | 1994 | pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; |
1978 | 1995 | ||
1979 | /* This driver only supports 1 slot */ | 1996 | pdata->switch_pin = cd_gpio; |
1980 | pdata->nr_slots = 1; | 1997 | pdata->gpio_wp = wp_gpio; |
1981 | pdata->slots[0].switch_pin = cd_gpio; | ||
1982 | pdata->slots[0].gpio_wp = wp_gpio; | ||
1983 | 1998 | ||
1984 | if (of_find_property(np, "ti,non-removable", NULL)) { | 1999 | if (of_find_property(np, "ti,non-removable", NULL)) { |
1985 | pdata->slots[0].nonremovable = true; | 2000 | pdata->nonremovable = true; |
1986 | pdata->slots[0].no_regulator_off_init = true; | 2001 | pdata->no_regulator_off_init = true; |
1987 | } | 2002 | } |
1988 | of_property_read_u32(np, "bus-width", &bus_width); | 2003 | of_property_read_u32(np, "bus-width", &bus_width); |
1989 | if (bus_width == 4) | 2004 | if (bus_width == 4) |
1990 | pdata->slots[0].caps |= MMC_CAP_4_BIT_DATA; | 2005 | pdata->caps |= MMC_CAP_4_BIT_DATA; |
1991 | else if (bus_width == 8) | 2006 | else if (bus_width == 8) |
1992 | pdata->slots[0].caps |= MMC_CAP_8_BIT_DATA; | 2007 | pdata->caps |= MMC_CAP_8_BIT_DATA; |
1993 | 2008 | ||
1994 | if (of_find_property(np, "ti,needs-special-reset", NULL)) | 2009 | if (of_find_property(np, "ti,needs-special-reset", NULL)) |
1995 | pdata->slots[0].features |= HSMMC_HAS_UPDATED_RESET; | 2010 | pdata->features |= HSMMC_HAS_UPDATED_RESET; |
1996 | 2011 | ||
1997 | if (!of_property_read_u32(np, "max-frequency", &max_freq)) | 2012 | if (!of_property_read_u32(np, "max-frequency", &max_freq)) |
1998 | pdata->max_freq = max_freq; | 2013 | pdata->max_freq = max_freq; |
1999 | 2014 | ||
2000 | if (of_find_property(np, "ti,needs-special-hs-handling", NULL)) | 2015 | if (of_find_property(np, "ti,needs-special-hs-handling", NULL)) |
2001 | pdata->slots[0].features |= HSMMC_HAS_HSPE_SUPPORT; | 2016 | pdata->features |= HSMMC_HAS_HSPE_SUPPORT; |
2002 | 2017 | ||
2003 | if (of_find_property(np, "keep-power-in-suspend", NULL)) | 2018 | if (of_find_property(np, "keep-power-in-suspend", NULL)) |
2004 | pdata->slots[0].pm_caps |= MMC_PM_KEEP_POWER; | 2019 | pdata->pm_caps |= MMC_PM_KEEP_POWER; |
2005 | 2020 | ||
2006 | if (of_find_property(np, "enable-sdio-wakeup", NULL)) | 2021 | if (of_find_property(np, "enable-sdio-wakeup", NULL)) |
2007 | pdata->slots[0].pm_caps |= MMC_PM_WAKE_SDIO_IRQ; | 2022 | pdata->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; |
2008 | 2023 | ||
2009 | return pdata; | 2024 | return pdata; |
2010 | } | 2025 | } |
2011 | #else | 2026 | #else |
2012 | static inline struct omap_mmc_platform_data | 2027 | static inline struct omap_hsmmc_platform_data |
2013 | *of_get_hsmmc_pdata(struct device *dev) | 2028 | *of_get_hsmmc_pdata(struct device *dev) |
2014 | { | 2029 | { |
2015 | return ERR_PTR(-EINVAL); | 2030 | return ERR_PTR(-EINVAL); |
@@ -2018,7 +2033,7 @@ static inline struct omap_mmc_platform_data | |||
2018 | 2033 | ||
2019 | static int omap_hsmmc_probe(struct platform_device *pdev) | 2034 | static int omap_hsmmc_probe(struct platform_device *pdev) |
2020 | { | 2035 | { |
2021 | struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; | 2036 | struct omap_hsmmc_platform_data *pdata = pdev->dev.platform_data; |
2022 | struct mmc_host *mmc; | 2037 | struct mmc_host *mmc; |
2023 | struct omap_hsmmc_host *host = NULL; | 2038 | struct omap_hsmmc_host *host = NULL; |
2024 | struct resource *res; | 2039 | struct resource *res; |
@@ -2048,11 +2063,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2048 | return -ENXIO; | 2063 | return -ENXIO; |
2049 | } | 2064 | } |
2050 | 2065 | ||
2051 | if (pdata->nr_slots == 0) { | ||
2052 | dev_err(&pdev->dev, "No Slots\n"); | ||
2053 | return -ENXIO; | ||
2054 | } | ||
2055 | |||
2056 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2066 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2057 | irq = platform_get_irq(pdev, 0); | 2067 | irq = platform_get_irq(pdev, 0); |
2058 | if (res == NULL || irq < 0) | 2068 | if (res == NULL || irq < 0) |
@@ -2062,14 +2072,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2062 | if (IS_ERR(base)) | 2072 | if (IS_ERR(base)) |
2063 | return PTR_ERR(base); | 2073 | return PTR_ERR(base); |
2064 | 2074 | ||
2065 | ret = omap_hsmmc_gpio_init(pdata); | ||
2066 | if (ret) | ||
2067 | goto err; | ||
2068 | |||
2069 | mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev); | 2075 | mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev); |
2070 | if (!mmc) { | 2076 | if (!mmc) { |
2071 | ret = -ENOMEM; | 2077 | ret = -ENOMEM; |
2072 | goto err_alloc; | 2078 | goto err; |
2073 | } | 2079 | } |
2074 | 2080 | ||
2075 | host = mmc_priv(mmc); | 2081 | host = mmc_priv(mmc); |
@@ -2079,13 +2085,16 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2079 | host->use_dma = 1; | 2085 | host->use_dma = 1; |
2080 | host->dma_ch = -1; | 2086 | host->dma_ch = -1; |
2081 | host->irq = irq; | 2087 | host->irq = irq; |
2082 | host->slot_id = 0; | ||
2083 | host->mapbase = res->start + pdata->reg_offset; | 2088 | host->mapbase = res->start + pdata->reg_offset; |
2084 | host->base = base + pdata->reg_offset; | 2089 | host->base = base + pdata->reg_offset; |
2085 | host->power_mode = MMC_POWER_OFF; | 2090 | host->power_mode = MMC_POWER_OFF; |
2086 | host->next_data.cookie = 1; | 2091 | host->next_data.cookie = 1; |
2087 | host->pbias_enabled = 0; | 2092 | host->pbias_enabled = 0; |
2088 | 2093 | ||
2094 | ret = omap_hsmmc_gpio_init(host, pdata); | ||
2095 | if (ret) | ||
2096 | goto err_gpio; | ||
2097 | |||
2089 | platform_set_drvdata(pdev, host); | 2098 | platform_set_drvdata(pdev, host); |
2090 | 2099 | ||
2091 | if (pdev->dev.of_node) | 2100 | if (pdev->dev.of_node) |
@@ -2144,14 +2153,14 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2144 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | | 2153 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | |
2145 | MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE; | 2154 | MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE; |
2146 | 2155 | ||
2147 | mmc->caps |= mmc_slot(host).caps; | 2156 | mmc->caps |= mmc_pdata(host)->caps; |
2148 | if (mmc->caps & MMC_CAP_8_BIT_DATA) | 2157 | if (mmc->caps & MMC_CAP_8_BIT_DATA) |
2149 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 2158 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
2150 | 2159 | ||
2151 | if (mmc_slot(host).nonremovable) | 2160 | if (mmc_pdata(host)->nonremovable) |
2152 | mmc->caps |= MMC_CAP_NONREMOVABLE; | 2161 | mmc->caps |= MMC_CAP_NONREMOVABLE; |
2153 | 2162 | ||
2154 | mmc->pm_caps = mmc_slot(host).pm_caps; | 2163 | mmc->pm_caps = mmc_pdata(host)->pm_caps; |
2155 | 2164 | ||
2156 | omap_hsmmc_conf_bus_power(host); | 2165 | omap_hsmmc_conf_bus_power(host); |
2157 | 2166 | ||
@@ -2204,27 +2213,19 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2204 | goto err_irq; | 2213 | goto err_irq; |
2205 | } | 2214 | } |
2206 | 2215 | ||
2207 | if (pdata->init != NULL) { | 2216 | if (omap_hsmmc_have_reg() && !mmc_pdata(host)->set_power) { |
2208 | if (pdata->init(&pdev->dev) != 0) { | ||
2209 | dev_err(mmc_dev(host->mmc), | ||
2210 | "Unable to configure MMC IRQs\n"); | ||
2211 | goto err_irq; | ||
2212 | } | ||
2213 | } | ||
2214 | |||
2215 | if (omap_hsmmc_have_reg() && !mmc_slot(host).set_power) { | ||
2216 | ret = omap_hsmmc_reg_get(host); | 2217 | ret = omap_hsmmc_reg_get(host); |
2217 | if (ret) | 2218 | if (ret) |
2218 | goto err_reg; | 2219 | goto err_irq; |
2219 | host->use_reg = 1; | 2220 | host->use_reg = 1; |
2220 | } | 2221 | } |
2221 | 2222 | ||
2222 | mmc->ocr_avail = mmc_slot(host).ocr_mask; | 2223 | mmc->ocr_avail = mmc_pdata(host)->ocr_mask; |
2223 | 2224 | ||
2224 | /* Request IRQ for card detect */ | 2225 | /* Request IRQ for card detect */ |
2225 | if ((mmc_slot(host).card_detect_irq)) { | 2226 | if (host->card_detect_irq) { |
2226 | ret = devm_request_threaded_irq(&pdev->dev, | 2227 | ret = devm_request_threaded_irq(&pdev->dev, |
2227 | mmc_slot(host).card_detect_irq, | 2228 | host->card_detect_irq, |
2228 | NULL, omap_hsmmc_detect, | 2229 | NULL, omap_hsmmc_detect, |
2229 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 2230 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
2230 | mmc_hostname(mmc), host); | 2231 | mmc_hostname(mmc), host); |
@@ -2233,8 +2234,8 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2233 | "Unable to grab MMC CD IRQ\n"); | 2234 | "Unable to grab MMC CD IRQ\n"); |
2234 | goto err_irq_cd; | 2235 | goto err_irq_cd; |
2235 | } | 2236 | } |
2236 | pdata->suspend = omap_hsmmc_suspend_cdirq; | 2237 | host->suspend = omap_hsmmc_suspend_cdirq; |
2237 | pdata->resume = omap_hsmmc_resume_cdirq; | 2238 | host->resume = omap_hsmmc_resume_cdirq; |
2238 | } | 2239 | } |
2239 | 2240 | ||
2240 | omap_hsmmc_disable_irq(host); | 2241 | omap_hsmmc_disable_irq(host); |
@@ -2255,12 +2256,12 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2255 | 2256 | ||
2256 | mmc_add_host(mmc); | 2257 | mmc_add_host(mmc); |
2257 | 2258 | ||
2258 | if (mmc_slot(host).name != NULL) { | 2259 | if (mmc_pdata(host)->name != NULL) { |
2259 | ret = device_create_file(&mmc->class_dev, &dev_attr_slot_name); | 2260 | ret = device_create_file(&mmc->class_dev, &dev_attr_slot_name); |
2260 | if (ret < 0) | 2261 | if (ret < 0) |
2261 | goto err_slot_name; | 2262 | goto err_slot_name; |
2262 | } | 2263 | } |
2263 | if (mmc_slot(host).card_detect_irq && mmc_slot(host).get_cover_state) { | 2264 | if (host->card_detect_irq && host->get_cover_state) { |
2264 | ret = device_create_file(&mmc->class_dev, | 2265 | ret = device_create_file(&mmc->class_dev, |
2265 | &dev_attr_cover_switch); | 2266 | &dev_attr_cover_switch); |
2266 | if (ret < 0) | 2267 | if (ret < 0) |
@@ -2278,9 +2279,6 @@ err_slot_name: | |||
2278 | err_irq_cd: | 2279 | err_irq_cd: |
2279 | if (host->use_reg) | 2280 | if (host->use_reg) |
2280 | omap_hsmmc_reg_put(host); | 2281 | omap_hsmmc_reg_put(host); |
2281 | err_reg: | ||
2282 | if (host->pdata->cleanup) | ||
2283 | host->pdata->cleanup(&pdev->dev); | ||
2284 | err_irq: | 2282 | err_irq: |
2285 | if (host->tx_chan) | 2283 | if (host->tx_chan) |
2286 | dma_release_channel(host->tx_chan); | 2284 | dma_release_channel(host->tx_chan); |
@@ -2291,9 +2289,9 @@ err_irq: | |||
2291 | if (host->dbclk) | 2289 | if (host->dbclk) |
2292 | clk_disable_unprepare(host->dbclk); | 2290 | clk_disable_unprepare(host->dbclk); |
2293 | err1: | 2291 | err1: |
2292 | omap_hsmmc_gpio_free(host, pdata); | ||
2293 | err_gpio: | ||
2294 | mmc_free_host(mmc); | 2294 | mmc_free_host(mmc); |
2295 | err_alloc: | ||
2296 | omap_hsmmc_gpio_free(pdata); | ||
2297 | err: | 2295 | err: |
2298 | return ret; | 2296 | return ret; |
2299 | } | 2297 | } |
@@ -2306,8 +2304,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
2306 | mmc_remove_host(host->mmc); | 2304 | mmc_remove_host(host->mmc); |
2307 | if (host->use_reg) | 2305 | if (host->use_reg) |
2308 | omap_hsmmc_reg_put(host); | 2306 | omap_hsmmc_reg_put(host); |
2309 | if (host->pdata->cleanup) | ||
2310 | host->pdata->cleanup(&pdev->dev); | ||
2311 | 2307 | ||
2312 | if (host->tx_chan) | 2308 | if (host->tx_chan) |
2313 | dma_release_channel(host->tx_chan); | 2309 | dma_release_channel(host->tx_chan); |
@@ -2319,7 +2315,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
2319 | if (host->dbclk) | 2315 | if (host->dbclk) |
2320 | clk_disable_unprepare(host->dbclk); | 2316 | clk_disable_unprepare(host->dbclk); |
2321 | 2317 | ||
2322 | omap_hsmmc_gpio_free(host->pdata); | 2318 | omap_hsmmc_gpio_free(host, host->pdata); |
2323 | mmc_free_host(host->mmc); | 2319 | mmc_free_host(host->mmc); |
2324 | 2320 | ||
2325 | return 0; | 2321 | return 0; |
@@ -2330,8 +2326,8 @@ static int omap_hsmmc_prepare(struct device *dev) | |||
2330 | { | 2326 | { |
2331 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 2327 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
2332 | 2328 | ||
2333 | if (host->pdata->suspend) | 2329 | if (host->suspend) |
2334 | return host->pdata->suspend(dev, host->slot_id); | 2330 | return host->suspend(dev); |
2335 | 2331 | ||
2336 | return 0; | 2332 | return 0; |
2337 | } | 2333 | } |
@@ -2340,8 +2336,8 @@ static void omap_hsmmc_complete(struct device *dev) | |||
2340 | { | 2336 | { |
2341 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 2337 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
2342 | 2338 | ||
2343 | if (host->pdata->resume) | 2339 | if (host->resume) |
2344 | host->pdata->resume(dev, host->slot_id); | 2340 | host->resume(dev); |
2345 | 2341 | ||
2346 | } | 2342 | } |
2347 | 2343 | ||
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 9cccc0e89b04..daba49ac1242 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
@@ -76,6 +76,7 @@ struct sdhci_acpi_host { | |||
76 | const struct sdhci_acpi_slot *slot; | 76 | const struct sdhci_acpi_slot *slot; |
77 | struct platform_device *pdev; | 77 | struct platform_device *pdev; |
78 | bool use_runtime_pm; | 78 | bool use_runtime_pm; |
79 | bool dma_setup; | ||
79 | }; | 80 | }; |
80 | 81 | ||
81 | static inline bool sdhci_acpi_flag(struct sdhci_acpi_host *c, unsigned int flag) | 82 | static inline bool sdhci_acpi_flag(struct sdhci_acpi_host *c, unsigned int flag) |
@@ -85,7 +86,29 @@ static inline bool sdhci_acpi_flag(struct sdhci_acpi_host *c, unsigned int flag) | |||
85 | 86 | ||
86 | static int sdhci_acpi_enable_dma(struct sdhci_host *host) | 87 | static int sdhci_acpi_enable_dma(struct sdhci_host *host) |
87 | { | 88 | { |
88 | return 0; | 89 | struct sdhci_acpi_host *c = sdhci_priv(host); |
90 | struct device *dev = &c->pdev->dev; | ||
91 | int err = -1; | ||
92 | |||
93 | if (c->dma_setup) | ||
94 | return 0; | ||
95 | |||
96 | if (host->flags & SDHCI_USE_64_BIT_DMA) { | ||
97 | if (host->quirks2 & SDHCI_QUIRK2_BROKEN_64_BIT_DMA) { | ||
98 | host->flags &= ~SDHCI_USE_64_BIT_DMA; | ||
99 | } else { | ||
100 | err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); | ||
101 | if (err) | ||
102 | dev_warn(dev, "Failed to set 64-bit DMA mask\n"); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | if (err) | ||
107 | err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); | ||
108 | |||
109 | c->dma_setup = !err; | ||
110 | |||
111 | return err; | ||
89 | } | 112 | } |
90 | 113 | ||
91 | static void sdhci_acpi_int_hw_reset(struct sdhci_host *host) | 114 | static void sdhci_acpi_int_hw_reset(struct sdhci_host *host) |
@@ -180,17 +203,21 @@ static int sdhci_acpi_sd_probe_slot(struct platform_device *pdev, | |||
180 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = { | 203 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = { |
181 | .chip = &sdhci_acpi_chip_int, | 204 | .chip = &sdhci_acpi_chip_int, |
182 | .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | | 205 | .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | |
183 | MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR, | 206 | MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR | |
207 | MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY, | ||
184 | .caps2 = MMC_CAP2_HC_ERASE_SZ, | 208 | .caps2 = MMC_CAP2_HC_ERASE_SZ, |
185 | .flags = SDHCI_ACPI_RUNTIME_PM, | 209 | .flags = SDHCI_ACPI_RUNTIME_PM, |
210 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | ||
186 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | SDHCI_QUIRK2_STOP_WITH_TC, | 211 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | SDHCI_QUIRK2_STOP_WITH_TC, |
187 | .probe_slot = sdhci_acpi_emmc_probe_slot, | 212 | .probe_slot = sdhci_acpi_emmc_probe_slot, |
188 | }; | 213 | }; |
189 | 214 | ||
190 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { | 215 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { |
191 | .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION, | 216 | .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | |
217 | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | ||
192 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON, | 218 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON, |
193 | .caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD, | 219 | .caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD | |
220 | MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY, | ||
194 | .flags = SDHCI_ACPI_RUNTIME_PM, | 221 | .flags = SDHCI_ACPI_RUNTIME_PM, |
195 | .pm_caps = MMC_PM_KEEP_POWER, | 222 | .pm_caps = MMC_PM_KEEP_POWER, |
196 | .probe_slot = sdhci_acpi_sdio_probe_slot, | 223 | .probe_slot = sdhci_acpi_sdio_probe_slot, |
@@ -199,8 +226,10 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { | |||
199 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { | 226 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { |
200 | .flags = SDHCI_ACPI_SD_CD | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL | | 227 | .flags = SDHCI_ACPI_SD_CD | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL | |
201 | SDHCI_ACPI_RUNTIME_PM, | 228 | SDHCI_ACPI_RUNTIME_PM, |
229 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | ||
202 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | | 230 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | |
203 | SDHCI_QUIRK2_STOP_WITH_TC, | 231 | SDHCI_QUIRK2_STOP_WITH_TC, |
232 | .caps = MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY, | ||
204 | .probe_slot = sdhci_acpi_sd_probe_slot, | 233 | .probe_slot = sdhci_acpi_sd_probe_slot, |
205 | }; | 234 | }; |
206 | 235 | ||
@@ -305,21 +334,6 @@ static int sdhci_acpi_probe(struct platform_device *pdev) | |||
305 | goto err_free; | 334 | goto err_free; |
306 | } | 335 | } |
307 | 336 | ||
308 | if (!dev->dma_mask) { | ||
309 | u64 dma_mask; | ||
310 | |||
311 | if (sdhci_readl(host, SDHCI_CAPABILITIES) & SDHCI_CAN_64BIT) { | ||
312 | /* 64-bit DMA is not supported at present */ | ||
313 | dma_mask = DMA_BIT_MASK(32); | ||
314 | } else { | ||
315 | dma_mask = DMA_BIT_MASK(32); | ||
316 | } | ||
317 | |||
318 | err = dma_coerce_mask_and_coherent(dev, dma_mask); | ||
319 | if (err) | ||
320 | goto err_free; | ||
321 | } | ||
322 | |||
323 | if (c->slot) { | 337 | if (c->slot) { |
324 | if (c->slot->probe_slot) { | 338 | if (c->slot->probe_slot) { |
325 | err = c->slot->probe_slot(pdev, hid, uid); | 339 | err = c->slot->probe_slot(pdev, hid, uid); |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 587ee0edeb57..12711ab51aed 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
@@ -65,8 +65,6 @@ | |||
65 | /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ | 65 | /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ |
66 | #define ESDHC_TUNING_START_TAP 0x1 | 66 | #define ESDHC_TUNING_START_TAP 0x1 |
67 | 67 | ||
68 | #define ESDHC_TUNING_BLOCK_PATTERN_LEN 64 | ||
69 | |||
70 | /* pinctrl state */ | 68 | /* pinctrl state */ |
71 | #define ESDHC_PINCTRL_STATE_100MHZ "state_100mhz" | 69 | #define ESDHC_PINCTRL_STATE_100MHZ "state_100mhz" |
72 | #define ESDHC_PINCTRL_STATE_200MHZ "state_200mhz" | 70 | #define ESDHC_PINCTRL_STATE_200MHZ "state_200mhz" |
@@ -692,8 +690,6 @@ static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val) | |||
692 | /* FIXME: delay a bit for card to be ready for next tuning due to errors */ | 690 | /* FIXME: delay a bit for card to be ready for next tuning due to errors */ |
693 | mdelay(1); | 691 | mdelay(1); |
694 | 692 | ||
695 | /* This is balanced by the runtime put in sdhci_tasklet_finish */ | ||
696 | pm_runtime_get_sync(host->mmc->parent); | ||
697 | reg = readl(host->ioaddr + ESDHC_MIX_CTRL); | 693 | reg = readl(host->ioaddr + ESDHC_MIX_CTRL); |
698 | reg |= ESDHC_MIX_CTRL_EXE_TUNE | ESDHC_MIX_CTRL_SMPCLK_SEL | | 694 | reg |= ESDHC_MIX_CTRL_EXE_TUNE | ESDHC_MIX_CTRL_SMPCLK_SEL | |
699 | ESDHC_MIX_CTRL_FBCLK_SEL; | 695 | ESDHC_MIX_CTRL_FBCLK_SEL; |
@@ -704,54 +700,6 @@ static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val) | |||
704 | val, readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS)); | 700 | val, readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS)); |
705 | } | 701 | } |
706 | 702 | ||
707 | static void esdhc_request_done(struct mmc_request *mrq) | ||
708 | { | ||
709 | complete(&mrq->completion); | ||
710 | } | ||
711 | |||
712 | static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode, | ||
713 | struct scatterlist *sg) | ||
714 | { | ||
715 | struct mmc_command cmd = {0}; | ||
716 | struct mmc_request mrq = {NULL}; | ||
717 | struct mmc_data data = {0}; | ||
718 | |||
719 | cmd.opcode = opcode; | ||
720 | cmd.arg = 0; | ||
721 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
722 | |||
723 | data.blksz = ESDHC_TUNING_BLOCK_PATTERN_LEN; | ||
724 | data.blocks = 1; | ||
725 | data.flags = MMC_DATA_READ; | ||
726 | data.sg = sg; | ||
727 | data.sg_len = 1; | ||
728 | |||
729 | mrq.cmd = &cmd; | ||
730 | mrq.cmd->mrq = &mrq; | ||
731 | mrq.data = &data; | ||
732 | mrq.data->mrq = &mrq; | ||
733 | mrq.cmd->data = mrq.data; | ||
734 | |||
735 | mrq.done = esdhc_request_done; | ||
736 | init_completion(&(mrq.completion)); | ||
737 | |||
738 | spin_lock_irq(&host->lock); | ||
739 | host->mrq = &mrq; | ||
740 | |||
741 | sdhci_send_command(host, mrq.cmd); | ||
742 | |||
743 | spin_unlock_irq(&host->lock); | ||
744 | |||
745 | wait_for_completion(&mrq.completion); | ||
746 | |||
747 | if (cmd.error) | ||
748 | return cmd.error; | ||
749 | if (data.error) | ||
750 | return data.error; | ||
751 | |||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | static void esdhc_post_tuning(struct sdhci_host *host) | 703 | static void esdhc_post_tuning(struct sdhci_host *host) |
756 | { | 704 | { |
757 | u32 reg; | 705 | u32 reg; |
@@ -763,21 +711,13 @@ static void esdhc_post_tuning(struct sdhci_host *host) | |||
763 | 711 | ||
764 | static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode) | 712 | static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode) |
765 | { | 713 | { |
766 | struct scatterlist sg; | ||
767 | char *tuning_pattern; | ||
768 | int min, max, avg, ret; | 714 | int min, max, avg, ret; |
769 | 715 | ||
770 | tuning_pattern = kmalloc(ESDHC_TUNING_BLOCK_PATTERN_LEN, GFP_KERNEL); | ||
771 | if (!tuning_pattern) | ||
772 | return -ENOMEM; | ||
773 | |||
774 | sg_init_one(&sg, tuning_pattern, ESDHC_TUNING_BLOCK_PATTERN_LEN); | ||
775 | |||
776 | /* find the mininum delay first which can pass tuning */ | 716 | /* find the mininum delay first which can pass tuning */ |
777 | min = ESDHC_TUNE_CTRL_MIN; | 717 | min = ESDHC_TUNE_CTRL_MIN; |
778 | while (min < ESDHC_TUNE_CTRL_MAX) { | 718 | while (min < ESDHC_TUNE_CTRL_MAX) { |
779 | esdhc_prepare_tuning(host, min); | 719 | esdhc_prepare_tuning(host, min); |
780 | if (!esdhc_send_tuning_cmd(host, opcode, &sg)) | 720 | if (!mmc_send_tuning(host->mmc)) |
781 | break; | 721 | break; |
782 | min += ESDHC_TUNE_CTRL_STEP; | 722 | min += ESDHC_TUNE_CTRL_STEP; |
783 | } | 723 | } |
@@ -786,7 +726,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode) | |||
786 | max = min + ESDHC_TUNE_CTRL_STEP; | 726 | max = min + ESDHC_TUNE_CTRL_STEP; |
787 | while (max < ESDHC_TUNE_CTRL_MAX) { | 727 | while (max < ESDHC_TUNE_CTRL_MAX) { |
788 | esdhc_prepare_tuning(host, max); | 728 | esdhc_prepare_tuning(host, max); |
789 | if (esdhc_send_tuning_cmd(host, opcode, &sg)) { | 729 | if (mmc_send_tuning(host->mmc)) { |
790 | max -= ESDHC_TUNE_CTRL_STEP; | 730 | max -= ESDHC_TUNE_CTRL_STEP; |
791 | break; | 731 | break; |
792 | } | 732 | } |
@@ -796,11 +736,9 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode) | |||
796 | /* use average delay to get the best timing */ | 736 | /* use average delay to get the best timing */ |
797 | avg = (min + max) / 2; | 737 | avg = (min + max) / 2; |
798 | esdhc_prepare_tuning(host, avg); | 738 | esdhc_prepare_tuning(host, avg); |
799 | ret = esdhc_send_tuning_cmd(host, opcode, &sg); | 739 | ret = mmc_send_tuning(host->mmc); |
800 | esdhc_post_tuning(host); | 740 | esdhc_post_tuning(host); |
801 | 741 | ||
802 | kfree(tuning_pattern); | ||
803 | |||
804 | dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n", | 742 | dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n", |
805 | ret ? "failed" : "passed", avg, ret); | 743 | ret ? "failed" : "passed", avg, ret); |
806 | 744 | ||
@@ -1031,11 +969,8 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) | |||
1031 | 969 | ||
1032 | imx_data->pins_default = pinctrl_lookup_state(imx_data->pinctrl, | 970 | imx_data->pins_default = pinctrl_lookup_state(imx_data->pinctrl, |
1033 | PINCTRL_STATE_DEFAULT); | 971 | PINCTRL_STATE_DEFAULT); |
1034 | if (IS_ERR(imx_data->pins_default)) { | 972 | if (IS_ERR(imx_data->pins_default)) |
1035 | err = PTR_ERR(imx_data->pins_default); | 973 | dev_warn(mmc_dev(host->mmc), "could not get default state\n"); |
1036 | dev_err(mmc_dev(host->mmc), "could not get default state\n"); | ||
1037 | goto disable_clk; | ||
1038 | } | ||
1039 | 974 | ||
1040 | host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; | 975 | host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; |
1041 | 976 | ||
@@ -1123,7 +1058,8 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) | |||
1123 | } | 1058 | } |
1124 | 1059 | ||
1125 | /* sdr50 and sdr104 needs work on 1.8v signal voltage */ | 1060 | /* sdr50 and sdr104 needs work on 1.8v signal voltage */ |
1126 | if ((boarddata->support_vsel) && esdhc_is_usdhc(imx_data)) { | 1061 | if ((boarddata->support_vsel) && esdhc_is_usdhc(imx_data) && |
1062 | !IS_ERR(imx_data->pins_default)) { | ||
1127 | imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl, | 1063 | imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl, |
1128 | ESDHC_PINCTRL_STATE_100MHZ); | 1064 | ESDHC_PINCTRL_STATE_100MHZ); |
1129 | imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, | 1065 | imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, |
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 30804385af6d..3d32ce896b09 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c | |||
@@ -339,9 +339,7 @@ static int msm_init_cm_dll(struct sdhci_host *host) | |||
339 | static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode) | 339 | static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode) |
340 | { | 340 | { |
341 | int tuning_seq_cnt = 3; | 341 | int tuning_seq_cnt = 3; |
342 | u8 phase, *data_buf, tuned_phases[16], tuned_phase_cnt = 0; | 342 | u8 phase, tuned_phases[16], tuned_phase_cnt = 0; |
343 | const u8 *tuning_block_pattern = tuning_blk_pattern_4bit; | ||
344 | int size = sizeof(tuning_blk_pattern_4bit); | ||
345 | int rc; | 343 | int rc; |
346 | struct mmc_host *mmc = host->mmc; | 344 | struct mmc_host *mmc = host->mmc; |
347 | struct mmc_ios ios = host->mmc->ios; | 345 | struct mmc_ios ios = host->mmc->ios; |
@@ -355,53 +353,21 @@ static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode) | |||
355 | (ios.timing == MMC_TIMING_UHS_SDR104))) | 353 | (ios.timing == MMC_TIMING_UHS_SDR104))) |
356 | return 0; | 354 | return 0; |
357 | 355 | ||
358 | if ((opcode == MMC_SEND_TUNING_BLOCK_HS200) && | ||
359 | (mmc->ios.bus_width == MMC_BUS_WIDTH_8)) { | ||
360 | tuning_block_pattern = tuning_blk_pattern_8bit; | ||
361 | size = sizeof(tuning_blk_pattern_8bit); | ||
362 | } | ||
363 | |||
364 | data_buf = kmalloc(size, GFP_KERNEL); | ||
365 | if (!data_buf) | ||
366 | return -ENOMEM; | ||
367 | |||
368 | retry: | 356 | retry: |
369 | /* First of all reset the tuning block */ | 357 | /* First of all reset the tuning block */ |
370 | rc = msm_init_cm_dll(host); | 358 | rc = msm_init_cm_dll(host); |
371 | if (rc) | 359 | if (rc) |
372 | goto out; | 360 | return rc; |
373 | 361 | ||
374 | phase = 0; | 362 | phase = 0; |
375 | do { | 363 | do { |
376 | struct mmc_command cmd = { 0 }; | ||
377 | struct mmc_data data = { 0 }; | ||
378 | struct mmc_request mrq = { | ||
379 | .cmd = &cmd, | ||
380 | .data = &data | ||
381 | }; | ||
382 | struct scatterlist sg; | ||
383 | |||
384 | /* Set the phase in delay line hw block */ | 364 | /* Set the phase in delay line hw block */ |
385 | rc = msm_config_cm_dll_phase(host, phase); | 365 | rc = msm_config_cm_dll_phase(host, phase); |
386 | if (rc) | 366 | if (rc) |
387 | goto out; | 367 | return rc; |
388 | 368 | ||
389 | cmd.opcode = opcode; | 369 | rc = mmc_send_tuning(mmc); |
390 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | 370 | if (!rc) { |
391 | |||
392 | data.blksz = size; | ||
393 | data.blocks = 1; | ||
394 | data.flags = MMC_DATA_READ; | ||
395 | data.timeout_ns = NSEC_PER_SEC; /* 1 second */ | ||
396 | |||
397 | data.sg = &sg; | ||
398 | data.sg_len = 1; | ||
399 | sg_init_one(&sg, data_buf, size); | ||
400 | memset(data_buf, 0, size); | ||
401 | mmc_wait_for_req(mmc, &mrq); | ||
402 | |||
403 | if (!cmd.error && !data.error && | ||
404 | !memcmp(data_buf, tuning_block_pattern, size)) { | ||
405 | /* Tuning is successful at this tuning point */ | 371 | /* Tuning is successful at this tuning point */ |
406 | tuned_phases[tuned_phase_cnt++] = phase; | 372 | tuned_phases[tuned_phase_cnt++] = phase; |
407 | dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n", | 373 | dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n", |
@@ -413,7 +379,7 @@ retry: | |||
413 | rc = msm_find_most_appropriate_phase(host, tuned_phases, | 379 | rc = msm_find_most_appropriate_phase(host, tuned_phases, |
414 | tuned_phase_cnt); | 380 | tuned_phase_cnt); |
415 | if (rc < 0) | 381 | if (rc < 0) |
416 | goto out; | 382 | return rc; |
417 | else | 383 | else |
418 | phase = rc; | 384 | phase = rc; |
419 | 385 | ||
@@ -423,7 +389,7 @@ retry: | |||
423 | */ | 389 | */ |
424 | rc = msm_config_cm_dll_phase(host, phase); | 390 | rc = msm_config_cm_dll_phase(host, phase); |
425 | if (rc) | 391 | if (rc) |
426 | goto out; | 392 | return rc; |
427 | dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n", | 393 | dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n", |
428 | mmc_hostname(mmc), phase); | 394 | mmc_hostname(mmc), phase); |
429 | } else { | 395 | } else { |
@@ -435,8 +401,6 @@ retry: | |||
435 | rc = -EIO; | 401 | rc = -EIO; |
436 | } | 402 | } |
437 | 403 | ||
438 | out: | ||
439 | kfree(data_buf); | ||
440 | return rc; | 404 | return rc; |
441 | } | 405 | } |
442 | 406 | ||
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 981d66e5c023..bcb51e9dfdcd 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c | |||
@@ -165,7 +165,6 @@ static int sdhci_arasan_probe(struct platform_device *pdev) | |||
165 | host = sdhci_pltfm_init(pdev, &sdhci_arasan_pdata, 0); | 165 | host = sdhci_pltfm_init(pdev, &sdhci_arasan_pdata, 0); |
166 | if (IS_ERR(host)) { | 166 | if (IS_ERR(host)) { |
167 | ret = PTR_ERR(host); | 167 | ret = PTR_ERR(host); |
168 | dev_err(&pdev->dev, "platform init failed (%u)\n", ret); | ||
169 | goto clk_disable_all; | 168 | goto clk_disable_all; |
170 | } | 169 | } |
171 | 170 | ||
@@ -175,10 +174,8 @@ static int sdhci_arasan_probe(struct platform_device *pdev) | |||
175 | pltfm_host->clk = clk_xin; | 174 | pltfm_host->clk = clk_xin; |
176 | 175 | ||
177 | ret = sdhci_add_host(host); | 176 | ret = sdhci_add_host(host); |
178 | if (ret) { | 177 | if (ret) |
179 | dev_err(&pdev->dev, "platform register failed (%u)\n", ret); | ||
180 | goto err_pltfm_free; | 178 | goto err_pltfm_free; |
181 | } | ||
182 | 179 | ||
183 | return 0; | 180 | return 0; |
184 | 181 | ||
diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c index 5670e381b0cf..e2ec108dba0e 100644 --- a/drivers/mmc/host/sdhci-pci-o2micro.c +++ b/drivers/mmc/host/sdhci-pci-o2micro.c | |||
@@ -127,8 +127,6 @@ void sdhci_pci_o2_fujin2_pci_init(struct sdhci_pci_chip *chip) | |||
127 | return; | 127 | return; |
128 | scratch_32 &= ~((1 << 21) | (1 << 30)); | 128 | scratch_32 &= ~((1 << 21) | (1 << 30)); |
129 | 129 | ||
130 | /* Set RTD3 function disabled */ | ||
131 | scratch_32 |= ((1 << 29) | (1 << 28)); | ||
132 | pci_write_config_dword(chip->pdev, O2_SD_FUNC_REG3, scratch_32); | 130 | pci_write_config_dword(chip->pdev, O2_SD_FUNC_REG3, scratch_32); |
133 | 131 | ||
134 | /* Set L1 Entrance Timer */ | 132 | /* Set L1 Entrance Timer */ |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 61192973e7cb..95f73007fccf 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -269,7 +269,9 @@ static void sdhci_pci_int_hw_reset(struct sdhci_host *host) | |||
269 | static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) | 269 | static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) |
270 | { | 270 | { |
271 | slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | | 271 | slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | |
272 | MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR; | 272 | MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR | |
273 | MMC_CAP_BUS_WIDTH_TEST | | ||
274 | MMC_CAP_WAIT_WHILE_BUSY; | ||
273 | slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ; | 275 | slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ; |
274 | slot->hw_reset = sdhci_pci_int_hw_reset; | 276 | slot->hw_reset = sdhci_pci_int_hw_reset; |
275 | if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BSW_EMMC) | 277 | if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BSW_EMMC) |
@@ -279,12 +281,16 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) | |||
279 | 281 | ||
280 | static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot) | 282 | static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot) |
281 | { | 283 | { |
282 | slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE; | 284 | slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE | |
285 | MMC_CAP_BUS_WIDTH_TEST | | ||
286 | MMC_CAP_WAIT_WHILE_BUSY; | ||
283 | return 0; | 287 | return 0; |
284 | } | 288 | } |
285 | 289 | ||
286 | static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) | 290 | static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) |
287 | { | 291 | { |
292 | slot->host->mmc->caps |= MMC_CAP_BUS_WIDTH_TEST | | ||
293 | MMC_CAP_WAIT_WHILE_BUSY; | ||
288 | slot->cd_con_id = NULL; | 294 | slot->cd_con_id = NULL; |
289 | slot->cd_idx = 0; | 295 | slot->cd_idx = 0; |
290 | slot->cd_override_level = true; | 296 | slot->cd_override_level = true; |
@@ -294,11 +300,13 @@ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) | |||
294 | static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = { | 300 | static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = { |
295 | .allow_runtime_pm = true, | 301 | .allow_runtime_pm = true, |
296 | .probe_slot = byt_emmc_probe_slot, | 302 | .probe_slot = byt_emmc_probe_slot, |
303 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | ||
297 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | 304 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
298 | SDHCI_QUIRK2_STOP_WITH_TC, | 305 | SDHCI_QUIRK2_STOP_WITH_TC, |
299 | }; | 306 | }; |
300 | 307 | ||
301 | static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { | 308 | static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { |
309 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | ||
302 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON | | 310 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON | |
303 | SDHCI_QUIRK2_PRESET_VALUE_BROKEN, | 311 | SDHCI_QUIRK2_PRESET_VALUE_BROKEN, |
304 | .allow_runtime_pm = true, | 312 | .allow_runtime_pm = true, |
@@ -306,6 +314,7 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { | |||
306 | }; | 314 | }; |
307 | 315 | ||
308 | static const struct sdhci_pci_fixes sdhci_intel_byt_sd = { | 316 | static const struct sdhci_pci_fixes sdhci_intel_byt_sd = { |
317 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | ||
309 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | | 318 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | |
310 | SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | 319 | SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
311 | SDHCI_QUIRK2_STOP_WITH_TC, | 320 | SDHCI_QUIRK2_STOP_WITH_TC, |
@@ -645,6 +654,25 @@ static const struct sdhci_pci_fixes sdhci_rtsx = { | |||
645 | .probe_slot = rtsx_probe_slot, | 654 | .probe_slot = rtsx_probe_slot, |
646 | }; | 655 | }; |
647 | 656 | ||
657 | static int amd_probe(struct sdhci_pci_chip *chip) | ||
658 | { | ||
659 | struct pci_dev *smbus_dev; | ||
660 | |||
661 | smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, | ||
662 | PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL); | ||
663 | |||
664 | if (smbus_dev && (smbus_dev->revision < 0x51)) { | ||
665 | chip->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD; | ||
666 | chip->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; | ||
667 | } | ||
668 | |||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | static const struct sdhci_pci_fixes sdhci_amd = { | ||
673 | .probe = amd_probe, | ||
674 | }; | ||
675 | |||
648 | static const struct pci_device_id pci_ids[] = { | 676 | static const struct pci_device_id pci_ids[] = { |
649 | { | 677 | { |
650 | .vendor = PCI_VENDOR_ID_RICOH, | 678 | .vendor = PCI_VENDOR_ID_RICOH, |
@@ -1044,7 +1072,15 @@ static const struct pci_device_id pci_ids[] = { | |||
1044 | .subdevice = PCI_ANY_ID, | 1072 | .subdevice = PCI_ANY_ID, |
1045 | .driver_data = (kernel_ulong_t)&sdhci_o2, | 1073 | .driver_data = (kernel_ulong_t)&sdhci_o2, |
1046 | }, | 1074 | }, |
1047 | 1075 | { | |
1076 | .vendor = PCI_VENDOR_ID_AMD, | ||
1077 | .device = PCI_ANY_ID, | ||
1078 | .class = PCI_CLASS_SYSTEM_SDHCI << 8, | ||
1079 | .class_mask = 0xFFFF00, | ||
1080 | .subvendor = PCI_ANY_ID, | ||
1081 | .subdevice = PCI_ANY_ID, | ||
1082 | .driver_data = (kernel_ulong_t)&sdhci_amd, | ||
1083 | }, | ||
1048 | { /* Generic SD host controller */ | 1084 | { /* Generic SD host controller */ |
1049 | PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) | 1085 | PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) |
1050 | }, | 1086 | }, |
@@ -1064,7 +1100,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host) | |||
1064 | { | 1100 | { |
1065 | struct sdhci_pci_slot *slot; | 1101 | struct sdhci_pci_slot *slot; |
1066 | struct pci_dev *pdev; | 1102 | struct pci_dev *pdev; |
1067 | int ret; | 1103 | int ret = -1; |
1068 | 1104 | ||
1069 | slot = sdhci_priv(host); | 1105 | slot = sdhci_priv(host); |
1070 | pdev = slot->chip->pdev; | 1106 | pdev = slot->chip->pdev; |
@@ -1076,7 +1112,17 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host) | |||
1076 | "doesn't fully claim to support it.\n"); | 1112 | "doesn't fully claim to support it.\n"); |
1077 | } | 1113 | } |
1078 | 1114 | ||
1079 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 1115 | if (host->flags & SDHCI_USE_64_BIT_DMA) { |
1116 | if (host->quirks2 & SDHCI_QUIRK2_BROKEN_64_BIT_DMA) { | ||
1117 | host->flags &= ~SDHCI_USE_64_BIT_DMA; | ||
1118 | } else { | ||
1119 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); | ||
1120 | if (ret) | ||
1121 | dev_warn(&pdev->dev, "Failed to set 64-bit DMA mask\n"); | ||
1122 | } | ||
1123 | } | ||
1124 | if (ret) | ||
1125 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
1080 | if (ret) | 1126 | if (ret) |
1081 | return ret; | 1127 | return ret; |
1082 | 1128 | ||
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index b4c23e983baf..f98008b5ea77 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c | |||
@@ -167,23 +167,17 @@ static int sdhci_pxav2_probe(struct platform_device *pdev) | |||
167 | struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; | 167 | struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; |
168 | struct device *dev = &pdev->dev; | 168 | struct device *dev = &pdev->dev; |
169 | struct sdhci_host *host = NULL; | 169 | struct sdhci_host *host = NULL; |
170 | struct sdhci_pxa *pxa = NULL; | ||
171 | const struct of_device_id *match; | 170 | const struct of_device_id *match; |
172 | 171 | ||
173 | int ret; | 172 | int ret; |
174 | struct clk *clk; | 173 | struct clk *clk; |
175 | 174 | ||
176 | pxa = kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL); | ||
177 | if (!pxa) | ||
178 | return -ENOMEM; | ||
179 | |||
180 | host = sdhci_pltfm_init(pdev, NULL, 0); | 175 | host = sdhci_pltfm_init(pdev, NULL, 0); |
181 | if (IS_ERR(host)) { | 176 | if (IS_ERR(host)) |
182 | kfree(pxa); | ||
183 | return PTR_ERR(host); | 177 | return PTR_ERR(host); |
184 | } | 178 | |
185 | pltfm_host = sdhci_priv(host); | 179 | pltfm_host = sdhci_priv(host); |
186 | pltfm_host->priv = pxa; | 180 | pltfm_host->priv = NULL; |
187 | 181 | ||
188 | clk = clk_get(dev, "PXA-SDHCLK"); | 182 | clk = clk_get(dev, "PXA-SDHCLK"); |
189 | if (IS_ERR(clk)) { | 183 | if (IS_ERR(clk)) { |
@@ -238,7 +232,6 @@ err_add_host: | |||
238 | clk_put(clk); | 232 | clk_put(clk); |
239 | err_clk_get: | 233 | err_clk_get: |
240 | sdhci_pltfm_free(pdev); | 234 | sdhci_pltfm_free(pdev); |
241 | kfree(pxa); | ||
242 | return ret; | 235 | return ret; |
243 | } | 236 | } |
244 | 237 | ||
@@ -246,14 +239,12 @@ static int sdhci_pxav2_remove(struct platform_device *pdev) | |||
246 | { | 239 | { |
247 | struct sdhci_host *host = platform_get_drvdata(pdev); | 240 | struct sdhci_host *host = platform_get_drvdata(pdev); |
248 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 241 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
249 | struct sdhci_pxa *pxa = pltfm_host->priv; | ||
250 | 242 | ||
251 | sdhci_remove_host(host, 1); | 243 | sdhci_remove_host(host, 1); |
252 | 244 | ||
253 | clk_disable_unprepare(pltfm_host->clk); | 245 | clk_disable_unprepare(pltfm_host->clk); |
254 | clk_put(pltfm_host->clk); | 246 | clk_put(pltfm_host->clk); |
255 | sdhci_pltfm_free(pdev); | 247 | sdhci_pltfm_free(pdev); |
256 | kfree(pxa); | ||
257 | 248 | ||
258 | return 0; | 249 | return 0; |
259 | } | 250 | } |
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 5036d7d39529..ad0badad0ebc 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
@@ -58,6 +58,12 @@ | |||
58 | #define SDCE_MISC_INT (1<<2) | 58 | #define SDCE_MISC_INT (1<<2) |
59 | #define SDCE_MISC_INT_EN (1<<1) | 59 | #define SDCE_MISC_INT_EN (1<<1) |
60 | 60 | ||
61 | struct sdhci_pxa { | ||
62 | struct clk *clk_core; | ||
63 | struct clk *clk_io; | ||
64 | u8 power_mode; | ||
65 | }; | ||
66 | |||
61 | /* | 67 | /* |
62 | * These registers are relative to the second register region, for the | 68 | * These registers are relative to the second register region, for the |
63 | * MBus bridge. | 69 | * MBus bridge. |
@@ -211,6 +217,7 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) | |||
211 | case MMC_TIMING_UHS_SDR104: | 217 | case MMC_TIMING_UHS_SDR104: |
212 | ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180; | 218 | ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180; |
213 | break; | 219 | break; |
220 | case MMC_TIMING_MMC_DDR52: | ||
214 | case MMC_TIMING_UHS_DDR50: | 221 | case MMC_TIMING_UHS_DDR50: |
215 | ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180; | 222 | ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180; |
216 | break; | 223 | break; |
@@ -283,9 +290,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
283 | struct sdhci_host *host = NULL; | 290 | struct sdhci_host *host = NULL; |
284 | struct sdhci_pxa *pxa = NULL; | 291 | struct sdhci_pxa *pxa = NULL; |
285 | const struct of_device_id *match; | 292 | const struct of_device_id *match; |
286 | |||
287 | int ret; | 293 | int ret; |
288 | struct clk *clk; | ||
289 | 294 | ||
290 | pxa = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_pxa), GFP_KERNEL); | 295 | pxa = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_pxa), GFP_KERNEL); |
291 | if (!pxa) | 296 | if (!pxa) |
@@ -305,14 +310,20 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
305 | pltfm_host = sdhci_priv(host); | 310 | pltfm_host = sdhci_priv(host); |
306 | pltfm_host->priv = pxa; | 311 | pltfm_host->priv = pxa; |
307 | 312 | ||
308 | clk = devm_clk_get(dev, NULL); | 313 | pxa->clk_io = devm_clk_get(dev, "io"); |
309 | if (IS_ERR(clk)) { | 314 | if (IS_ERR(pxa->clk_io)) |
315 | pxa->clk_io = devm_clk_get(dev, NULL); | ||
316 | if (IS_ERR(pxa->clk_io)) { | ||
310 | dev_err(dev, "failed to get io clock\n"); | 317 | dev_err(dev, "failed to get io clock\n"); |
311 | ret = PTR_ERR(clk); | 318 | ret = PTR_ERR(pxa->clk_io); |
312 | goto err_clk_get; | 319 | goto err_clk_get; |
313 | } | 320 | } |
314 | pltfm_host->clk = clk; | 321 | pltfm_host->clk = pxa->clk_io; |
315 | clk_prepare_enable(clk); | 322 | clk_prepare_enable(pxa->clk_io); |
323 | |||
324 | pxa->clk_core = devm_clk_get(dev, "core"); | ||
325 | if (!IS_ERR(pxa->clk_core)) | ||
326 | clk_prepare_enable(pxa->clk_core); | ||
316 | 327 | ||
317 | /* enable 1/8V DDR capable */ | 328 | /* enable 1/8V DDR capable */ |
318 | host->mmc->caps |= MMC_CAP_1_8V_DDR; | 329 | host->mmc->caps |= MMC_CAP_1_8V_DDR; |
@@ -385,7 +396,9 @@ err_add_host: | |||
385 | pm_runtime_disable(&pdev->dev); | 396 | pm_runtime_disable(&pdev->dev); |
386 | err_of_parse: | 397 | err_of_parse: |
387 | err_cd_req: | 398 | err_cd_req: |
388 | clk_disable_unprepare(clk); | 399 | clk_disable_unprepare(pxa->clk_io); |
400 | if (!IS_ERR(pxa->clk_core)) | ||
401 | clk_disable_unprepare(pxa->clk_core); | ||
389 | err_clk_get: | 402 | err_clk_get: |
390 | err_mbus_win: | 403 | err_mbus_win: |
391 | sdhci_pltfm_free(pdev); | 404 | sdhci_pltfm_free(pdev); |
@@ -396,12 +409,15 @@ static int sdhci_pxav3_remove(struct platform_device *pdev) | |||
396 | { | 409 | { |
397 | struct sdhci_host *host = platform_get_drvdata(pdev); | 410 | struct sdhci_host *host = platform_get_drvdata(pdev); |
398 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 411 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
412 | struct sdhci_pxa *pxa = pltfm_host->priv; | ||
399 | 413 | ||
400 | pm_runtime_get_sync(&pdev->dev); | 414 | pm_runtime_get_sync(&pdev->dev); |
401 | sdhci_remove_host(host, 1); | 415 | sdhci_remove_host(host, 1); |
402 | pm_runtime_disable(&pdev->dev); | 416 | pm_runtime_disable(&pdev->dev); |
403 | 417 | ||
404 | clk_disable_unprepare(pltfm_host->clk); | 418 | clk_disable_unprepare(pxa->clk_io); |
419 | if (!IS_ERR(pxa->clk_core)) | ||
420 | clk_disable_unprepare(pxa->clk_core); | ||
405 | 421 | ||
406 | sdhci_pltfm_free(pdev); | 422 | sdhci_pltfm_free(pdev); |
407 | 423 | ||
@@ -441,15 +457,16 @@ static int sdhci_pxav3_runtime_suspend(struct device *dev) | |||
441 | { | 457 | { |
442 | struct sdhci_host *host = dev_get_drvdata(dev); | 458 | struct sdhci_host *host = dev_get_drvdata(dev); |
443 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 459 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
460 | struct sdhci_pxa *pxa = pltfm_host->priv; | ||
444 | unsigned long flags; | 461 | unsigned long flags; |
445 | 462 | ||
446 | if (pltfm_host->clk) { | 463 | spin_lock_irqsave(&host->lock, flags); |
447 | spin_lock_irqsave(&host->lock, flags); | 464 | host->runtime_suspended = true; |
448 | host->runtime_suspended = true; | 465 | spin_unlock_irqrestore(&host->lock, flags); |
449 | spin_unlock_irqrestore(&host->lock, flags); | ||
450 | 466 | ||
451 | clk_disable_unprepare(pltfm_host->clk); | 467 | clk_disable_unprepare(pxa->clk_io); |
452 | } | 468 | if (!IS_ERR(pxa->clk_core)) |
469 | clk_disable_unprepare(pxa->clk_core); | ||
453 | 470 | ||
454 | return 0; | 471 | return 0; |
455 | } | 472 | } |
@@ -458,15 +475,16 @@ static int sdhci_pxav3_runtime_resume(struct device *dev) | |||
458 | { | 475 | { |
459 | struct sdhci_host *host = dev_get_drvdata(dev); | 476 | struct sdhci_host *host = dev_get_drvdata(dev); |
460 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 477 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
478 | struct sdhci_pxa *pxa = pltfm_host->priv; | ||
461 | unsigned long flags; | 479 | unsigned long flags; |
462 | 480 | ||
463 | if (pltfm_host->clk) { | 481 | clk_prepare_enable(pxa->clk_io); |
464 | clk_prepare_enable(pltfm_host->clk); | 482 | if (!IS_ERR(pxa->clk_core)) |
483 | clk_prepare_enable(pxa->clk_core); | ||
465 | 484 | ||
466 | spin_lock_irqsave(&host->lock, flags); | 485 | spin_lock_irqsave(&host->lock, flags); |
467 | host->runtime_suspended = false; | 486 | host->runtime_suspended = false; |
468 | spin_unlock_irqrestore(&host->lock, flags); | 487 | spin_unlock_irqrestore(&host->lock, flags); |
469 | } | ||
470 | 488 | ||
471 | return 0; | 489 | return 0; |
472 | } | 490 | } |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 0ce6eb17deaf..4f7a63213b33 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -300,6 +300,7 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) | |||
300 | struct device *dev = &ourhost->pdev->dev; | 300 | struct device *dev = &ourhost->pdev->dev; |
301 | unsigned long timeout; | 301 | unsigned long timeout; |
302 | u16 clk = 0; | 302 | u16 clk = 0; |
303 | int ret; | ||
303 | 304 | ||
304 | host->mmc->actual_clock = 0; | 305 | host->mmc->actual_clock = 0; |
305 | 306 | ||
@@ -311,7 +312,12 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) | |||
311 | 312 | ||
312 | sdhci_s3c_set_clock(host, clock); | 313 | sdhci_s3c_set_clock(host, clock); |
313 | 314 | ||
314 | clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock); | 315 | ret = clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock); |
316 | if (ret != 0) { | ||
317 | dev_err(dev, "%s: failed to set clock rate %uHz\n", | ||
318 | mmc_hostname(host->mmc), clock); | ||
319 | return; | ||
320 | } | ||
315 | 321 | ||
316 | clk = SDHCI_CLOCK_INT_EN; | 322 | clk = SDHCI_CLOCK_INT_EN; |
317 | sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); | 323 | sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ada1a3ea3a87..73de62a58d70 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -44,8 +44,6 @@ | |||
44 | 44 | ||
45 | #define MAX_TUNING_LOOP 40 | 45 | #define MAX_TUNING_LOOP 40 |
46 | 46 | ||
47 | #define ADMA_SIZE ((128 * 2 + 1) * 4) | ||
48 | |||
49 | static unsigned int debug_quirks = 0; | 47 | static unsigned int debug_quirks = 0; |
50 | static unsigned int debug_quirks2; | 48 | static unsigned int debug_quirks2; |
51 | 49 | ||
@@ -119,10 +117,17 @@ static void sdhci_dumpregs(struct sdhci_host *host) | |||
119 | pr_debug(DRIVER_NAME ": Host ctl2: 0x%08x\n", | 117 | pr_debug(DRIVER_NAME ": Host ctl2: 0x%08x\n", |
120 | sdhci_readw(host, SDHCI_HOST_CONTROL2)); | 118 | sdhci_readw(host, SDHCI_HOST_CONTROL2)); |
121 | 119 | ||
122 | if (host->flags & SDHCI_USE_ADMA) | 120 | if (host->flags & SDHCI_USE_ADMA) { |
123 | pr_debug(DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n", | 121 | if (host->flags & SDHCI_USE_64_BIT_DMA) |
124 | readl(host->ioaddr + SDHCI_ADMA_ERROR), | 122 | pr_debug(DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x%08x\n", |
125 | readl(host->ioaddr + SDHCI_ADMA_ADDRESS)); | 123 | readl(host->ioaddr + SDHCI_ADMA_ERROR), |
124 | readl(host->ioaddr + SDHCI_ADMA_ADDRESS_HI), | ||
125 | readl(host->ioaddr + SDHCI_ADMA_ADDRESS)); | ||
126 | else | ||
127 | pr_debug(DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n", | ||
128 | readl(host->ioaddr + SDHCI_ADMA_ERROR), | ||
129 | readl(host->ioaddr + SDHCI_ADMA_ADDRESS)); | ||
130 | } | ||
126 | 131 | ||
127 | pr_debug(DRIVER_NAME ": ===========================================\n"); | 132 | pr_debug(DRIVER_NAME ": ===========================================\n"); |
128 | } | 133 | } |
@@ -448,18 +453,26 @@ static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) | |||
448 | local_irq_restore(*flags); | 453 | local_irq_restore(*flags); |
449 | } | 454 | } |
450 | 455 | ||
451 | static void sdhci_set_adma_desc(u8 *desc, u32 addr, int len, unsigned cmd) | 456 | static void sdhci_adma_write_desc(struct sdhci_host *host, void *desc, |
457 | dma_addr_t addr, int len, unsigned cmd) | ||
452 | { | 458 | { |
453 | __le32 *dataddr = (__le32 __force *)(desc + 4); | 459 | struct sdhci_adma2_64_desc *dma_desc = desc; |
454 | __le16 *cmdlen = (__le16 __force *)desc; | 460 | |
461 | /* 32-bit and 64-bit descriptors have these members in same position */ | ||
462 | dma_desc->cmd = cpu_to_le16(cmd); | ||
463 | dma_desc->len = cpu_to_le16(len); | ||
464 | dma_desc->addr_lo = cpu_to_le32((u32)addr); | ||
455 | 465 | ||
456 | /* SDHCI specification says ADMA descriptors should be 4 byte | 466 | if (host->flags & SDHCI_USE_64_BIT_DMA) |
457 | * aligned, so using 16 or 32bit operations should be safe. */ | 467 | dma_desc->addr_hi = cpu_to_le32((u64)addr >> 32); |
468 | } | ||
458 | 469 | ||
459 | cmdlen[0] = cpu_to_le16(cmd); | 470 | static void sdhci_adma_mark_end(void *desc) |
460 | cmdlen[1] = cpu_to_le16(len); | 471 | { |
472 | struct sdhci_adma2_64_desc *dma_desc = desc; | ||
461 | 473 | ||
462 | dataddr[0] = cpu_to_le32(addr); | 474 | /* 32-bit and 64-bit descriptors have 'cmd' in same position */ |
475 | dma_desc->cmd |= cpu_to_le16(ADMA2_END); | ||
463 | } | 476 | } |
464 | 477 | ||
465 | static int sdhci_adma_table_pre(struct sdhci_host *host, | 478 | static int sdhci_adma_table_pre(struct sdhci_host *host, |
@@ -467,8 +480,8 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
467 | { | 480 | { |
468 | int direction; | 481 | int direction; |
469 | 482 | ||
470 | u8 *desc; | 483 | void *desc; |
471 | u8 *align; | 484 | void *align; |
472 | dma_addr_t addr; | 485 | dma_addr_t addr; |
473 | dma_addr_t align_addr; | 486 | dma_addr_t align_addr; |
474 | int len, offset; | 487 | int len, offset; |
@@ -489,17 +502,17 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
489 | direction = DMA_TO_DEVICE; | 502 | direction = DMA_TO_DEVICE; |
490 | 503 | ||
491 | host->align_addr = dma_map_single(mmc_dev(host->mmc), | 504 | host->align_addr = dma_map_single(mmc_dev(host->mmc), |
492 | host->align_buffer, 128 * 4, direction); | 505 | host->align_buffer, host->align_buffer_sz, direction); |
493 | if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) | 506 | if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) |
494 | goto fail; | 507 | goto fail; |
495 | BUG_ON(host->align_addr & 0x3); | 508 | BUG_ON(host->align_addr & host->align_mask); |
496 | 509 | ||
497 | host->sg_count = dma_map_sg(mmc_dev(host->mmc), | 510 | host->sg_count = dma_map_sg(mmc_dev(host->mmc), |
498 | data->sg, data->sg_len, direction); | 511 | data->sg, data->sg_len, direction); |
499 | if (host->sg_count == 0) | 512 | if (host->sg_count == 0) |
500 | goto unmap_align; | 513 | goto unmap_align; |
501 | 514 | ||
502 | desc = host->adma_desc; | 515 | desc = host->adma_table; |
503 | align = host->align_buffer; | 516 | align = host->align_buffer; |
504 | 517 | ||
505 | align_addr = host->align_addr; | 518 | align_addr = host->align_addr; |
@@ -515,24 +528,27 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
515 | * the (up to three) bytes that screw up the | 528 | * the (up to three) bytes that screw up the |
516 | * alignment. | 529 | * alignment. |
517 | */ | 530 | */ |
518 | offset = (4 - (addr & 0x3)) & 0x3; | 531 | offset = (host->align_sz - (addr & host->align_mask)) & |
532 | host->align_mask; | ||
519 | if (offset) { | 533 | if (offset) { |
520 | if (data->flags & MMC_DATA_WRITE) { | 534 | if (data->flags & MMC_DATA_WRITE) { |
521 | buffer = sdhci_kmap_atomic(sg, &flags); | 535 | buffer = sdhci_kmap_atomic(sg, &flags); |
522 | WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3)); | 536 | WARN_ON(((long)buffer & (PAGE_SIZE - 1)) > |
537 | (PAGE_SIZE - offset)); | ||
523 | memcpy(align, buffer, offset); | 538 | memcpy(align, buffer, offset); |
524 | sdhci_kunmap_atomic(buffer, &flags); | 539 | sdhci_kunmap_atomic(buffer, &flags); |
525 | } | 540 | } |
526 | 541 | ||
527 | /* tran, valid */ | 542 | /* tran, valid */ |
528 | sdhci_set_adma_desc(desc, align_addr, offset, 0x21); | 543 | sdhci_adma_write_desc(host, desc, align_addr, offset, |
544 | ADMA2_TRAN_VALID); | ||
529 | 545 | ||
530 | BUG_ON(offset > 65536); | 546 | BUG_ON(offset > 65536); |
531 | 547 | ||
532 | align += 4; | 548 | align += host->align_sz; |
533 | align_addr += 4; | 549 | align_addr += host->align_sz; |
534 | 550 | ||
535 | desc += 8; | 551 | desc += host->desc_sz; |
536 | 552 | ||
537 | addr += offset; | 553 | addr += offset; |
538 | len -= offset; | 554 | len -= offset; |
@@ -541,23 +557,23 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
541 | BUG_ON(len > 65536); | 557 | BUG_ON(len > 65536); |
542 | 558 | ||
543 | /* tran, valid */ | 559 | /* tran, valid */ |
544 | sdhci_set_adma_desc(desc, addr, len, 0x21); | 560 | sdhci_adma_write_desc(host, desc, addr, len, ADMA2_TRAN_VALID); |
545 | desc += 8; | 561 | desc += host->desc_sz; |
546 | 562 | ||
547 | /* | 563 | /* |
548 | * If this triggers then we have a calculation bug | 564 | * If this triggers then we have a calculation bug |
549 | * somewhere. :/ | 565 | * somewhere. :/ |
550 | */ | 566 | */ |
551 | WARN_ON((desc - host->adma_desc) > ADMA_SIZE); | 567 | WARN_ON((desc - host->adma_table) >= host->adma_table_sz); |
552 | } | 568 | } |
553 | 569 | ||
554 | if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) { | 570 | if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) { |
555 | /* | 571 | /* |
556 | * Mark the last descriptor as the terminating descriptor | 572 | * Mark the last descriptor as the terminating descriptor |
557 | */ | 573 | */ |
558 | if (desc != host->adma_desc) { | 574 | if (desc != host->adma_table) { |
559 | desc -= 8; | 575 | desc -= host->desc_sz; |
560 | desc[0] |= 0x2; /* end */ | 576 | sdhci_adma_mark_end(desc); |
561 | } | 577 | } |
562 | } else { | 578 | } else { |
563 | /* | 579 | /* |
@@ -565,7 +581,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
565 | */ | 581 | */ |
566 | 582 | ||
567 | /* nop, end, valid */ | 583 | /* nop, end, valid */ |
568 | sdhci_set_adma_desc(desc, 0, 0, 0x3); | 584 | sdhci_adma_write_desc(host, desc, 0, 0, ADMA2_NOP_END_VALID); |
569 | } | 585 | } |
570 | 586 | ||
571 | /* | 587 | /* |
@@ -573,14 +589,14 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
573 | */ | 589 | */ |
574 | if (data->flags & MMC_DATA_WRITE) { | 590 | if (data->flags & MMC_DATA_WRITE) { |
575 | dma_sync_single_for_device(mmc_dev(host->mmc), | 591 | dma_sync_single_for_device(mmc_dev(host->mmc), |
576 | host->align_addr, 128 * 4, direction); | 592 | host->align_addr, host->align_buffer_sz, direction); |
577 | } | 593 | } |
578 | 594 | ||
579 | return 0; | 595 | return 0; |
580 | 596 | ||
581 | unmap_align: | 597 | unmap_align: |
582 | dma_unmap_single(mmc_dev(host->mmc), host->align_addr, | 598 | dma_unmap_single(mmc_dev(host->mmc), host->align_addr, |
583 | 128 * 4, direction); | 599 | host->align_buffer_sz, direction); |
584 | fail: | 600 | fail: |
585 | return -EINVAL; | 601 | return -EINVAL; |
586 | } | 602 | } |
@@ -592,7 +608,7 @@ static void sdhci_adma_table_post(struct sdhci_host *host, | |||
592 | 608 | ||
593 | struct scatterlist *sg; | 609 | struct scatterlist *sg; |
594 | int i, size; | 610 | int i, size; |
595 | u8 *align; | 611 | void *align; |
596 | char *buffer; | 612 | char *buffer; |
597 | unsigned long flags; | 613 | unsigned long flags; |
598 | bool has_unaligned; | 614 | bool has_unaligned; |
@@ -603,12 +619,12 @@ static void sdhci_adma_table_post(struct sdhci_host *host, | |||
603 | direction = DMA_TO_DEVICE; | 619 | direction = DMA_TO_DEVICE; |
604 | 620 | ||
605 | dma_unmap_single(mmc_dev(host->mmc), host->align_addr, | 621 | dma_unmap_single(mmc_dev(host->mmc), host->align_addr, |
606 | 128 * 4, direction); | 622 | host->align_buffer_sz, direction); |
607 | 623 | ||
608 | /* Do a quick scan of the SG list for any unaligned mappings */ | 624 | /* Do a quick scan of the SG list for any unaligned mappings */ |
609 | has_unaligned = false; | 625 | has_unaligned = false; |
610 | for_each_sg(data->sg, sg, host->sg_count, i) | 626 | for_each_sg(data->sg, sg, host->sg_count, i) |
611 | if (sg_dma_address(sg) & 3) { | 627 | if (sg_dma_address(sg) & host->align_mask) { |
612 | has_unaligned = true; | 628 | has_unaligned = true; |
613 | break; | 629 | break; |
614 | } | 630 | } |
@@ -620,15 +636,17 @@ static void sdhci_adma_table_post(struct sdhci_host *host, | |||
620 | align = host->align_buffer; | 636 | align = host->align_buffer; |
621 | 637 | ||
622 | for_each_sg(data->sg, sg, host->sg_count, i) { | 638 | for_each_sg(data->sg, sg, host->sg_count, i) { |
623 | if (sg_dma_address(sg) & 0x3) { | 639 | if (sg_dma_address(sg) & host->align_mask) { |
624 | size = 4 - (sg_dma_address(sg) & 0x3); | 640 | size = host->align_sz - |
641 | (sg_dma_address(sg) & host->align_mask); | ||
625 | 642 | ||
626 | buffer = sdhci_kmap_atomic(sg, &flags); | 643 | buffer = sdhci_kmap_atomic(sg, &flags); |
627 | WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3)); | 644 | WARN_ON(((long)buffer & (PAGE_SIZE - 1)) > |
645 | (PAGE_SIZE - size)); | ||
628 | memcpy(buffer, align, size); | 646 | memcpy(buffer, align, size); |
629 | sdhci_kunmap_atomic(buffer, &flags); | 647 | sdhci_kunmap_atomic(buffer, &flags); |
630 | 648 | ||
631 | align += 4; | 649 | align += host->align_sz; |
632 | } | 650 | } |
633 | } | 651 | } |
634 | } | 652 | } |
@@ -822,6 +840,10 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) | |||
822 | } else { | 840 | } else { |
823 | sdhci_writel(host, host->adma_addr, | 841 | sdhci_writel(host, host->adma_addr, |
824 | SDHCI_ADMA_ADDRESS); | 842 | SDHCI_ADMA_ADDRESS); |
843 | if (host->flags & SDHCI_USE_64_BIT_DMA) | ||
844 | sdhci_writel(host, | ||
845 | (u64)host->adma_addr >> 32, | ||
846 | SDHCI_ADMA_ADDRESS_HI); | ||
825 | } | 847 | } |
826 | } else { | 848 | } else { |
827 | int sg_cnt; | 849 | int sg_cnt; |
@@ -855,10 +877,14 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) | |||
855 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); | 877 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); |
856 | ctrl &= ~SDHCI_CTRL_DMA_MASK; | 878 | ctrl &= ~SDHCI_CTRL_DMA_MASK; |
857 | if ((host->flags & SDHCI_REQ_USE_DMA) && | 879 | if ((host->flags & SDHCI_REQ_USE_DMA) && |
858 | (host->flags & SDHCI_USE_ADMA)) | 880 | (host->flags & SDHCI_USE_ADMA)) { |
859 | ctrl |= SDHCI_CTRL_ADMA32; | 881 | if (host->flags & SDHCI_USE_64_BIT_DMA) |
860 | else | 882 | ctrl |= SDHCI_CTRL_ADMA64; |
883 | else | ||
884 | ctrl |= SDHCI_CTRL_ADMA32; | ||
885 | } else { | ||
861 | ctrl |= SDHCI_CTRL_SDMA; | 886 | ctrl |= SDHCI_CTRL_SDMA; |
887 | } | ||
862 | sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); | 888 | sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); |
863 | } | 889 | } |
864 | 890 | ||
@@ -889,10 +915,15 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, | |||
889 | struct mmc_data *data = cmd->data; | 915 | struct mmc_data *data = cmd->data; |
890 | 916 | ||
891 | if (data == NULL) { | 917 | if (data == NULL) { |
918 | if (host->quirks2 & | ||
919 | SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD) { | ||
920 | sdhci_writew(host, 0x0, SDHCI_TRANSFER_MODE); | ||
921 | } else { | ||
892 | /* clear Auto CMD settings for no data CMDs */ | 922 | /* clear Auto CMD settings for no data CMDs */ |
893 | mode = sdhci_readw(host, SDHCI_TRANSFER_MODE); | 923 | mode = sdhci_readw(host, SDHCI_TRANSFER_MODE); |
894 | sdhci_writew(host, mode & ~(SDHCI_TRNS_AUTO_CMD12 | | 924 | sdhci_writew(host, mode & ~(SDHCI_TRNS_AUTO_CMD12 | |
895 | SDHCI_TRNS_AUTO_CMD23), SDHCI_TRANSFER_MODE); | 925 | SDHCI_TRNS_AUTO_CMD23), SDHCI_TRANSFER_MODE); |
926 | } | ||
896 | return; | 927 | return; |
897 | } | 928 | } |
898 | 929 | ||
@@ -1117,6 +1148,9 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host) | |||
1117 | case MMC_TIMING_UHS_DDR50: | 1148 | case MMC_TIMING_UHS_DDR50: |
1118 | preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50); | 1149 | preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50); |
1119 | break; | 1150 | break; |
1151 | case MMC_TIMING_MMC_HS400: | ||
1152 | preset = sdhci_readw(host, SDHCI_PRESET_FOR_HS400); | ||
1153 | break; | ||
1120 | default: | 1154 | default: |
1121 | pr_warn("%s: Invalid UHS-I mode selected\n", | 1155 | pr_warn("%s: Invalid UHS-I mode selected\n", |
1122 | mmc_hostname(host->mmc)); | 1156 | mmc_hostname(host->mmc)); |
@@ -1444,6 +1478,8 @@ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing) | |||
1444 | else if ((timing == MMC_TIMING_UHS_DDR50) || | 1478 | else if ((timing == MMC_TIMING_UHS_DDR50) || |
1445 | (timing == MMC_TIMING_MMC_DDR52)) | 1479 | (timing == MMC_TIMING_MMC_DDR52)) |
1446 | ctrl_2 |= SDHCI_CTRL_UHS_DDR50; | 1480 | ctrl_2 |= SDHCI_CTRL_UHS_DDR50; |
1481 | else if (timing == MMC_TIMING_MMC_HS400) | ||
1482 | ctrl_2 |= SDHCI_CTRL_HS400; /* Non-standard */ | ||
1447 | sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); | 1483 | sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); |
1448 | } | 1484 | } |
1449 | EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling); | 1485 | EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling); |
@@ -1515,7 +1551,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | |||
1515 | u16 clk, ctrl_2; | 1551 | u16 clk, ctrl_2; |
1516 | 1552 | ||
1517 | /* In case of UHS-I modes, set High Speed Enable */ | 1553 | /* In case of UHS-I modes, set High Speed Enable */ |
1518 | if ((ios->timing == MMC_TIMING_MMC_HS200) || | 1554 | if ((ios->timing == MMC_TIMING_MMC_HS400) || |
1555 | (ios->timing == MMC_TIMING_MMC_HS200) || | ||
1519 | (ios->timing == MMC_TIMING_MMC_DDR52) || | 1556 | (ios->timing == MMC_TIMING_MMC_DDR52) || |
1520 | (ios->timing == MMC_TIMING_UHS_SDR50) || | 1557 | (ios->timing == MMC_TIMING_UHS_SDR50) || |
1521 | (ios->timing == MMC_TIMING_UHS_SDR104) || | 1558 | (ios->timing == MMC_TIMING_UHS_SDR104) || |
@@ -1862,6 +1899,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1862 | * tuning function has to be executed. | 1899 | * tuning function has to be executed. |
1863 | */ | 1900 | */ |
1864 | switch (host->timing) { | 1901 | switch (host->timing) { |
1902 | case MMC_TIMING_MMC_HS400: | ||
1865 | case MMC_TIMING_MMC_HS200: | 1903 | case MMC_TIMING_MMC_HS200: |
1866 | case MMC_TIMING_UHS_SDR104: | 1904 | case MMC_TIMING_UHS_SDR104: |
1867 | break; | 1905 | break; |
@@ -2144,9 +2182,10 @@ static void sdhci_tasklet_finish(unsigned long param) | |||
2144 | */ | 2182 | */ |
2145 | if (!(host->flags & SDHCI_DEVICE_DEAD) && | 2183 | if (!(host->flags & SDHCI_DEVICE_DEAD) && |
2146 | ((mrq->cmd && mrq->cmd->error) || | 2184 | ((mrq->cmd && mrq->cmd->error) || |
2147 | (mrq->data && (mrq->data->error || | 2185 | (mrq->sbc && mrq->sbc->error) || |
2148 | (mrq->data->stop && mrq->data->stop->error))) || | 2186 | (mrq->data && ((mrq->data->error && !mrq->data->stop) || |
2149 | (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) { | 2187 | (mrq->data->stop && mrq->data->stop->error))) || |
2188 | (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) { | ||
2150 | 2189 | ||
2151 | /* Some controllers need this kick or reset won't work here */ | 2190 | /* Some controllers need this kick or reset won't work here */ |
2152 | if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) | 2191 | if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) |
@@ -2282,32 +2321,36 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *mask) | |||
2282 | } | 2321 | } |
2283 | 2322 | ||
2284 | #ifdef CONFIG_MMC_DEBUG | 2323 | #ifdef CONFIG_MMC_DEBUG |
2285 | static void sdhci_show_adma_error(struct sdhci_host *host) | 2324 | static void sdhci_adma_show_error(struct sdhci_host *host) |
2286 | { | 2325 | { |
2287 | const char *name = mmc_hostname(host->mmc); | 2326 | const char *name = mmc_hostname(host->mmc); |
2288 | u8 *desc = host->adma_desc; | 2327 | void *desc = host->adma_table; |
2289 | __le32 *dma; | ||
2290 | __le16 *len; | ||
2291 | u8 attr; | ||
2292 | 2328 | ||
2293 | sdhci_dumpregs(host); | 2329 | sdhci_dumpregs(host); |
2294 | 2330 | ||
2295 | while (true) { | 2331 | while (true) { |
2296 | dma = (__le32 *)(desc + 4); | 2332 | struct sdhci_adma2_64_desc *dma_desc = desc; |
2297 | len = (__le16 *)(desc + 2); | 2333 | |
2298 | attr = *desc; | 2334 | if (host->flags & SDHCI_USE_64_BIT_DMA) |
2299 | 2335 | DBG("%s: %p: DMA 0x%08x%08x, LEN 0x%04x, Attr=0x%02x\n", | |
2300 | DBG("%s: %p: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n", | 2336 | name, desc, le32_to_cpu(dma_desc->addr_hi), |
2301 | name, desc, le32_to_cpu(*dma), le16_to_cpu(*len), attr); | 2337 | le32_to_cpu(dma_desc->addr_lo), |
2338 | le16_to_cpu(dma_desc->len), | ||
2339 | le16_to_cpu(dma_desc->cmd)); | ||
2340 | else | ||
2341 | DBG("%s: %p: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n", | ||
2342 | name, desc, le32_to_cpu(dma_desc->addr_lo), | ||
2343 | le16_to_cpu(dma_desc->len), | ||
2344 | le16_to_cpu(dma_desc->cmd)); | ||
2302 | 2345 | ||
2303 | desc += 8; | 2346 | desc += host->desc_sz; |
2304 | 2347 | ||
2305 | if (attr & 2) | 2348 | if (dma_desc->cmd & cpu_to_le16(ADMA2_END)) |
2306 | break; | 2349 | break; |
2307 | } | 2350 | } |
2308 | } | 2351 | } |
2309 | #else | 2352 | #else |
2310 | static void sdhci_show_adma_error(struct sdhci_host *host) { } | 2353 | static void sdhci_adma_show_error(struct sdhci_host *host) { } |
2311 | #endif | 2354 | #endif |
2312 | 2355 | ||
2313 | static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | 2356 | static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) |
@@ -2370,7 +2413,7 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
2370 | host->data->error = -EILSEQ; | 2413 | host->data->error = -EILSEQ; |
2371 | else if (intmask & SDHCI_INT_ADMA_ERROR) { | 2414 | else if (intmask & SDHCI_INT_ADMA_ERROR) { |
2372 | pr_err("%s: ADMA error\n", mmc_hostname(host->mmc)); | 2415 | pr_err("%s: ADMA error\n", mmc_hostname(host->mmc)); |
2373 | sdhci_show_adma_error(host); | 2416 | sdhci_adma_show_error(host); |
2374 | host->data->error = -EIO; | 2417 | host->data->error = -EIO; |
2375 | if (host->ops->adma_workaround) | 2418 | if (host->ops->adma_workaround) |
2376 | host->ops->adma_workaround(host, intmask); | 2419 | host->ops->adma_workaround(host, intmask); |
@@ -2849,6 +2892,16 @@ int sdhci_add_host(struct sdhci_host *host) | |||
2849 | host->flags &= ~SDHCI_USE_ADMA; | 2892 | host->flags &= ~SDHCI_USE_ADMA; |
2850 | } | 2893 | } |
2851 | 2894 | ||
2895 | /* | ||
2896 | * It is assumed that a 64-bit capable device has set a 64-bit DMA mask | ||
2897 | * and *must* do 64-bit DMA. A driver has the opportunity to change | ||
2898 | * that during the first call to ->enable_dma(). Similarly | ||
2899 | * SDHCI_QUIRK2_BROKEN_64_BIT_DMA must be left to the drivers to | ||
2900 | * implement. | ||
2901 | */ | ||
2902 | if (sdhci_readl(host, SDHCI_CAPABILITIES) & SDHCI_CAN_64BIT) | ||
2903 | host->flags |= SDHCI_USE_64_BIT_DMA; | ||
2904 | |||
2852 | if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { | 2905 | if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { |
2853 | if (host->ops->enable_dma) { | 2906 | if (host->ops->enable_dma) { |
2854 | if (host->ops->enable_dma(host)) { | 2907 | if (host->ops->enable_dma(host)) { |
@@ -2860,33 +2913,56 @@ int sdhci_add_host(struct sdhci_host *host) | |||
2860 | } | 2913 | } |
2861 | } | 2914 | } |
2862 | 2915 | ||
2916 | /* SDMA does not support 64-bit DMA */ | ||
2917 | if (host->flags & SDHCI_USE_64_BIT_DMA) | ||
2918 | host->flags &= ~SDHCI_USE_SDMA; | ||
2919 | |||
2863 | if (host->flags & SDHCI_USE_ADMA) { | 2920 | if (host->flags & SDHCI_USE_ADMA) { |
2864 | /* | 2921 | /* |
2865 | * We need to allocate descriptors for all sg entries | 2922 | * The DMA descriptor table size is calculated as the maximum |
2866 | * (128) and potentially one alignment transfer for | 2923 | * number of segments times 2, to allow for an alignment |
2867 | * each of those entries. | 2924 | * descriptor for each segment, plus 1 for a nop end descriptor, |
2925 | * all multipled by the descriptor size. | ||
2868 | */ | 2926 | */ |
2869 | host->adma_desc = dma_alloc_coherent(mmc_dev(mmc), | 2927 | if (host->flags & SDHCI_USE_64_BIT_DMA) { |
2870 | ADMA_SIZE, &host->adma_addr, | 2928 | host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * |
2871 | GFP_KERNEL); | 2929 | SDHCI_ADMA2_64_DESC_SZ; |
2872 | host->align_buffer = kmalloc(128 * 4, GFP_KERNEL); | 2930 | host->align_buffer_sz = SDHCI_MAX_SEGS * |
2873 | if (!host->adma_desc || !host->align_buffer) { | 2931 | SDHCI_ADMA2_64_ALIGN; |
2874 | dma_free_coherent(mmc_dev(mmc), ADMA_SIZE, | 2932 | host->desc_sz = SDHCI_ADMA2_64_DESC_SZ; |
2875 | host->adma_desc, host->adma_addr); | 2933 | host->align_sz = SDHCI_ADMA2_64_ALIGN; |
2934 | host->align_mask = SDHCI_ADMA2_64_ALIGN - 1; | ||
2935 | } else { | ||
2936 | host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * | ||
2937 | SDHCI_ADMA2_32_DESC_SZ; | ||
2938 | host->align_buffer_sz = SDHCI_MAX_SEGS * | ||
2939 | SDHCI_ADMA2_32_ALIGN; | ||
2940 | host->desc_sz = SDHCI_ADMA2_32_DESC_SZ; | ||
2941 | host->align_sz = SDHCI_ADMA2_32_ALIGN; | ||
2942 | host->align_mask = SDHCI_ADMA2_32_ALIGN - 1; | ||
2943 | } | ||
2944 | host->adma_table = dma_alloc_coherent(mmc_dev(mmc), | ||
2945 | host->adma_table_sz, | ||
2946 | &host->adma_addr, | ||
2947 | GFP_KERNEL); | ||
2948 | host->align_buffer = kmalloc(host->align_buffer_sz, GFP_KERNEL); | ||
2949 | if (!host->adma_table || !host->align_buffer) { | ||
2950 | dma_free_coherent(mmc_dev(mmc), host->adma_table_sz, | ||
2951 | host->adma_table, host->adma_addr); | ||
2876 | kfree(host->align_buffer); | 2952 | kfree(host->align_buffer); |
2877 | pr_warn("%s: Unable to allocate ADMA buffers - falling back to standard DMA\n", | 2953 | pr_warn("%s: Unable to allocate ADMA buffers - falling back to standard DMA\n", |
2878 | mmc_hostname(mmc)); | 2954 | mmc_hostname(mmc)); |
2879 | host->flags &= ~SDHCI_USE_ADMA; | 2955 | host->flags &= ~SDHCI_USE_ADMA; |
2880 | host->adma_desc = NULL; | 2956 | host->adma_table = NULL; |
2881 | host->align_buffer = NULL; | 2957 | host->align_buffer = NULL; |
2882 | } else if (host->adma_addr & 3) { | 2958 | } else if (host->adma_addr & host->align_mask) { |
2883 | pr_warn("%s: unable to allocate aligned ADMA descriptor\n", | 2959 | pr_warn("%s: unable to allocate aligned ADMA descriptor\n", |
2884 | mmc_hostname(mmc)); | 2960 | mmc_hostname(mmc)); |
2885 | host->flags &= ~SDHCI_USE_ADMA; | 2961 | host->flags &= ~SDHCI_USE_ADMA; |
2886 | dma_free_coherent(mmc_dev(mmc), ADMA_SIZE, | 2962 | dma_free_coherent(mmc_dev(mmc), host->adma_table_sz, |
2887 | host->adma_desc, host->adma_addr); | 2963 | host->adma_table, host->adma_addr); |
2888 | kfree(host->align_buffer); | 2964 | kfree(host->align_buffer); |
2889 | host->adma_desc = NULL; | 2965 | host->adma_table = NULL; |
2890 | host->align_buffer = NULL; | 2966 | host->align_buffer = NULL; |
2891 | } | 2967 | } |
2892 | } | 2968 | } |
@@ -3027,7 +3103,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3027 | if (ret) { | 3103 | if (ret) { |
3028 | pr_warn("%s: Failed to enable vqmmc regulator: %d\n", | 3104 | pr_warn("%s: Failed to enable vqmmc regulator: %d\n", |
3029 | mmc_hostname(mmc), ret); | 3105 | mmc_hostname(mmc), ret); |
3030 | mmc->supply.vqmmc = NULL; | 3106 | mmc->supply.vqmmc = ERR_PTR(-EINVAL); |
3031 | } | 3107 | } |
3032 | } | 3108 | } |
3033 | 3109 | ||
@@ -3046,16 +3122,21 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3046 | /* SD3.0: SDR104 is supported so (for eMMC) the caps2 | 3122 | /* SD3.0: SDR104 is supported so (for eMMC) the caps2 |
3047 | * field can be promoted to support HS200. | 3123 | * field can be promoted to support HS200. |
3048 | */ | 3124 | */ |
3049 | if (!(host->quirks2 & SDHCI_QUIRK2_BROKEN_HS200)) { | 3125 | if (!(host->quirks2 & SDHCI_QUIRK2_BROKEN_HS200)) |
3050 | mmc->caps2 |= MMC_CAP2_HS200; | 3126 | mmc->caps2 |= MMC_CAP2_HS200; |
3051 | if (IS_ERR(mmc->supply.vqmmc) || | ||
3052 | !regulator_is_supported_voltage | ||
3053 | (mmc->supply.vqmmc, 1100000, 1300000)) | ||
3054 | mmc->caps2 &= ~MMC_CAP2_HS200_1_2V_SDR; | ||
3055 | } | ||
3056 | } else if (caps[1] & SDHCI_SUPPORT_SDR50) | 3127 | } else if (caps[1] & SDHCI_SUPPORT_SDR50) |
3057 | mmc->caps |= MMC_CAP_UHS_SDR50; | 3128 | mmc->caps |= MMC_CAP_UHS_SDR50; |
3058 | 3129 | ||
3130 | if (host->quirks2 & SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 && | ||
3131 | (caps[1] & SDHCI_SUPPORT_HS400)) | ||
3132 | mmc->caps2 |= MMC_CAP2_HS400; | ||
3133 | |||
3134 | if ((mmc->caps2 & MMC_CAP2_HSX00_1_2V) && | ||
3135 | (IS_ERR(mmc->supply.vqmmc) || | ||
3136 | !regulator_is_supported_voltage(mmc->supply.vqmmc, 1100000, | ||
3137 | 1300000))) | ||
3138 | mmc->caps2 &= ~MMC_CAP2_HSX00_1_2V; | ||
3139 | |||
3059 | if ((caps[1] & SDHCI_SUPPORT_DDR50) && | 3140 | if ((caps[1] & SDHCI_SUPPORT_DDR50) && |
3060 | !(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50)) | 3141 | !(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50)) |
3061 | mmc->caps |= MMC_CAP_UHS_DDR50; | 3142 | mmc->caps |= MMC_CAP_UHS_DDR50; |
@@ -3175,11 +3256,11 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3175 | * can do scatter/gather or not. | 3256 | * can do scatter/gather or not. |
3176 | */ | 3257 | */ |
3177 | if (host->flags & SDHCI_USE_ADMA) | 3258 | if (host->flags & SDHCI_USE_ADMA) |
3178 | mmc->max_segs = 128; | 3259 | mmc->max_segs = SDHCI_MAX_SEGS; |
3179 | else if (host->flags & SDHCI_USE_SDMA) | 3260 | else if (host->flags & SDHCI_USE_SDMA) |
3180 | mmc->max_segs = 1; | 3261 | mmc->max_segs = 1; |
3181 | else /* PIO */ | 3262 | else /* PIO */ |
3182 | mmc->max_segs = 128; | 3263 | mmc->max_segs = SDHCI_MAX_SEGS; |
3183 | 3264 | ||
3184 | /* | 3265 | /* |
3185 | * Maximum number of sectors in one transfer. Limited by DMA boundary | 3266 | * Maximum number of sectors in one transfer. Limited by DMA boundary |
@@ -3277,7 +3358,8 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3277 | 3358 | ||
3278 | pr_info("%s: SDHCI controller on %s [%s] using %s\n", | 3359 | pr_info("%s: SDHCI controller on %s [%s] using %s\n", |
3279 | mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), | 3360 | mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), |
3280 | (host->flags & SDHCI_USE_ADMA) ? "ADMA" : | 3361 | (host->flags & SDHCI_USE_ADMA) ? |
3362 | (host->flags & SDHCI_USE_64_BIT_DMA) ? "ADMA 64-bit" : "ADMA" : | ||
3281 | (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"); | 3363 | (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"); |
3282 | 3364 | ||
3283 | sdhci_enable_card_detection(host); | 3365 | sdhci_enable_card_detection(host); |
@@ -3339,18 +3421,15 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) | |||
3339 | 3421 | ||
3340 | tasklet_kill(&host->finish_tasklet); | 3422 | tasklet_kill(&host->finish_tasklet); |
3341 | 3423 | ||
3342 | if (!IS_ERR(mmc->supply.vmmc)) | ||
3343 | regulator_disable(mmc->supply.vmmc); | ||
3344 | |||
3345 | if (!IS_ERR(mmc->supply.vqmmc)) | 3424 | if (!IS_ERR(mmc->supply.vqmmc)) |
3346 | regulator_disable(mmc->supply.vqmmc); | 3425 | regulator_disable(mmc->supply.vqmmc); |
3347 | 3426 | ||
3348 | if (host->adma_desc) | 3427 | if (host->adma_table) |
3349 | dma_free_coherent(mmc_dev(mmc), ADMA_SIZE, | 3428 | dma_free_coherent(mmc_dev(mmc), host->adma_table_sz, |
3350 | host->adma_desc, host->adma_addr); | 3429 | host->adma_table, host->adma_addr); |
3351 | kfree(host->align_buffer); | 3430 | kfree(host->align_buffer); |
3352 | 3431 | ||
3353 | host->adma_desc = NULL; | 3432 | host->adma_table = NULL; |
3354 | host->align_buffer = NULL; | 3433 | host->align_buffer = NULL; |
3355 | } | 3434 | } |
3356 | 3435 | ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 31896a779d4e..ddd31cda2370 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -161,7 +161,7 @@ | |||
161 | #define SDHCI_CTRL_UHS_SDR50 0x0002 | 161 | #define SDHCI_CTRL_UHS_SDR50 0x0002 |
162 | #define SDHCI_CTRL_UHS_SDR104 0x0003 | 162 | #define SDHCI_CTRL_UHS_SDR104 0x0003 |
163 | #define SDHCI_CTRL_UHS_DDR50 0x0004 | 163 | #define SDHCI_CTRL_UHS_DDR50 0x0004 |
164 | #define SDHCI_CTRL_HS_SDR200 0x0005 /* reserved value in SDIO spec */ | 164 | #define SDHCI_CTRL_HS400 0x0005 /* Non-standard */ |
165 | #define SDHCI_CTRL_VDD_180 0x0008 | 165 | #define SDHCI_CTRL_VDD_180 0x0008 |
166 | #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 | 166 | #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 |
167 | #define SDHCI_CTRL_DRV_TYPE_B 0x0000 | 167 | #define SDHCI_CTRL_DRV_TYPE_B 0x0000 |
@@ -204,6 +204,7 @@ | |||
204 | #define SDHCI_RETUNING_MODE_SHIFT 14 | 204 | #define SDHCI_RETUNING_MODE_SHIFT 14 |
205 | #define SDHCI_CLOCK_MUL_MASK 0x00FF0000 | 205 | #define SDHCI_CLOCK_MUL_MASK 0x00FF0000 |
206 | #define SDHCI_CLOCK_MUL_SHIFT 16 | 206 | #define SDHCI_CLOCK_MUL_SHIFT 16 |
207 | #define SDHCI_SUPPORT_HS400 0x80000000 /* Non-standard */ | ||
207 | 208 | ||
208 | #define SDHCI_CAPABILITIES_1 0x44 | 209 | #define SDHCI_CAPABILITIES_1 0x44 |
209 | 210 | ||
@@ -227,6 +228,7 @@ | |||
227 | /* 55-57 reserved */ | 228 | /* 55-57 reserved */ |
228 | 229 | ||
229 | #define SDHCI_ADMA_ADDRESS 0x58 | 230 | #define SDHCI_ADMA_ADDRESS 0x58 |
231 | #define SDHCI_ADMA_ADDRESS_HI 0x5C | ||
230 | 232 | ||
231 | /* 60-FB reserved */ | 233 | /* 60-FB reserved */ |
232 | 234 | ||
@@ -235,6 +237,7 @@ | |||
235 | #define SDHCI_PRESET_FOR_SDR50 0x6A | 237 | #define SDHCI_PRESET_FOR_SDR50 0x6A |
236 | #define SDHCI_PRESET_FOR_SDR104 0x6C | 238 | #define SDHCI_PRESET_FOR_SDR104 0x6C |
237 | #define SDHCI_PRESET_FOR_DDR50 0x6E | 239 | #define SDHCI_PRESET_FOR_DDR50 0x6E |
240 | #define SDHCI_PRESET_FOR_HS400 0x74 /* Non-standard */ | ||
238 | #define SDHCI_PRESET_DRV_MASK 0xC000 | 241 | #define SDHCI_PRESET_DRV_MASK 0xC000 |
239 | #define SDHCI_PRESET_DRV_SHIFT 14 | 242 | #define SDHCI_PRESET_DRV_SHIFT 14 |
240 | #define SDHCI_PRESET_CLKGEN_SEL_MASK 0x400 | 243 | #define SDHCI_PRESET_CLKGEN_SEL_MASK 0x400 |
@@ -266,6 +269,46 @@ | |||
266 | #define SDHCI_DEFAULT_BOUNDARY_SIZE (512 * 1024) | 269 | #define SDHCI_DEFAULT_BOUNDARY_SIZE (512 * 1024) |
267 | #define SDHCI_DEFAULT_BOUNDARY_ARG (ilog2(SDHCI_DEFAULT_BOUNDARY_SIZE) - 12) | 270 | #define SDHCI_DEFAULT_BOUNDARY_ARG (ilog2(SDHCI_DEFAULT_BOUNDARY_SIZE) - 12) |
268 | 271 | ||
272 | /* ADMA2 32-bit DMA descriptor size */ | ||
273 | #define SDHCI_ADMA2_32_DESC_SZ 8 | ||
274 | |||
275 | /* ADMA2 32-bit DMA alignment */ | ||
276 | #define SDHCI_ADMA2_32_ALIGN 4 | ||
277 | |||
278 | /* ADMA2 32-bit descriptor */ | ||
279 | struct sdhci_adma2_32_desc { | ||
280 | __le16 cmd; | ||
281 | __le16 len; | ||
282 | __le32 addr; | ||
283 | } __packed __aligned(SDHCI_ADMA2_32_ALIGN); | ||
284 | |||
285 | /* ADMA2 64-bit DMA descriptor size */ | ||
286 | #define SDHCI_ADMA2_64_DESC_SZ 12 | ||
287 | |||
288 | /* ADMA2 64-bit DMA alignment */ | ||
289 | #define SDHCI_ADMA2_64_ALIGN 8 | ||
290 | |||
291 | /* | ||
292 | * ADMA2 64-bit descriptor. Note 12-byte descriptor can't always be 8-byte | ||
293 | * aligned. | ||
294 | */ | ||
295 | struct sdhci_adma2_64_desc { | ||
296 | __le16 cmd; | ||
297 | __le16 len; | ||
298 | __le32 addr_lo; | ||
299 | __le32 addr_hi; | ||
300 | } __packed __aligned(4); | ||
301 | |||
302 | #define ADMA2_TRAN_VALID 0x21 | ||
303 | #define ADMA2_NOP_END_VALID 0x3 | ||
304 | #define ADMA2_END 0x2 | ||
305 | |||
306 | /* | ||
307 | * Maximum segments assuming a 512KiB maximum requisition size and a minimum | ||
308 | * 4KiB page size. | ||
309 | */ | ||
310 | #define SDHCI_MAX_SEGS 128 | ||
311 | |||
269 | struct sdhci_ops { | 312 | struct sdhci_ops { |
270 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS | 313 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS |
271 | u32 (*read_l)(struct sdhci_host *host, int reg); | 314 | u32 (*read_l)(struct sdhci_host *host, int reg); |
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index d1663b3c4143..15cb8b7ffc34 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/err.h> | 21 | #include <linux/err.h> |
22 | 22 | ||
23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
24 | #include <linux/clk-private.h> | ||
25 | #include <linux/clk/sunxi.h> | 24 | #include <linux/clk/sunxi.h> |
26 | 25 | ||
27 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
diff --git a/drivers/mmc/host/toshsd.c b/drivers/mmc/host/toshsd.c new file mode 100644 index 000000000000..4666262edaca --- /dev/null +++ b/drivers/mmc/host/toshsd.c | |||
@@ -0,0 +1,717 @@ | |||
1 | /* | ||
2 | * Toshiba PCI Secure Digital Host Controller Interface driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Ondrej Zary | ||
5 | * Copyright (C) 2007 Richard Betts, All Rights Reserved. | ||
6 | * | ||
7 | * Based on asic3_mmc.c, copyright (c) 2005 SDG Systems, LLC and, | ||
8 | * sdhci.c, copyright (C) 2005-2006 Pierre Ossman | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or (at | ||
13 | * your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/delay.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <linux/scatterlist.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/pm.h> | ||
24 | #include <linux/mmc/host.h> | ||
25 | #include <linux/mmc/mmc.h> | ||
26 | |||
27 | #include "toshsd.h" | ||
28 | |||
29 | #define DRIVER_NAME "toshsd" | ||
30 | |||
31 | static const struct pci_device_id pci_ids[] = { | ||
32 | { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA, 0x0805) }, | ||
33 | { /* end: all zeroes */ }, | ||
34 | }; | ||
35 | |||
36 | MODULE_DEVICE_TABLE(pci, pci_ids); | ||
37 | |||
38 | static void toshsd_init(struct toshsd_host *host) | ||
39 | { | ||
40 | /* enable clock */ | ||
41 | pci_write_config_byte(host->pdev, SD_PCICFG_CLKSTOP, | ||
42 | SD_PCICFG_CLKSTOP_ENABLE_ALL); | ||
43 | pci_write_config_byte(host->pdev, SD_PCICFG_CARDDETECT, 2); | ||
44 | |||
45 | /* reset */ | ||
46 | iowrite16(0, host->ioaddr + SD_SOFTWARERESET); /* assert */ | ||
47 | mdelay(2); | ||
48 | iowrite16(1, host->ioaddr + SD_SOFTWARERESET); /* deassert */ | ||
49 | mdelay(2); | ||
50 | |||
51 | /* Clear card registers */ | ||
52 | iowrite16(0, host->ioaddr + SD_CARDCLOCKCTRL); | ||
53 | iowrite32(0, host->ioaddr + SD_CARDSTATUS); | ||
54 | iowrite32(0, host->ioaddr + SD_ERRORSTATUS0); | ||
55 | iowrite16(0, host->ioaddr + SD_STOPINTERNAL); | ||
56 | |||
57 | /* SDIO clock? */ | ||
58 | iowrite16(0x100, host->ioaddr + SDIO_BASE + SDIO_CLOCKNWAITCTRL); | ||
59 | |||
60 | /* enable LED */ | ||
61 | pci_write_config_byte(host->pdev, SD_PCICFG_SDLED_ENABLE1, | ||
62 | SD_PCICFG_LED_ENABLE1_START); | ||
63 | pci_write_config_byte(host->pdev, SD_PCICFG_SDLED_ENABLE2, | ||
64 | SD_PCICFG_LED_ENABLE2_START); | ||
65 | |||
66 | /* set interrupt masks */ | ||
67 | iowrite32(~(u32)(SD_CARD_RESP_END | SD_CARD_RW_END | ||
68 | | SD_CARD_CARD_REMOVED_0 | SD_CARD_CARD_INSERTED_0 | ||
69 | | SD_BUF_READ_ENABLE | SD_BUF_WRITE_ENABLE | ||
70 | | SD_BUF_CMD_TIMEOUT), | ||
71 | host->ioaddr + SD_INTMASKCARD); | ||
72 | |||
73 | iowrite16(0x1000, host->ioaddr + SD_TRANSACTIONCTRL); | ||
74 | } | ||
75 | |||
76 | /* Set MMC clock / power. | ||
77 | * Note: This controller uses a simple divider scheme therefore it cannot run | ||
78 | * SD/MMC cards at full speed (24/20MHz). HCLK (=33MHz PCI clock?) is too high | ||
79 | * and the next slowest is 16MHz (div=2). | ||
80 | */ | ||
81 | static void __toshsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
82 | { | ||
83 | struct toshsd_host *host = mmc_priv(mmc); | ||
84 | |||
85 | if (ios->clock) { | ||
86 | u16 clk; | ||
87 | int div = 1; | ||
88 | |||
89 | while (ios->clock < HCLK / div) | ||
90 | div *= 2; | ||
91 | |||
92 | clk = div >> 2; | ||
93 | |||
94 | if (div == 1) { /* disable the divider */ | ||
95 | pci_write_config_byte(host->pdev, SD_PCICFG_CLKMODE, | ||
96 | SD_PCICFG_CLKMODE_DIV_DISABLE); | ||
97 | clk |= SD_CARDCLK_DIV_DISABLE; | ||
98 | } else | ||
99 | pci_write_config_byte(host->pdev, SD_PCICFG_CLKMODE, 0); | ||
100 | |||
101 | clk |= SD_CARDCLK_ENABLE_CLOCK; | ||
102 | iowrite16(clk, host->ioaddr + SD_CARDCLOCKCTRL); | ||
103 | |||
104 | mdelay(10); | ||
105 | } else | ||
106 | iowrite16(0, host->ioaddr + SD_CARDCLOCKCTRL); | ||
107 | |||
108 | switch (ios->power_mode) { | ||
109 | case MMC_POWER_OFF: | ||
110 | pci_write_config_byte(host->pdev, SD_PCICFG_POWER1, | ||
111 | SD_PCICFG_PWR1_OFF); | ||
112 | mdelay(1); | ||
113 | break; | ||
114 | case MMC_POWER_UP: | ||
115 | break; | ||
116 | case MMC_POWER_ON: | ||
117 | pci_write_config_byte(host->pdev, SD_PCICFG_POWER1, | ||
118 | SD_PCICFG_PWR1_33V); | ||
119 | pci_write_config_byte(host->pdev, SD_PCICFG_POWER2, | ||
120 | SD_PCICFG_PWR2_AUTO); | ||
121 | mdelay(20); | ||
122 | break; | ||
123 | } | ||
124 | |||
125 | switch (ios->bus_width) { | ||
126 | case MMC_BUS_WIDTH_1: | ||
127 | iowrite16(SD_CARDOPT_REQUIRED | SD_CARDOPT_DATA_RESP_TIMEOUT(14) | ||
128 | | SD_CARDOPT_C2_MODULE_ABSENT | ||
129 | | SD_CARDOPT_DATA_XFR_WIDTH_1, | ||
130 | host->ioaddr + SD_CARDOPTIONSETUP); | ||
131 | break; | ||
132 | case MMC_BUS_WIDTH_4: | ||
133 | iowrite16(SD_CARDOPT_REQUIRED | SD_CARDOPT_DATA_RESP_TIMEOUT(14) | ||
134 | | SD_CARDOPT_C2_MODULE_ABSENT | ||
135 | | SD_CARDOPT_DATA_XFR_WIDTH_4, | ||
136 | host->ioaddr + SD_CARDOPTIONSETUP); | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | static void toshsd_set_led(struct toshsd_host *host, unsigned char state) | ||
142 | { | ||
143 | iowrite16(state, host->ioaddr + SDIO_BASE + SDIO_LEDCTRL); | ||
144 | } | ||
145 | |||
146 | static void toshsd_finish_request(struct toshsd_host *host) | ||
147 | { | ||
148 | struct mmc_request *mrq = host->mrq; | ||
149 | |||
150 | /* Write something to end the command */ | ||
151 | host->mrq = NULL; | ||
152 | host->cmd = NULL; | ||
153 | host->data = NULL; | ||
154 | |||
155 | toshsd_set_led(host, 0); | ||
156 | mmc_request_done(host->mmc, mrq); | ||
157 | } | ||
158 | |||
159 | static irqreturn_t toshsd_thread_irq(int irq, void *dev_id) | ||
160 | { | ||
161 | struct toshsd_host *host = dev_id; | ||
162 | struct mmc_data *data = host->data; | ||
163 | struct sg_mapping_iter *sg_miter = &host->sg_miter; | ||
164 | unsigned short *buf; | ||
165 | int count; | ||
166 | unsigned long flags; | ||
167 | |||
168 | if (!data) { | ||
169 | dev_warn(&host->pdev->dev, "Spurious Data IRQ\n"); | ||
170 | if (host->cmd) { | ||
171 | host->cmd->error = -EIO; | ||
172 | toshsd_finish_request(host); | ||
173 | } | ||
174 | return IRQ_NONE; | ||
175 | } | ||
176 | spin_lock_irqsave(&host->lock, flags); | ||
177 | |||
178 | if (!sg_miter_next(sg_miter)) | ||
179 | return IRQ_HANDLED; | ||
180 | buf = sg_miter->addr; | ||
181 | |||
182 | /* Ensure we dont read more than one block. The chip will interrupt us | ||
183 | * When the next block is available. | ||
184 | */ | ||
185 | count = sg_miter->length; | ||
186 | if (count > data->blksz) | ||
187 | count = data->blksz; | ||
188 | |||
189 | dev_dbg(&host->pdev->dev, "count: %08x, flags %08x\n", count, | ||
190 | data->flags); | ||
191 | |||
192 | /* Transfer the data */ | ||
193 | if (data->flags & MMC_DATA_READ) | ||
194 | ioread32_rep(host->ioaddr + SD_DATAPORT, buf, count >> 2); | ||
195 | else | ||
196 | iowrite32_rep(host->ioaddr + SD_DATAPORT, buf, count >> 2); | ||
197 | |||
198 | sg_miter->consumed = count; | ||
199 | sg_miter_stop(sg_miter); | ||
200 | |||
201 | spin_unlock_irqrestore(&host->lock, flags); | ||
202 | |||
203 | return IRQ_HANDLED; | ||
204 | } | ||
205 | |||
206 | static void toshsd_cmd_irq(struct toshsd_host *host) | ||
207 | { | ||
208 | struct mmc_command *cmd = host->cmd; | ||
209 | u8 *buf; | ||
210 | u16 data; | ||
211 | |||
212 | if (!host->cmd) { | ||
213 | dev_warn(&host->pdev->dev, "Spurious CMD irq\n"); | ||
214 | return; | ||
215 | } | ||
216 | buf = (u8 *)cmd->resp; | ||
217 | host->cmd = NULL; | ||
218 | |||
219 | if (cmd->flags & MMC_RSP_PRESENT && cmd->flags & MMC_RSP_136) { | ||
220 | /* R2 */ | ||
221 | buf[12] = 0xff; | ||
222 | data = ioread16(host->ioaddr + SD_RESPONSE0); | ||
223 | buf[13] = data & 0xff; | ||
224 | buf[14] = data >> 8; | ||
225 | data = ioread16(host->ioaddr + SD_RESPONSE1); | ||
226 | buf[15] = data & 0xff; | ||
227 | buf[8] = data >> 8; | ||
228 | data = ioread16(host->ioaddr + SD_RESPONSE2); | ||
229 | buf[9] = data & 0xff; | ||
230 | buf[10] = data >> 8; | ||
231 | data = ioread16(host->ioaddr + SD_RESPONSE3); | ||
232 | buf[11] = data & 0xff; | ||
233 | buf[4] = data >> 8; | ||
234 | data = ioread16(host->ioaddr + SD_RESPONSE4); | ||
235 | buf[5] = data & 0xff; | ||
236 | buf[6] = data >> 8; | ||
237 | data = ioread16(host->ioaddr + SD_RESPONSE5); | ||
238 | buf[7] = data & 0xff; | ||
239 | buf[0] = data >> 8; | ||
240 | data = ioread16(host->ioaddr + SD_RESPONSE6); | ||
241 | buf[1] = data & 0xff; | ||
242 | buf[2] = data >> 8; | ||
243 | data = ioread16(host->ioaddr + SD_RESPONSE7); | ||
244 | buf[3] = data & 0xff; | ||
245 | } else if (cmd->flags & MMC_RSP_PRESENT) { | ||
246 | /* R1, R1B, R3, R6, R7 */ | ||
247 | data = ioread16(host->ioaddr + SD_RESPONSE0); | ||
248 | buf[0] = data & 0xff; | ||
249 | buf[1] = data >> 8; | ||
250 | data = ioread16(host->ioaddr + SD_RESPONSE1); | ||
251 | buf[2] = data & 0xff; | ||
252 | buf[3] = data >> 8; | ||
253 | } | ||
254 | |||
255 | dev_dbg(&host->pdev->dev, "Command IRQ complete %d %d %x\n", | ||
256 | cmd->opcode, cmd->error, cmd->flags); | ||
257 | |||
258 | /* If there is data to handle we will | ||
259 | * finish the request in the mmc_data_end_irq handler.*/ | ||
260 | if (host->data) | ||
261 | return; | ||
262 | |||
263 | toshsd_finish_request(host); | ||
264 | } | ||
265 | |||
266 | static void toshsd_data_end_irq(struct toshsd_host *host) | ||
267 | { | ||
268 | struct mmc_data *data = host->data; | ||
269 | |||
270 | host->data = NULL; | ||
271 | |||
272 | if (!data) { | ||
273 | dev_warn(&host->pdev->dev, "Spurious data end IRQ\n"); | ||
274 | return; | ||
275 | } | ||
276 | |||
277 | if (data->error == 0) | ||
278 | data->bytes_xfered = data->blocks * data->blksz; | ||
279 | else | ||
280 | data->bytes_xfered = 0; | ||
281 | |||
282 | dev_dbg(&host->pdev->dev, "Completed data request xfr=%d\n", | ||
283 | data->bytes_xfered); | ||
284 | |||
285 | iowrite16(0, host->ioaddr + SD_STOPINTERNAL); | ||
286 | |||
287 | toshsd_finish_request(host); | ||
288 | } | ||
289 | |||
290 | static irqreturn_t toshsd_irq(int irq, void *dev_id) | ||
291 | { | ||
292 | struct toshsd_host *host = dev_id; | ||
293 | u32 int_reg, int_mask, int_status, detail; | ||
294 | int error = 0, ret = IRQ_HANDLED; | ||
295 | |||
296 | spin_lock(&host->lock); | ||
297 | int_status = ioread32(host->ioaddr + SD_CARDSTATUS); | ||
298 | int_mask = ioread32(host->ioaddr + SD_INTMASKCARD); | ||
299 | int_reg = int_status & ~int_mask & ~IRQ_DONT_CARE_BITS; | ||
300 | |||
301 | dev_dbg(&host->pdev->dev, "IRQ status:%x mask:%x\n", | ||
302 | int_status, int_mask); | ||
303 | |||
304 | /* nothing to do: it's not our IRQ */ | ||
305 | if (!int_reg) { | ||
306 | ret = IRQ_NONE; | ||
307 | goto irq_end; | ||
308 | } | ||
309 | |||
310 | if (int_reg & SD_BUF_CMD_TIMEOUT) { | ||
311 | error = -ETIMEDOUT; | ||
312 | dev_dbg(&host->pdev->dev, "Timeout\n"); | ||
313 | } else if (int_reg & SD_BUF_CRC_ERR) { | ||
314 | error = -EILSEQ; | ||
315 | dev_err(&host->pdev->dev, "BadCRC\n"); | ||
316 | } else if (int_reg & (SD_BUF_ILLEGAL_ACCESS | ||
317 | | SD_BUF_CMD_INDEX_ERR | ||
318 | | SD_BUF_STOP_BIT_END_ERR | ||
319 | | SD_BUF_OVERFLOW | ||
320 | | SD_BUF_UNDERFLOW | ||
321 | | SD_BUF_DATA_TIMEOUT)) { | ||
322 | dev_err(&host->pdev->dev, "Buffer status error: { %s%s%s%s%s%s}\n", | ||
323 | int_reg & SD_BUF_ILLEGAL_ACCESS ? "ILLEGAL_ACC " : "", | ||
324 | int_reg & SD_BUF_CMD_INDEX_ERR ? "CMD_INDEX " : "", | ||
325 | int_reg & SD_BUF_STOP_BIT_END_ERR ? "STOPBIT_END " : "", | ||
326 | int_reg & SD_BUF_OVERFLOW ? "OVERFLOW " : "", | ||
327 | int_reg & SD_BUF_UNDERFLOW ? "UNDERFLOW " : "", | ||
328 | int_reg & SD_BUF_DATA_TIMEOUT ? "DATA_TIMEOUT " : ""); | ||
329 | |||
330 | detail = ioread32(host->ioaddr + SD_ERRORSTATUS0); | ||
331 | dev_err(&host->pdev->dev, "detail error status { %s%s%s%s%s%s%s%s%s%s%s%s%s}\n", | ||
332 | detail & SD_ERR0_RESP_CMD_ERR ? "RESP_CMD " : "", | ||
333 | detail & SD_ERR0_RESP_NON_CMD12_END_BIT_ERR ? "RESP_END_BIT " : "", | ||
334 | detail & SD_ERR0_RESP_CMD12_END_BIT_ERR ? "RESP_END_BIT " : "", | ||
335 | detail & SD_ERR0_READ_DATA_END_BIT_ERR ? "READ_DATA_END_BIT " : "", | ||
336 | detail & SD_ERR0_WRITE_CRC_STATUS_END_BIT_ERR ? "WRITE_CMD_END_BIT " : "", | ||
337 | detail & SD_ERR0_RESP_NON_CMD12_CRC_ERR ? "RESP_CRC " : "", | ||
338 | detail & SD_ERR0_RESP_CMD12_CRC_ERR ? "RESP_CRC " : "", | ||
339 | detail & SD_ERR0_READ_DATA_CRC_ERR ? "READ_DATA_CRC " : "", | ||
340 | detail & SD_ERR0_WRITE_CMD_CRC_ERR ? "WRITE_CMD_CRC " : "", | ||
341 | detail & SD_ERR1_NO_CMD_RESP ? "NO_CMD_RESP " : "", | ||
342 | detail & SD_ERR1_TIMEOUT_READ_DATA ? "READ_DATA_TIMEOUT " : "", | ||
343 | detail & SD_ERR1_TIMEOUT_CRS_STATUS ? "CRS_STATUS_TIMEOUT " : "", | ||
344 | detail & SD_ERR1_TIMEOUT_CRC_BUSY ? "CRC_BUSY_TIMEOUT " : ""); | ||
345 | error = -EIO; | ||
346 | } | ||
347 | |||
348 | if (error) { | ||
349 | if (host->cmd) | ||
350 | host->cmd->error = error; | ||
351 | |||
352 | if (error == -ETIMEDOUT) { | ||
353 | iowrite32(int_status & | ||
354 | ~(SD_BUF_CMD_TIMEOUT | SD_CARD_RESP_END), | ||
355 | host->ioaddr + SD_CARDSTATUS); | ||
356 | } else { | ||
357 | toshsd_init(host); | ||
358 | __toshsd_set_ios(host->mmc, &host->mmc->ios); | ||
359 | goto irq_end; | ||
360 | } | ||
361 | } | ||
362 | |||
363 | /* Card insert/remove. The mmc controlling code is stateless. */ | ||
364 | if (int_reg & (SD_CARD_CARD_INSERTED_0 | SD_CARD_CARD_REMOVED_0)) { | ||
365 | iowrite32(int_status & | ||
366 | ~(SD_CARD_CARD_REMOVED_0 | SD_CARD_CARD_INSERTED_0), | ||
367 | host->ioaddr + SD_CARDSTATUS); | ||
368 | |||
369 | if (int_reg & SD_CARD_CARD_INSERTED_0) | ||
370 | toshsd_init(host); | ||
371 | |||
372 | mmc_detect_change(host->mmc, 1); | ||
373 | } | ||
374 | |||
375 | /* Data transfer */ | ||
376 | if (int_reg & (SD_BUF_READ_ENABLE | SD_BUF_WRITE_ENABLE)) { | ||
377 | iowrite32(int_status & | ||
378 | ~(SD_BUF_WRITE_ENABLE | SD_BUF_READ_ENABLE), | ||
379 | host->ioaddr + SD_CARDSTATUS); | ||
380 | |||
381 | ret = IRQ_WAKE_THREAD; | ||
382 | goto irq_end; | ||
383 | } | ||
384 | |||
385 | /* Command completion */ | ||
386 | if (int_reg & SD_CARD_RESP_END) { | ||
387 | iowrite32(int_status & ~(SD_CARD_RESP_END), | ||
388 | host->ioaddr + SD_CARDSTATUS); | ||
389 | toshsd_cmd_irq(host); | ||
390 | } | ||
391 | |||
392 | /* Data transfer completion */ | ||
393 | if (int_reg & SD_CARD_RW_END) { | ||
394 | iowrite32(int_status & ~(SD_CARD_RW_END), | ||
395 | host->ioaddr + SD_CARDSTATUS); | ||
396 | toshsd_data_end_irq(host); | ||
397 | } | ||
398 | irq_end: | ||
399 | spin_unlock(&host->lock); | ||
400 | return ret; | ||
401 | } | ||
402 | |||
403 | static void toshsd_start_cmd(struct toshsd_host *host, struct mmc_command *cmd) | ||
404 | { | ||
405 | struct mmc_data *data = host->data; | ||
406 | int c = cmd->opcode; | ||
407 | |||
408 | dev_dbg(&host->pdev->dev, "Command opcode: %d\n", cmd->opcode); | ||
409 | |||
410 | if (cmd->opcode == MMC_STOP_TRANSMISSION) { | ||
411 | iowrite16(SD_STOPINT_ISSUE_CMD12, | ||
412 | host->ioaddr + SD_STOPINTERNAL); | ||
413 | |||
414 | cmd->resp[0] = cmd->opcode; | ||
415 | cmd->resp[1] = 0; | ||
416 | cmd->resp[2] = 0; | ||
417 | cmd->resp[3] = 0; | ||
418 | |||
419 | toshsd_finish_request(host); | ||
420 | return; | ||
421 | } | ||
422 | |||
423 | switch (mmc_resp_type(cmd)) { | ||
424 | case MMC_RSP_NONE: | ||
425 | c |= SD_CMD_RESP_TYPE_NONE; | ||
426 | break; | ||
427 | |||
428 | case MMC_RSP_R1: | ||
429 | c |= SD_CMD_RESP_TYPE_EXT_R1; | ||
430 | break; | ||
431 | case MMC_RSP_R1B: | ||
432 | c |= SD_CMD_RESP_TYPE_EXT_R1B; | ||
433 | break; | ||
434 | case MMC_RSP_R2: | ||
435 | c |= SD_CMD_RESP_TYPE_EXT_R2; | ||
436 | break; | ||
437 | case MMC_RSP_R3: | ||
438 | c |= SD_CMD_RESP_TYPE_EXT_R3; | ||
439 | break; | ||
440 | |||
441 | default: | ||
442 | dev_err(&host->pdev->dev, "Unknown response type %d\n", | ||
443 | mmc_resp_type(cmd)); | ||
444 | break; | ||
445 | } | ||
446 | |||
447 | host->cmd = cmd; | ||
448 | |||
449 | if (cmd->opcode == MMC_APP_CMD) | ||
450 | c |= SD_CMD_TYPE_ACMD; | ||
451 | |||
452 | if (cmd->opcode == MMC_GO_IDLE_STATE) | ||
453 | c |= (3 << 8); /* removed from ipaq-asic3.h for some reason */ | ||
454 | |||
455 | if (data) { | ||
456 | c |= SD_CMD_DATA_PRESENT; | ||
457 | |||
458 | if (data->blocks > 1) { | ||
459 | iowrite16(SD_STOPINT_AUTO_ISSUE_CMD12, | ||
460 | host->ioaddr + SD_STOPINTERNAL); | ||
461 | c |= SD_CMD_MULTI_BLOCK; | ||
462 | } | ||
463 | |||
464 | if (data->flags & MMC_DATA_READ) | ||
465 | c |= SD_CMD_TRANSFER_READ; | ||
466 | |||
467 | /* MMC_DATA_WRITE does not require a bit to be set */ | ||
468 | } | ||
469 | |||
470 | /* Send the command */ | ||
471 | iowrite32(cmd->arg, host->ioaddr + SD_ARG0); | ||
472 | iowrite16(c, host->ioaddr + SD_CMD); | ||
473 | } | ||
474 | |||
475 | static void toshsd_start_data(struct toshsd_host *host, struct mmc_data *data) | ||
476 | { | ||
477 | unsigned int flags = SG_MITER_ATOMIC; | ||
478 | |||
479 | dev_dbg(&host->pdev->dev, "setup data transfer: blocksize %08x nr_blocks %d, offset: %08x\n", | ||
480 | data->blksz, data->blocks, data->sg->offset); | ||
481 | |||
482 | host->data = data; | ||
483 | |||
484 | if (data->flags & MMC_DATA_READ) | ||
485 | flags |= SG_MITER_TO_SG; | ||
486 | else | ||
487 | flags |= SG_MITER_FROM_SG; | ||
488 | |||
489 | sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); | ||
490 | |||
491 | /* Set transfer length and blocksize */ | ||
492 | iowrite16(data->blocks, host->ioaddr + SD_BLOCKCOUNT); | ||
493 | iowrite16(data->blksz, host->ioaddr + SD_CARDXFERDATALEN); | ||
494 | } | ||
495 | |||
496 | /* Process requests from the MMC layer */ | ||
497 | static void toshsd_request(struct mmc_host *mmc, struct mmc_request *mrq) | ||
498 | { | ||
499 | struct toshsd_host *host = mmc_priv(mmc); | ||
500 | unsigned long flags; | ||
501 | |||
502 | /* abort if card not present */ | ||
503 | if (!(ioread16(host->ioaddr + SD_CARDSTATUS) & SD_CARD_PRESENT_0)) { | ||
504 | mrq->cmd->error = -ENOMEDIUM; | ||
505 | mmc_request_done(mmc, mrq); | ||
506 | return; | ||
507 | } | ||
508 | |||
509 | spin_lock_irqsave(&host->lock, flags); | ||
510 | |||
511 | WARN_ON(host->mrq != NULL); | ||
512 | |||
513 | host->mrq = mrq; | ||
514 | |||
515 | if (mrq->data) | ||
516 | toshsd_start_data(host, mrq->data); | ||
517 | |||
518 | toshsd_set_led(host, 1); | ||
519 | |||
520 | toshsd_start_cmd(host, mrq->cmd); | ||
521 | |||
522 | spin_unlock_irqrestore(&host->lock, flags); | ||
523 | } | ||
524 | |||
525 | static void toshsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
526 | { | ||
527 | struct toshsd_host *host = mmc_priv(mmc); | ||
528 | unsigned long flags; | ||
529 | |||
530 | spin_lock_irqsave(&host->lock, flags); | ||
531 | __toshsd_set_ios(mmc, ios); | ||
532 | spin_unlock_irqrestore(&host->lock, flags); | ||
533 | } | ||
534 | |||
535 | static int toshsd_get_ro(struct mmc_host *mmc) | ||
536 | { | ||
537 | struct toshsd_host *host = mmc_priv(mmc); | ||
538 | |||
539 | /* active low */ | ||
540 | return !(ioread16(host->ioaddr + SD_CARDSTATUS) & SD_CARD_WRITE_PROTECT); | ||
541 | } | ||
542 | |||
543 | static int toshsd_get_cd(struct mmc_host *mmc) | ||
544 | { | ||
545 | struct toshsd_host *host = mmc_priv(mmc); | ||
546 | |||
547 | return !!(ioread16(host->ioaddr + SD_CARDSTATUS) & SD_CARD_PRESENT_0); | ||
548 | } | ||
549 | |||
550 | static struct mmc_host_ops toshsd_ops = { | ||
551 | .request = toshsd_request, | ||
552 | .set_ios = toshsd_set_ios, | ||
553 | .get_ro = toshsd_get_ro, | ||
554 | .get_cd = toshsd_get_cd, | ||
555 | }; | ||
556 | |||
557 | |||
558 | static void toshsd_powerdown(struct toshsd_host *host) | ||
559 | { | ||
560 | /* mask all interrupts */ | ||
561 | iowrite32(0xffffffff, host->ioaddr + SD_INTMASKCARD); | ||
562 | /* disable card clock */ | ||
563 | iowrite16(0x000, host->ioaddr + SDIO_BASE + SDIO_CLOCKNWAITCTRL); | ||
564 | iowrite16(0, host->ioaddr + SD_CARDCLOCKCTRL); | ||
565 | /* power down card */ | ||
566 | pci_write_config_byte(host->pdev, SD_PCICFG_POWER1, SD_PCICFG_PWR1_OFF); | ||
567 | /* disable clock */ | ||
568 | pci_write_config_byte(host->pdev, SD_PCICFG_CLKSTOP, 0); | ||
569 | } | ||
570 | |||
571 | #ifdef CONFIG_PM_SLEEP | ||
572 | static int toshsd_pm_suspend(struct device *dev) | ||
573 | { | ||
574 | struct pci_dev *pdev = to_pci_dev(dev); | ||
575 | struct toshsd_host *host = pci_get_drvdata(pdev); | ||
576 | |||
577 | toshsd_powerdown(host); | ||
578 | |||
579 | pci_save_state(pdev); | ||
580 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
581 | pci_disable_device(pdev); | ||
582 | pci_set_power_state(pdev, PCI_D3hot); | ||
583 | |||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | static int toshsd_pm_resume(struct device *dev) | ||
588 | { | ||
589 | struct pci_dev *pdev = to_pci_dev(dev); | ||
590 | struct toshsd_host *host = pci_get_drvdata(pdev); | ||
591 | int ret; | ||
592 | |||
593 | pci_set_power_state(pdev, PCI_D0); | ||
594 | pci_restore_state(pdev); | ||
595 | ret = pci_enable_device(pdev); | ||
596 | if (ret) | ||
597 | return ret; | ||
598 | |||
599 | toshsd_init(host); | ||
600 | |||
601 | return 0; | ||
602 | } | ||
603 | #endif /* CONFIG_PM_SLEEP */ | ||
604 | |||
605 | static int toshsd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
606 | { | ||
607 | int ret; | ||
608 | struct toshsd_host *host; | ||
609 | struct mmc_host *mmc; | ||
610 | resource_size_t base; | ||
611 | |||
612 | ret = pci_enable_device(pdev); | ||
613 | if (ret) | ||
614 | return ret; | ||
615 | |||
616 | mmc = mmc_alloc_host(sizeof(struct toshsd_host), &pdev->dev); | ||
617 | if (!mmc) { | ||
618 | ret = -ENOMEM; | ||
619 | goto err; | ||
620 | } | ||
621 | |||
622 | host = mmc_priv(mmc); | ||
623 | host->mmc = mmc; | ||
624 | |||
625 | host->pdev = pdev; | ||
626 | pci_set_drvdata(pdev, host); | ||
627 | |||
628 | ret = pci_request_regions(pdev, DRIVER_NAME); | ||
629 | if (ret) | ||
630 | goto free; | ||
631 | |||
632 | host->ioaddr = pci_iomap(pdev, 0, 0); | ||
633 | if (!host->ioaddr) { | ||
634 | ret = -ENOMEM; | ||
635 | goto release; | ||
636 | } | ||
637 | |||
638 | /* Set MMC host parameters */ | ||
639 | mmc->ops = &toshsd_ops; | ||
640 | mmc->caps = MMC_CAP_4_BIT_DATA; | ||
641 | mmc->ocr_avail = MMC_VDD_32_33; | ||
642 | |||
643 | mmc->f_min = HCLK / 512; | ||
644 | mmc->f_max = HCLK; | ||
645 | |||
646 | spin_lock_init(&host->lock); | ||
647 | |||
648 | toshsd_init(host); | ||
649 | |||
650 | ret = request_threaded_irq(pdev->irq, toshsd_irq, toshsd_thread_irq, | ||
651 | IRQF_SHARED, DRIVER_NAME, host); | ||
652 | if (ret) | ||
653 | goto unmap; | ||
654 | |||
655 | mmc_add_host(mmc); | ||
656 | |||
657 | base = pci_resource_start(pdev, 0); | ||
658 | dev_dbg(&pdev->dev, "MMIO %pa, IRQ %d\n", &base, pdev->irq); | ||
659 | |||
660 | pm_suspend_ignore_children(&pdev->dev, 1); | ||
661 | |||
662 | return 0; | ||
663 | |||
664 | unmap: | ||
665 | pci_iounmap(pdev, host->ioaddr); | ||
666 | release: | ||
667 | pci_release_regions(pdev); | ||
668 | free: | ||
669 | mmc_free_host(mmc); | ||
670 | pci_set_drvdata(pdev, NULL); | ||
671 | err: | ||
672 | pci_disable_device(pdev); | ||
673 | return ret; | ||
674 | } | ||
675 | |||
676 | static void toshsd_remove(struct pci_dev *pdev) | ||
677 | { | ||
678 | struct toshsd_host *host = pci_get_drvdata(pdev); | ||
679 | |||
680 | mmc_remove_host(host->mmc); | ||
681 | toshsd_powerdown(host); | ||
682 | free_irq(pdev->irq, host); | ||
683 | pci_iounmap(pdev, host->ioaddr); | ||
684 | pci_release_regions(pdev); | ||
685 | mmc_free_host(host->mmc); | ||
686 | pci_set_drvdata(pdev, NULL); | ||
687 | pci_disable_device(pdev); | ||
688 | } | ||
689 | |||
690 | static const struct dev_pm_ops toshsd_pm_ops = { | ||
691 | SET_SYSTEM_SLEEP_PM_OPS(toshsd_pm_suspend, toshsd_pm_resume) | ||
692 | }; | ||
693 | |||
694 | static struct pci_driver toshsd_driver = { | ||
695 | .name = DRIVER_NAME, | ||
696 | .id_table = pci_ids, | ||
697 | .probe = toshsd_probe, | ||
698 | .remove = toshsd_remove, | ||
699 | .driver.pm = &toshsd_pm_ops, | ||
700 | }; | ||
701 | |||
702 | static int __init toshsd_drv_init(void) | ||
703 | { | ||
704 | return pci_register_driver(&toshsd_driver); | ||
705 | } | ||
706 | |||
707 | static void __exit toshsd_drv_exit(void) | ||
708 | { | ||
709 | pci_unregister_driver(&toshsd_driver); | ||
710 | } | ||
711 | |||
712 | module_init(toshsd_drv_init); | ||
713 | module_exit(toshsd_drv_exit); | ||
714 | |||
715 | MODULE_AUTHOR("Ondrej Zary, Richard Betts"); | ||
716 | MODULE_DESCRIPTION("Toshiba PCI Secure Digital Host Controller Interface driver"); | ||
717 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mmc/host/toshsd.h b/drivers/mmc/host/toshsd.h new file mode 100644 index 000000000000..b6c0d89e53a6 --- /dev/null +++ b/drivers/mmc/host/toshsd.h | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * Toshiba PCI Secure Digital Host Controller Interface driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Ondrej Zary | ||
5 | * Copyright (C) 2007 Richard Betts, All Rights Reserved. | ||
6 | * | ||
7 | * Based on asic3_mmc.c Copyright (c) 2005 SDG Systems, LLC | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or (at | ||
12 | * your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #define HCLK 33000000 /* 33 MHz (PCI clock) */ | ||
16 | |||
17 | #define SD_PCICFG_CLKSTOP 0x40 /* 0x1f = clock controller, 0 = stop */ | ||
18 | #define SD_PCICFG_GATEDCLK 0x41 /* Gated clock */ | ||
19 | #define SD_PCICFG_CLKMODE 0x42 /* Control clock of SD controller */ | ||
20 | #define SD_PCICFG_PINSTATUS 0x44 /* R/O: read status of SD pins */ | ||
21 | #define SD_PCICFG_POWER1 0x48 | ||
22 | #define SD_PCICFG_POWER2 0x49 | ||
23 | #define SD_PCICFG_POWER3 0x4a | ||
24 | #define SD_PCICFG_CARDDETECT 0x4c | ||
25 | #define SD_PCICFG_SLOTS 0x50 /* R/O: define support slot number */ | ||
26 | #define SD_PCICFG_EXTGATECLK1 0xf0 /* Could be used for gated clock */ | ||
27 | #define SD_PCICFG_EXTGATECLK2 0xf1 /* Could be used for gated clock */ | ||
28 | #define SD_PCICFG_EXTGATECLK3 0xf9 /* Bit 1: double buffer/single buffer */ | ||
29 | #define SD_PCICFG_SDLED_ENABLE1 0xfa | ||
30 | #define SD_PCICFG_SDLED_ENABLE2 0xfe | ||
31 | |||
32 | #define SD_PCICFG_CLKMODE_DIV_DISABLE BIT(0) | ||
33 | #define SD_PCICFG_CLKSTOP_ENABLE_ALL 0x1f | ||
34 | #define SD_PCICFG_LED_ENABLE1_START 0x12 | ||
35 | #define SD_PCICFG_LED_ENABLE2_START 0x80 | ||
36 | |||
37 | #define SD_PCICFG_PWR1_33V 0x08 /* Set for 3.3 volts */ | ||
38 | #define SD_PCICFG_PWR1_OFF 0x00 /* Turn off power */ | ||
39 | #define SD_PCICFG_PWR2_AUTO 0x02 | ||
40 | |||
41 | #define SD_CMD 0x00 /* also for SDIO */ | ||
42 | #define SD_ARG0 0x04 /* also for SDIO */ | ||
43 | #define SD_ARG1 0x06 /* also for SDIO */ | ||
44 | #define SD_STOPINTERNAL 0x08 | ||
45 | #define SD_BLOCKCOUNT 0x0a /* also for SDIO */ | ||
46 | #define SD_RESPONSE0 0x0c /* also for SDIO */ | ||
47 | #define SD_RESPONSE1 0x0e /* also for SDIO */ | ||
48 | #define SD_RESPONSE2 0x10 /* also for SDIO */ | ||
49 | #define SD_RESPONSE3 0x12 /* also for SDIO */ | ||
50 | #define SD_RESPONSE4 0x14 /* also for SDIO */ | ||
51 | #define SD_RESPONSE5 0x16 /* also for SDIO */ | ||
52 | #define SD_RESPONSE6 0x18 /* also for SDIO */ | ||
53 | #define SD_RESPONSE7 0x1a /* also for SDIO */ | ||
54 | #define SD_CARDSTATUS 0x1c /* also for SDIO */ | ||
55 | #define SD_BUFFERCTRL 0x1e /* also for SDIO */ | ||
56 | #define SD_INTMASKCARD 0x20 /* also for SDIO */ | ||
57 | #define SD_INTMASKBUFFER 0x22 /* also for SDIO */ | ||
58 | #define SD_CARDCLOCKCTRL 0x24 | ||
59 | #define SD_CARDXFERDATALEN 0x26 /* also for SDIO */ | ||
60 | #define SD_CARDOPTIONSETUP 0x28 /* also for SDIO */ | ||
61 | #define SD_ERRORSTATUS0 0x2c /* also for SDIO */ | ||
62 | #define SD_ERRORSTATUS1 0x2e /* also for SDIO */ | ||
63 | #define SD_DATAPORT 0x30 /* also for SDIO */ | ||
64 | #define SD_TRANSACTIONCTRL 0x34 /* also for SDIO */ | ||
65 | #define SD_SOFTWARERESET 0xe0 /* also for SDIO */ | ||
66 | |||
67 | /* registers above marked "also for SDIO" and all SDIO registers below can be | ||
68 | * accessed at SDIO_BASE + reg address */ | ||
69 | #define SDIO_BASE 0x100 | ||
70 | |||
71 | #define SDIO_CARDPORTSEL 0x02 | ||
72 | #define SDIO_CARDINTCTRL 0x36 | ||
73 | #define SDIO_CLOCKNWAITCTRL 0x38 | ||
74 | #define SDIO_HOSTINFORMATION 0x3a | ||
75 | #define SDIO_ERRORCTRL 0x3c | ||
76 | #define SDIO_LEDCTRL 0x3e | ||
77 | |||
78 | #define SD_TRANSCTL_SET BIT(8) | ||
79 | |||
80 | #define SD_CARDCLK_DIV_DISABLE BIT(15) | ||
81 | #define SD_CARDCLK_ENABLE_CLOCK BIT(8) | ||
82 | #define SD_CARDCLK_CLK_DIV_512 BIT(7) | ||
83 | #define SD_CARDCLK_CLK_DIV_256 BIT(6) | ||
84 | #define SD_CARDCLK_CLK_DIV_128 BIT(5) | ||
85 | #define SD_CARDCLK_CLK_DIV_64 BIT(4) | ||
86 | #define SD_CARDCLK_CLK_DIV_32 BIT(3) | ||
87 | #define SD_CARDCLK_CLK_DIV_16 BIT(2) | ||
88 | #define SD_CARDCLK_CLK_DIV_8 BIT(1) | ||
89 | #define SD_CARDCLK_CLK_DIV_4 BIT(0) | ||
90 | #define SD_CARDCLK_CLK_DIV_2 0 | ||
91 | |||
92 | #define SD_CARDOPT_REQUIRED 0x000e | ||
93 | #define SD_CARDOPT_DATA_RESP_TIMEOUT(x) (((x) & 0x0f) << 4) /* 4 bits */ | ||
94 | #define SD_CARDOPT_C2_MODULE_ABSENT BIT(14) | ||
95 | #define SD_CARDOPT_DATA_XFR_WIDTH_1 (1 << 15) | ||
96 | #define SD_CARDOPT_DATA_XFR_WIDTH_4 (0 << 15) | ||
97 | |||
98 | #define SD_CMD_TYPE_CMD (0 << 6) | ||
99 | #define SD_CMD_TYPE_ACMD (1 << 6) | ||
100 | #define SD_CMD_TYPE_AUTHEN (2 << 6) | ||
101 | #define SD_CMD_RESP_TYPE_NONE (3 << 8) | ||
102 | #define SD_CMD_RESP_TYPE_EXT_R1 (4 << 8) | ||
103 | #define SD_CMD_RESP_TYPE_EXT_R1B (5 << 8) | ||
104 | #define SD_CMD_RESP_TYPE_EXT_R2 (6 << 8) | ||
105 | #define SD_CMD_RESP_TYPE_EXT_R3 (7 << 8) | ||
106 | #define SD_CMD_RESP_TYPE_EXT_R6 (4 << 8) | ||
107 | #define SD_CMD_RESP_TYPE_EXT_R7 (4 << 8) | ||
108 | #define SD_CMD_DATA_PRESENT BIT(11) | ||
109 | #define SD_CMD_TRANSFER_READ BIT(12) | ||
110 | #define SD_CMD_MULTI_BLOCK BIT(13) | ||
111 | #define SD_CMD_SECURITY_CMD BIT(14) | ||
112 | |||
113 | #define SD_STOPINT_ISSUE_CMD12 BIT(0) | ||
114 | #define SD_STOPINT_AUTO_ISSUE_CMD12 BIT(8) | ||
115 | |||
116 | #define SD_CARD_RESP_END BIT(0) | ||
117 | #define SD_CARD_RW_END BIT(2) | ||
118 | #define SD_CARD_CARD_REMOVED_0 BIT(3) | ||
119 | #define SD_CARD_CARD_INSERTED_0 BIT(4) | ||
120 | #define SD_CARD_PRESENT_0 BIT(5) | ||
121 | #define SD_CARD_UNK6 BIT(6) | ||
122 | #define SD_CARD_WRITE_PROTECT BIT(7) | ||
123 | #define SD_CARD_CARD_REMOVED_3 BIT(8) | ||
124 | #define SD_CARD_CARD_INSERTED_3 BIT(9) | ||
125 | #define SD_CARD_PRESENT_3 BIT(10) | ||
126 | |||
127 | #define SD_BUF_CMD_INDEX_ERR BIT(16) | ||
128 | #define SD_BUF_CRC_ERR BIT(17) | ||
129 | #define SD_BUF_STOP_BIT_END_ERR BIT(18) | ||
130 | #define SD_BUF_DATA_TIMEOUT BIT(19) | ||
131 | #define SD_BUF_OVERFLOW BIT(20) | ||
132 | #define SD_BUF_UNDERFLOW BIT(21) | ||
133 | #define SD_BUF_CMD_TIMEOUT BIT(22) | ||
134 | #define SD_BUF_UNK7 BIT(23) | ||
135 | #define SD_BUF_READ_ENABLE BIT(24) | ||
136 | #define SD_BUF_WRITE_ENABLE BIT(25) | ||
137 | #define SD_BUF_ILLEGAL_FUNCTION BIT(29) | ||
138 | #define SD_BUF_CMD_BUSY BIT(30) | ||
139 | #define SD_BUF_ILLEGAL_ACCESS BIT(31) | ||
140 | |||
141 | #define SD_ERR0_RESP_CMD_ERR BIT(0) | ||
142 | #define SD_ERR0_RESP_NON_CMD12_END_BIT_ERR BIT(2) | ||
143 | #define SD_ERR0_RESP_CMD12_END_BIT_ERR BIT(3) | ||
144 | #define SD_ERR0_READ_DATA_END_BIT_ERR BIT(4) | ||
145 | #define SD_ERR0_WRITE_CRC_STATUS_END_BIT_ERR BIT(5) | ||
146 | #define SD_ERR0_RESP_NON_CMD12_CRC_ERR BIT(8) | ||
147 | #define SD_ERR0_RESP_CMD12_CRC_ERR BIT(9) | ||
148 | #define SD_ERR0_READ_DATA_CRC_ERR BIT(10) | ||
149 | #define SD_ERR0_WRITE_CMD_CRC_ERR BIT(11) | ||
150 | |||
151 | #define SD_ERR1_NO_CMD_RESP BIT(16) | ||
152 | #define SD_ERR1_TIMEOUT_READ_DATA BIT(20) | ||
153 | #define SD_ERR1_TIMEOUT_CRS_STATUS BIT(21) | ||
154 | #define SD_ERR1_TIMEOUT_CRC_BUSY BIT(22) | ||
155 | |||
156 | #define IRQ_DONT_CARE_BITS (SD_CARD_PRESENT_3 \ | ||
157 | | SD_CARD_WRITE_PROTECT \ | ||
158 | | SD_CARD_UNK6 \ | ||
159 | | SD_CARD_PRESENT_0 \ | ||
160 | | SD_BUF_UNK7 \ | ||
161 | | SD_BUF_CMD_BUSY) | ||
162 | |||
163 | struct toshsd_host { | ||
164 | struct pci_dev *pdev; | ||
165 | struct mmc_host *mmc; | ||
166 | |||
167 | spinlock_t lock; | ||
168 | |||
169 | struct mmc_request *mrq;/* Current request */ | ||
170 | struct mmc_command *cmd;/* Current command */ | ||
171 | struct mmc_data *data; /* Current data request */ | ||
172 | |||
173 | struct sg_mapping_iter sg_miter; /* for PIO */ | ||
174 | |||
175 | void __iomem *ioaddr; /* mapped address */ | ||
176 | }; | ||
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index c13d83e15ace..45f09a66e6c9 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c | |||
@@ -225,7 +225,12 @@ static int bond_changelink(struct net_device *bond_dev, | |||
225 | 225 | ||
226 | bond_option_arp_ip_targets_clear(bond); | 226 | bond_option_arp_ip_targets_clear(bond); |
227 | nla_for_each_nested(attr, data[IFLA_BOND_ARP_IP_TARGET], rem) { | 227 | nla_for_each_nested(attr, data[IFLA_BOND_ARP_IP_TARGET], rem) { |
228 | __be32 target = nla_get_be32(attr); | 228 | __be32 target; |
229 | |||
230 | if (nla_len(attr) < sizeof(target)) | ||
231 | return -EINVAL; | ||
232 | |||
233 | target = nla_get_be32(attr); | ||
229 | 234 | ||
230 | bond_opt_initval(&newval, (__force u64)target); | 235 | bond_opt_initval(&newval, (__force u64)target); |
231 | err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS, | 236 | err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS, |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 8520d5529df8..279873cb6e3a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -2442,9 +2442,13 @@ static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps) | |||
2442 | SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full | | 2442 | SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full | |
2443 | SUPPORTED_10000baseKX4_Full; | 2443 | SUPPORTED_10000baseKX4_Full; |
2444 | else if (type == FW_PORT_TYPE_FIBER_XFI || | 2444 | else if (type == FW_PORT_TYPE_FIBER_XFI || |
2445 | type == FW_PORT_TYPE_FIBER_XAUI || type == FW_PORT_TYPE_SFP) | 2445 | type == FW_PORT_TYPE_FIBER_XAUI || type == FW_PORT_TYPE_SFP) { |
2446 | v |= SUPPORTED_FIBRE; | 2446 | v |= SUPPORTED_FIBRE; |
2447 | else if (type == FW_PORT_TYPE_BP40_BA) | 2447 | if (caps & FW_PORT_CAP_SPEED_1G) |
2448 | v |= SUPPORTED_1000baseT_Full; | ||
2449 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
2450 | v |= SUPPORTED_10000baseT_Full; | ||
2451 | } else if (type == FW_PORT_TYPE_BP40_BA) | ||
2448 | v |= SUPPORTED_40000baseSR4_Full; | 2452 | v |= SUPPORTED_40000baseSR4_Full; |
2449 | 2453 | ||
2450 | if (caps & FW_PORT_CAP_ANEG) | 2454 | if (caps & FW_PORT_CAP_ANEG) |
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 60e9c2cd051e..b5db6b3f939f 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -917,21 +917,13 @@ static int sh_eth_reset(struct net_device *ndev) | |||
917 | return ret; | 917 | return ret; |
918 | } | 918 | } |
919 | 919 | ||
920 | #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) | ||
921 | static void sh_eth_set_receive_align(struct sk_buff *skb) | 920 | static void sh_eth_set_receive_align(struct sk_buff *skb) |
922 | { | 921 | { |
923 | int reserve; | 922 | uintptr_t reserve = (uintptr_t)skb->data & (SH_ETH_RX_ALIGN - 1); |
924 | 923 | ||
925 | reserve = SH4_SKB_RX_ALIGN - ((u32)skb->data & (SH4_SKB_RX_ALIGN - 1)); | ||
926 | if (reserve) | 924 | if (reserve) |
927 | skb_reserve(skb, reserve); | 925 | skb_reserve(skb, SH_ETH_RX_ALIGN - reserve); |
928 | } | 926 | } |
929 | #else | ||
930 | static void sh_eth_set_receive_align(struct sk_buff *skb) | ||
931 | { | ||
932 | skb_reserve(skb, SH2_SH3_SKB_RX_ALIGN); | ||
933 | } | ||
934 | #endif | ||
935 | 927 | ||
936 | 928 | ||
937 | /* CPU <-> EDMAC endian convert */ | 929 | /* CPU <-> EDMAC endian convert */ |
@@ -1119,6 +1111,7 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
1119 | struct sh_eth_txdesc *txdesc = NULL; | 1111 | struct sh_eth_txdesc *txdesc = NULL; |
1120 | int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring; | 1112 | int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring; |
1121 | int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring; | 1113 | int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring; |
1114 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; | ||
1122 | 1115 | ||
1123 | mdp->cur_rx = 0; | 1116 | mdp->cur_rx = 0; |
1124 | mdp->cur_tx = 0; | 1117 | mdp->cur_tx = 0; |
@@ -1131,21 +1124,21 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
1131 | for (i = 0; i < mdp->num_rx_ring; i++) { | 1124 | for (i = 0; i < mdp->num_rx_ring; i++) { |
1132 | /* skb */ | 1125 | /* skb */ |
1133 | mdp->rx_skbuff[i] = NULL; | 1126 | mdp->rx_skbuff[i] = NULL; |
1134 | skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz); | 1127 | skb = netdev_alloc_skb(ndev, skbuff_size); |
1135 | mdp->rx_skbuff[i] = skb; | 1128 | mdp->rx_skbuff[i] = skb; |
1136 | if (skb == NULL) | 1129 | if (skb == NULL) |
1137 | break; | 1130 | break; |
1138 | dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz, | ||
1139 | DMA_FROM_DEVICE); | ||
1140 | sh_eth_set_receive_align(skb); | 1131 | sh_eth_set_receive_align(skb); |
1141 | 1132 | ||
1142 | /* RX descriptor */ | 1133 | /* RX descriptor */ |
1143 | rxdesc = &mdp->rx_ring[i]; | 1134 | rxdesc = &mdp->rx_ring[i]; |
1135 | /* The size of the buffer is a multiple of 16 bytes. */ | ||
1136 | rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); | ||
1137 | dma_map_single(&ndev->dev, skb->data, rxdesc->buffer_length, | ||
1138 | DMA_FROM_DEVICE); | ||
1144 | rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); | 1139 | rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); |
1145 | rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP); | 1140 | rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP); |
1146 | 1141 | ||
1147 | /* The size of the buffer is 16 byte boundary. */ | ||
1148 | rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); | ||
1149 | /* Rx descriptor address set */ | 1142 | /* Rx descriptor address set */ |
1150 | if (i == 0) { | 1143 | if (i == 0) { |
1151 | sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR); | 1144 | sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR); |
@@ -1397,6 +1390,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) | |||
1397 | struct sk_buff *skb; | 1390 | struct sk_buff *skb; |
1398 | u16 pkt_len = 0; | 1391 | u16 pkt_len = 0; |
1399 | u32 desc_status; | 1392 | u32 desc_status; |
1393 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; | ||
1400 | 1394 | ||
1401 | rxdesc = &mdp->rx_ring[entry]; | 1395 | rxdesc = &mdp->rx_ring[entry]; |
1402 | while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) { | 1396 | while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) { |
@@ -1448,7 +1442,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) | |||
1448 | if (mdp->cd->rpadir) | 1442 | if (mdp->cd->rpadir) |
1449 | skb_reserve(skb, NET_IP_ALIGN); | 1443 | skb_reserve(skb, NET_IP_ALIGN); |
1450 | dma_sync_single_for_cpu(&ndev->dev, rxdesc->addr, | 1444 | dma_sync_single_for_cpu(&ndev->dev, rxdesc->addr, |
1451 | mdp->rx_buf_sz, | 1445 | ALIGN(mdp->rx_buf_sz, 16), |
1452 | DMA_FROM_DEVICE); | 1446 | DMA_FROM_DEVICE); |
1453 | skb_put(skb, pkt_len); | 1447 | skb_put(skb, pkt_len); |
1454 | skb->protocol = eth_type_trans(skb, ndev); | 1448 | skb->protocol = eth_type_trans(skb, ndev); |
@@ -1468,13 +1462,13 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) | |||
1468 | rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); | 1462 | rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); |
1469 | 1463 | ||
1470 | if (mdp->rx_skbuff[entry] == NULL) { | 1464 | if (mdp->rx_skbuff[entry] == NULL) { |
1471 | skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz); | 1465 | skb = netdev_alloc_skb(ndev, skbuff_size); |
1472 | mdp->rx_skbuff[entry] = skb; | 1466 | mdp->rx_skbuff[entry] = skb; |
1473 | if (skb == NULL) | 1467 | if (skb == NULL) |
1474 | break; /* Better luck next round. */ | 1468 | break; /* Better luck next round. */ |
1475 | dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz, | ||
1476 | DMA_FROM_DEVICE); | ||
1477 | sh_eth_set_receive_align(skb); | 1469 | sh_eth_set_receive_align(skb); |
1470 | dma_map_single(&ndev->dev, skb->data, | ||
1471 | rxdesc->buffer_length, DMA_FROM_DEVICE); | ||
1478 | 1472 | ||
1479 | skb_checksum_none_assert(skb); | 1473 | skb_checksum_none_assert(skb); |
1480 | rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); | 1474 | rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); |
@@ -2042,6 +2036,8 @@ static int sh_eth_open(struct net_device *ndev) | |||
2042 | if (ret) | 2036 | if (ret) |
2043 | goto out_free_irq; | 2037 | goto out_free_irq; |
2044 | 2038 | ||
2039 | mdp->is_opened = 1; | ||
2040 | |||
2045 | return ret; | 2041 | return ret; |
2046 | 2042 | ||
2047 | out_free_irq: | 2043 | out_free_irq: |
@@ -2131,6 +2127,36 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
2131 | return NETDEV_TX_OK; | 2127 | return NETDEV_TX_OK; |
2132 | } | 2128 | } |
2133 | 2129 | ||
2130 | static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) | ||
2131 | { | ||
2132 | struct sh_eth_private *mdp = netdev_priv(ndev); | ||
2133 | |||
2134 | if (sh_eth_is_rz_fast_ether(mdp)) | ||
2135 | return &ndev->stats; | ||
2136 | |||
2137 | if (!mdp->is_opened) | ||
2138 | return &ndev->stats; | ||
2139 | |||
2140 | ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR); | ||
2141 | sh_eth_write(ndev, 0, TROCR); /* (write clear) */ | ||
2142 | ndev->stats.collisions += sh_eth_read(ndev, CDCR); | ||
2143 | sh_eth_write(ndev, 0, CDCR); /* (write clear) */ | ||
2144 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR); | ||
2145 | sh_eth_write(ndev, 0, LCCR); /* (write clear) */ | ||
2146 | |||
2147 | if (sh_eth_is_gether(mdp)) { | ||
2148 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR); | ||
2149 | sh_eth_write(ndev, 0, CERCR); /* (write clear) */ | ||
2150 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR); | ||
2151 | sh_eth_write(ndev, 0, CEECR); /* (write clear) */ | ||
2152 | } else { | ||
2153 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR); | ||
2154 | sh_eth_write(ndev, 0, CNDCR); /* (write clear) */ | ||
2155 | } | ||
2156 | |||
2157 | return &ndev->stats; | ||
2158 | } | ||
2159 | |||
2134 | /* device close function */ | 2160 | /* device close function */ |
2135 | static int sh_eth_close(struct net_device *ndev) | 2161 | static int sh_eth_close(struct net_device *ndev) |
2136 | { | 2162 | { |
@@ -2145,6 +2171,7 @@ static int sh_eth_close(struct net_device *ndev) | |||
2145 | sh_eth_write(ndev, 0, EDTRR); | 2171 | sh_eth_write(ndev, 0, EDTRR); |
2146 | sh_eth_write(ndev, 0, EDRRR); | 2172 | sh_eth_write(ndev, 0, EDRRR); |
2147 | 2173 | ||
2174 | sh_eth_get_stats(ndev); | ||
2148 | /* PHY Disconnect */ | 2175 | /* PHY Disconnect */ |
2149 | if (mdp->phydev) { | 2176 | if (mdp->phydev) { |
2150 | phy_stop(mdp->phydev); | 2177 | phy_stop(mdp->phydev); |
@@ -2163,36 +2190,9 @@ static int sh_eth_close(struct net_device *ndev) | |||
2163 | 2190 | ||
2164 | pm_runtime_put_sync(&mdp->pdev->dev); | 2191 | pm_runtime_put_sync(&mdp->pdev->dev); |
2165 | 2192 | ||
2166 | return 0; | 2193 | mdp->is_opened = 0; |
2167 | } | ||
2168 | |||
2169 | static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) | ||
2170 | { | ||
2171 | struct sh_eth_private *mdp = netdev_priv(ndev); | ||
2172 | |||
2173 | if (sh_eth_is_rz_fast_ether(mdp)) | ||
2174 | return &ndev->stats; | ||
2175 | 2194 | ||
2176 | pm_runtime_get_sync(&mdp->pdev->dev); | 2195 | return 0; |
2177 | |||
2178 | ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR); | ||
2179 | sh_eth_write(ndev, 0, TROCR); /* (write clear) */ | ||
2180 | ndev->stats.collisions += sh_eth_read(ndev, CDCR); | ||
2181 | sh_eth_write(ndev, 0, CDCR); /* (write clear) */ | ||
2182 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR); | ||
2183 | sh_eth_write(ndev, 0, LCCR); /* (write clear) */ | ||
2184 | if (sh_eth_is_gether(mdp)) { | ||
2185 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR); | ||
2186 | sh_eth_write(ndev, 0, CERCR); /* (write clear) */ | ||
2187 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR); | ||
2188 | sh_eth_write(ndev, 0, CEECR); /* (write clear) */ | ||
2189 | } else { | ||
2190 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR); | ||
2191 | sh_eth_write(ndev, 0, CNDCR); /* (write clear) */ | ||
2192 | } | ||
2193 | pm_runtime_put_sync(&mdp->pdev->dev); | ||
2194 | |||
2195 | return &ndev->stats; | ||
2196 | } | 2196 | } |
2197 | 2197 | ||
2198 | /* ioctl to device function */ | 2198 | /* ioctl to device function */ |
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index b37c427144ee..22301bf9c21d 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h | |||
@@ -162,9 +162,9 @@ enum { | |||
162 | 162 | ||
163 | /* Driver's parameters */ | 163 | /* Driver's parameters */ |
164 | #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) | 164 | #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) |
165 | #define SH4_SKB_RX_ALIGN 32 | 165 | #define SH_ETH_RX_ALIGN 32 |
166 | #else | 166 | #else |
167 | #define SH2_SH3_SKB_RX_ALIGN 2 | 167 | #define SH_ETH_RX_ALIGN 2 |
168 | #endif | 168 | #endif |
169 | 169 | ||
170 | /* Register's bits | 170 | /* Register's bits |
@@ -522,6 +522,7 @@ struct sh_eth_private { | |||
522 | 522 | ||
523 | unsigned no_ether_link:1; | 523 | unsigned no_ether_link:1; |
524 | unsigned ether_link_active_low:1; | 524 | unsigned ether_link_active_low:1; |
525 | unsigned is_opened:1; | ||
525 | }; | 526 | }; |
526 | 527 | ||
527 | static inline void sh_eth_soft_swap(char *src, int len) | 528 | static inline void sh_eth_soft_swap(char *src, int len) |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 5b0da3986216..58a1a0a423d4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
@@ -265,6 +265,15 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) | |||
265 | 265 | ||
266 | plat_dat = dev_get_platdata(&pdev->dev); | 266 | plat_dat = dev_get_platdata(&pdev->dev); |
267 | 267 | ||
268 | if (!plat_dat) | ||
269 | plat_dat = devm_kzalloc(&pdev->dev, | ||
270 | sizeof(struct plat_stmmacenet_data), | ||
271 | GFP_KERNEL); | ||
272 | if (!plat_dat) { | ||
273 | pr_err("%s: ERROR: no memory", __func__); | ||
274 | return -ENOMEM; | ||
275 | } | ||
276 | |||
268 | /* Set default value for multicast hash bins */ | 277 | /* Set default value for multicast hash bins */ |
269 | plat_dat->multicast_filter_bins = HASH_TABLE_SIZE; | 278 | plat_dat->multicast_filter_bins = HASH_TABLE_SIZE; |
270 | 279 | ||
@@ -272,15 +281,6 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) | |||
272 | plat_dat->unicast_filter_entries = 1; | 281 | plat_dat->unicast_filter_entries = 1; |
273 | 282 | ||
274 | if (pdev->dev.of_node) { | 283 | if (pdev->dev.of_node) { |
275 | if (!plat_dat) | ||
276 | plat_dat = devm_kzalloc(&pdev->dev, | ||
277 | sizeof(struct plat_stmmacenet_data), | ||
278 | GFP_KERNEL); | ||
279 | if (!plat_dat) { | ||
280 | pr_err("%s: ERROR: no memory", __func__); | ||
281 | return -ENOMEM; | ||
282 | } | ||
283 | |||
284 | ret = stmmac_probe_config_dt(pdev, plat_dat, &mac); | 284 | ret = stmmac_probe_config_dt(pdev, plat_dat, &mac); |
285 | if (ret) { | 285 | if (ret) { |
286 | pr_err("%s: main dt probe failed", __func__); | 286 | pr_err("%s: main dt probe failed", __func__); |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index cca871346a0f..ece8d1804d13 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -496,9 +496,6 @@ static void xennet_make_frags(struct sk_buff *skb, struct netfront_queue *queue, | |||
496 | len = skb_frag_size(frag); | 496 | len = skb_frag_size(frag); |
497 | offset = frag->page_offset; | 497 | offset = frag->page_offset; |
498 | 498 | ||
499 | /* Data must not cross a page boundary. */ | ||
500 | BUG_ON(len + offset > PAGE_SIZE<<compound_order(page)); | ||
501 | |||
502 | /* Skip unused frames from start of page */ | 499 | /* Skip unused frames from start of page */ |
503 | page += offset >> PAGE_SHIFT; | 500 | page += offset >> PAGE_SHIFT; |
504 | offset &= ~PAGE_MASK; | 501 | offset &= ~PAGE_MASK; |
@@ -506,8 +503,6 @@ static void xennet_make_frags(struct sk_buff *skb, struct netfront_queue *queue, | |||
506 | while (len > 0) { | 503 | while (len > 0) { |
507 | unsigned long bytes; | 504 | unsigned long bytes; |
508 | 505 | ||
509 | BUG_ON(offset >= PAGE_SIZE); | ||
510 | |||
511 | bytes = PAGE_SIZE - offset; | 506 | bytes = PAGE_SIZE - offset; |
512 | if (bytes > len) | 507 | if (bytes > len) |
513 | bytes = len; | 508 | bytes = len; |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 30e97bcc4f88..d134710de96d 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -964,8 +964,6 @@ void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size) | |||
964 | int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base, | 964 | int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base, |
965 | phys_addr_t size, bool nomap) | 965 | phys_addr_t size, bool nomap) |
966 | { | 966 | { |
967 | if (memblock_is_region_reserved(base, size)) | ||
968 | return -EBUSY; | ||
969 | if (nomap) | 967 | if (nomap) |
970 | return memblock_remove(base, size); | 968 | return memblock_remove(base, size); |
971 | return memblock_reserve(base, size); | 969 | return memblock_reserve(base, size); |
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 3d43874319be..19bb19c7db4a 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -276,6 +276,7 @@ struct tegra_pcie { | |||
276 | 276 | ||
277 | struct resource all; | 277 | struct resource all; |
278 | struct resource io; | 278 | struct resource io; |
279 | struct resource pio; | ||
279 | struct resource mem; | 280 | struct resource mem; |
280 | struct resource prefetch; | 281 | struct resource prefetch; |
281 | struct resource busn; | 282 | struct resource busn; |
@@ -658,7 +659,6 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
658 | { | 659 | { |
659 | struct tegra_pcie *pcie = sys_to_pcie(sys); | 660 | struct tegra_pcie *pcie = sys_to_pcie(sys); |
660 | int err; | 661 | int err; |
661 | phys_addr_t io_start; | ||
662 | 662 | ||
663 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->mem); | 663 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->mem); |
664 | if (err < 0) | 664 | if (err < 0) |
@@ -668,14 +668,12 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
668 | if (err) | 668 | if (err) |
669 | return err; | 669 | return err; |
670 | 670 | ||
671 | io_start = pci_pio_to_address(pcie->io.start); | ||
672 | |||
673 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 671 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); |
674 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, | 672 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, |
675 | sys->mem_offset); | 673 | sys->mem_offset); |
676 | pci_add_resource(&sys->resources, &pcie->busn); | 674 | pci_add_resource(&sys->resources, &pcie->busn); |
677 | 675 | ||
678 | pci_ioremap_io(nr * SZ_64K, io_start); | 676 | pci_ioremap_io(pcie->pio.start, pcie->io.start); |
679 | 677 | ||
680 | return 1; | 678 | return 1; |
681 | } | 679 | } |
@@ -786,7 +784,6 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg) | |||
786 | static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | 784 | static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) |
787 | { | 785 | { |
788 | u32 fpci_bar, size, axi_address; | 786 | u32 fpci_bar, size, axi_address; |
789 | phys_addr_t io_start = pci_pio_to_address(pcie->io.start); | ||
790 | 787 | ||
791 | /* Bar 0: type 1 extended configuration space */ | 788 | /* Bar 0: type 1 extended configuration space */ |
792 | fpci_bar = 0xfe100000; | 789 | fpci_bar = 0xfe100000; |
@@ -799,7 +796,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | |||
799 | /* Bar 1: downstream IO bar */ | 796 | /* Bar 1: downstream IO bar */ |
800 | fpci_bar = 0xfdfc0000; | 797 | fpci_bar = 0xfdfc0000; |
801 | size = resource_size(&pcie->io); | 798 | size = resource_size(&pcie->io); |
802 | axi_address = io_start; | 799 | axi_address = pcie->io.start; |
803 | afi_writel(pcie, axi_address, AFI_AXI_BAR1_START); | 800 | afi_writel(pcie, axi_address, AFI_AXI_BAR1_START); |
804 | afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); | 801 | afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); |
805 | afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1); | 802 | afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1); |
@@ -1690,8 +1687,23 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) | |||
1690 | 1687 | ||
1691 | switch (res.flags & IORESOURCE_TYPE_BITS) { | 1688 | switch (res.flags & IORESOURCE_TYPE_BITS) { |
1692 | case IORESOURCE_IO: | 1689 | case IORESOURCE_IO: |
1693 | memcpy(&pcie->io, &res, sizeof(res)); | 1690 | memcpy(&pcie->pio, &res, sizeof(res)); |
1694 | pcie->io.name = np->full_name; | 1691 | pcie->pio.name = np->full_name; |
1692 | |||
1693 | /* | ||
1694 | * The Tegra PCIe host bridge uses this to program the | ||
1695 | * mapping of the I/O space to the physical address, | ||
1696 | * so we override the .start and .end fields here that | ||
1697 | * of_pci_range_to_resource() converted to I/O space. | ||
1698 | * We also set the IORESOURCE_MEM type to clarify that | ||
1699 | * the resource is in the physical memory space. | ||
1700 | */ | ||
1701 | pcie->io.start = range.cpu_addr; | ||
1702 | pcie->io.end = range.cpu_addr + range.size - 1; | ||
1703 | pcie->io.flags = IORESOURCE_MEM; | ||
1704 | pcie->io.name = "I/O"; | ||
1705 | |||
1706 | memcpy(&res, &pcie->io, sizeof(res)); | ||
1695 | break; | 1707 | break; |
1696 | 1708 | ||
1697 | case IORESOURCE_MEM: | 1709 | case IORESOURCE_MEM: |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 5b303bfe9358..c3a60b57a865 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -537,13 +537,13 @@ config REGULATOR_S2MPA01 | |||
537 | via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs. | 537 | via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs. |
538 | 538 | ||
539 | config REGULATOR_S2MPS11 | 539 | config REGULATOR_S2MPS11 |
540 | tristate "Samsung S2MPS11/S2MPS14/S2MPU02 voltage regulator" | 540 | tristate "Samsung S2MPS11/S2MPS13/S2MPS14/S2MPU02 voltage regulator" |
541 | depends on MFD_SEC_CORE | 541 | depends on MFD_SEC_CORE |
542 | help | 542 | help |
543 | This driver supports a Samsung S2MPS11/S2MPS14/S2MPU02 voltage output | 543 | This driver supports a Samsung S2MPS11/S2MPS13/S2MPS14/S2MPU02 voltage |
544 | regulator via I2C bus. The chip is comprised of high efficient Buck | 544 | output regulator via I2C bus. The chip is comprised of high efficient |
545 | converters including Dual-Phase Buck converter, Buck-Boost converter, | 545 | Buck converters including Dual-Phase Buck converter, Buck-Boost |
546 | various LDOs. | 546 | converter, various LDOs. |
547 | 547 | ||
548 | config REGULATOR_S5M8767 | 548 | config REGULATOR_S5M8767 |
549 | tristate "Samsung S5M8767A voltage regulator" | 549 | tristate "Samsung S5M8767A voltage regulator" |
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 2fa99a85853f..b345cf51225a 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/of_gpio.h> | 30 | #include <linux/of_gpio.h> |
31 | #include <linux/mfd/samsung/core.h> | 31 | #include <linux/mfd/samsung/core.h> |
32 | #include <linux/mfd/samsung/s2mps11.h> | 32 | #include <linux/mfd/samsung/s2mps11.h> |
33 | #include <linux/mfd/samsung/s2mps13.h> | ||
33 | #include <linux/mfd/samsung/s2mps14.h> | 34 | #include <linux/mfd/samsung/s2mps14.h> |
34 | #include <linux/mfd/samsung/s2mpu02.h> | 35 | #include <linux/mfd/samsung/s2mpu02.h> |
35 | 36 | ||
@@ -45,10 +46,10 @@ struct s2mps11_info { | |||
45 | enum sec_device_type dev_type; | 46 | enum sec_device_type dev_type; |
46 | 47 | ||
47 | /* | 48 | /* |
48 | * One bit for each S2MPS14/S2MPU02 regulator whether the suspend mode | 49 | * One bit for each S2MPS13/S2MPS14/S2MPU02 regulator whether |
49 | * was enabled. | 50 | * the suspend mode was enabled. |
50 | */ | 51 | */ |
51 | unsigned long long s2mps14_suspend_state:35; | 52 | unsigned long long s2mps14_suspend_state:50; |
52 | 53 | ||
53 | /* Array of size rdev_num with GPIO-s for external sleep control */ | 54 | /* Array of size rdev_num with GPIO-s for external sleep control */ |
54 | int *ext_control_gpio; | 55 | int *ext_control_gpio; |
@@ -369,12 +370,101 @@ static const struct regulator_desc s2mps11_regulators[] = { | |||
369 | regulator_desc_s2mps11_buck6_10(10, MIN_750_MV, STEP_12_5_MV), | 370 | regulator_desc_s2mps11_buck6_10(10, MIN_750_MV, STEP_12_5_MV), |
370 | }; | 371 | }; |
371 | 372 | ||
373 | static struct regulator_ops s2mps14_reg_ops; | ||
374 | |||
375 | #define regulator_desc_s2mps13_ldo(num, min, step, min_sel) { \ | ||
376 | .name = "LDO"#num, \ | ||
377 | .id = S2MPS13_LDO##num, \ | ||
378 | .ops = &s2mps14_reg_ops, \ | ||
379 | .type = REGULATOR_VOLTAGE, \ | ||
380 | .owner = THIS_MODULE, \ | ||
381 | .min_uV = min, \ | ||
382 | .uV_step = step, \ | ||
383 | .linear_min_sel = min_sel, \ | ||
384 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
385 | .vsel_reg = S2MPS13_REG_L1CTRL + num - 1, \ | ||
386 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
387 | .enable_reg = S2MPS13_REG_L1CTRL + num - 1, \ | ||
388 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
389 | } | ||
390 | |||
391 | #define regulator_desc_s2mps13_buck(num, min, step, min_sel) { \ | ||
392 | .name = "BUCK"#num, \ | ||
393 | .id = S2MPS13_BUCK##num, \ | ||
394 | .ops = &s2mps14_reg_ops, \ | ||
395 | .type = REGULATOR_VOLTAGE, \ | ||
396 | .owner = THIS_MODULE, \ | ||
397 | .min_uV = min, \ | ||
398 | .uV_step = step, \ | ||
399 | .linear_min_sel = min_sel, \ | ||
400 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | ||
401 | .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \ | ||
402 | .vsel_reg = S2MPS13_REG_B1OUT + (num - 1) * 2, \ | ||
403 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | ||
404 | .enable_reg = S2MPS13_REG_B1CTRL + (num - 1) * 2, \ | ||
405 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
406 | } | ||
407 | |||
408 | static const struct regulator_desc s2mps13_regulators[] = { | ||
409 | regulator_desc_s2mps13_ldo(1, MIN_800_MV, STEP_12_5_MV, 0x00), | ||
410 | regulator_desc_s2mps13_ldo(2, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
411 | regulator_desc_s2mps13_ldo(3, MIN_1000_MV, STEP_25_MV, 0x08), | ||
412 | regulator_desc_s2mps13_ldo(4, MIN_800_MV, STEP_12_5_MV, 0x00), | ||
413 | regulator_desc_s2mps13_ldo(5, MIN_800_MV, STEP_12_5_MV, 0x00), | ||
414 | regulator_desc_s2mps13_ldo(6, MIN_800_MV, STEP_12_5_MV, 0x00), | ||
415 | regulator_desc_s2mps13_ldo(7, MIN_1000_MV, STEP_25_MV, 0x08), | ||
416 | regulator_desc_s2mps13_ldo(8, MIN_1000_MV, STEP_25_MV, 0x08), | ||
417 | regulator_desc_s2mps13_ldo(9, MIN_1000_MV, STEP_25_MV, 0x08), | ||
418 | regulator_desc_s2mps13_ldo(10, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
419 | regulator_desc_s2mps13_ldo(11, MIN_800_MV, STEP_25_MV, 0x10), | ||
420 | regulator_desc_s2mps13_ldo(12, MIN_800_MV, STEP_25_MV, 0x10), | ||
421 | regulator_desc_s2mps13_ldo(13, MIN_800_MV, STEP_25_MV, 0x10), | ||
422 | regulator_desc_s2mps13_ldo(14, MIN_800_MV, STEP_12_5_MV, 0x00), | ||
423 | regulator_desc_s2mps13_ldo(15, MIN_800_MV, STEP_12_5_MV, 0x00), | ||
424 | regulator_desc_s2mps13_ldo(16, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
425 | regulator_desc_s2mps13_ldo(17, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
426 | regulator_desc_s2mps13_ldo(18, MIN_1000_MV, STEP_25_MV, 0x08), | ||
427 | regulator_desc_s2mps13_ldo(19, MIN_1000_MV, STEP_25_MV, 0x08), | ||
428 | regulator_desc_s2mps13_ldo(20, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
429 | regulator_desc_s2mps13_ldo(21, MIN_1000_MV, STEP_25_MV, 0x08), | ||
430 | regulator_desc_s2mps13_ldo(22, MIN_1000_MV, STEP_25_MV, 0x08), | ||
431 | regulator_desc_s2mps13_ldo(23, MIN_800_MV, STEP_12_5_MV, 0x00), | ||
432 | regulator_desc_s2mps13_ldo(24, MIN_800_MV, STEP_12_5_MV, 0x00), | ||
433 | regulator_desc_s2mps13_ldo(25, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
434 | regulator_desc_s2mps13_ldo(26, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
435 | regulator_desc_s2mps13_ldo(27, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
436 | regulator_desc_s2mps13_ldo(28, MIN_1000_MV, STEP_25_MV, 0x08), | ||
437 | regulator_desc_s2mps13_ldo(29, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
438 | regulator_desc_s2mps13_ldo(30, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
439 | regulator_desc_s2mps13_ldo(31, MIN_1000_MV, STEP_25_MV, 0x08), | ||
440 | regulator_desc_s2mps13_ldo(32, MIN_1000_MV, STEP_25_MV, 0x08), | ||
441 | regulator_desc_s2mps13_ldo(33, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
442 | regulator_desc_s2mps13_ldo(34, MIN_1000_MV, STEP_25_MV, 0x08), | ||
443 | regulator_desc_s2mps13_ldo(35, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
444 | regulator_desc_s2mps13_ldo(36, MIN_800_MV, STEP_12_5_MV, 0x00), | ||
445 | regulator_desc_s2mps13_ldo(37, MIN_1000_MV, STEP_25_MV, 0x08), | ||
446 | regulator_desc_s2mps13_ldo(38, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
447 | regulator_desc_s2mps13_ldo(39, MIN_1000_MV, STEP_25_MV, 0x08), | ||
448 | regulator_desc_s2mps13_ldo(40, MIN_1400_MV, STEP_50_MV, 0x0C), | ||
449 | regulator_desc_s2mps13_buck(1, MIN_500_MV, STEP_6_25_MV, 0x10), | ||
450 | regulator_desc_s2mps13_buck(2, MIN_500_MV, STEP_6_25_MV, 0x10), | ||
451 | regulator_desc_s2mps13_buck(3, MIN_500_MV, STEP_6_25_MV, 0x10), | ||
452 | regulator_desc_s2mps13_buck(4, MIN_500_MV, STEP_6_25_MV, 0x10), | ||
453 | regulator_desc_s2mps13_buck(5, MIN_500_MV, STEP_6_25_MV, 0x10), | ||
454 | regulator_desc_s2mps13_buck(6, MIN_500_MV, STEP_6_25_MV, 0x10), | ||
455 | regulator_desc_s2mps13_buck(7, MIN_500_MV, STEP_6_25_MV, 0x10), | ||
456 | regulator_desc_s2mps13_buck(8, MIN_1000_MV, STEP_12_5_MV, 0x20), | ||
457 | regulator_desc_s2mps13_buck(9, MIN_1000_MV, STEP_12_5_MV, 0x20), | ||
458 | regulator_desc_s2mps13_buck(10, MIN_500_MV, STEP_6_25_MV, 0x10), | ||
459 | }; | ||
460 | |||
372 | static int s2mps14_regulator_enable(struct regulator_dev *rdev) | 461 | static int s2mps14_regulator_enable(struct regulator_dev *rdev) |
373 | { | 462 | { |
374 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); | 463 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); |
375 | unsigned int val; | 464 | unsigned int val; |
376 | 465 | ||
377 | switch (s2mps11->dev_type) { | 466 | switch (s2mps11->dev_type) { |
467 | case S2MPS13X: | ||
378 | case S2MPS14X: | 468 | case S2MPS14X: |
379 | if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) | 469 | if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) |
380 | val = S2MPS14_ENABLE_SUSPEND; | 470 | val = S2MPS14_ENABLE_SUSPEND; |
@@ -406,6 +496,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) | |||
406 | 496 | ||
407 | /* Below LDO should be always on or does not support suspend mode. */ | 497 | /* Below LDO should be always on or does not support suspend mode. */ |
408 | switch (s2mps11->dev_type) { | 498 | switch (s2mps11->dev_type) { |
499 | case S2MPS13X: | ||
409 | case S2MPS14X: | 500 | case S2MPS14X: |
410 | switch (rdev_id) { | 501 | switch (rdev_id) { |
411 | case S2MPS14_LDO3: | 502 | case S2MPS14_LDO3: |
@@ -831,6 +922,10 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) | |||
831 | s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators); | 922 | s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators); |
832 | regulators = s2mps11_regulators; | 923 | regulators = s2mps11_regulators; |
833 | break; | 924 | break; |
925 | case S2MPS13X: | ||
926 | s2mps11->rdev_num = ARRAY_SIZE(s2mps13_regulators); | ||
927 | regulators = s2mps13_regulators; | ||
928 | break; | ||
834 | case S2MPS14X: | 929 | case S2MPS14X: |
835 | s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators); | 930 | s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators); |
836 | regulators = s2mps14_regulators; | 931 | regulators = s2mps14_regulators; |
@@ -928,6 +1023,7 @@ out: | |||
928 | 1023 | ||
929 | static const struct platform_device_id s2mps11_pmic_id[] = { | 1024 | static const struct platform_device_id s2mps11_pmic_id[] = { |
930 | { "s2mps11-pmic", S2MPS11X}, | 1025 | { "s2mps11-pmic", S2MPS11X}, |
1026 | { "s2mps13-pmic", S2MPS13X}, | ||
931 | { "s2mps14-pmic", S2MPS14X}, | 1027 | { "s2mps14-pmic", S2MPS14X}, |
932 | { "s2mpu02-pmic", S2MPU02}, | 1028 | { "s2mpu02-pmic", S2MPU02}, |
933 | { }, | 1029 | { }, |
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 8532c3e2aea7..1626dc66e763 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c | |||
@@ -161,7 +161,7 @@ static const struct s3c2410_wdt_variant drv_data_exynos5420 = { | |||
161 | static const struct s3c2410_wdt_variant drv_data_exynos7 = { | 161 | static const struct s3c2410_wdt_variant drv_data_exynos7 = { |
162 | .disable_reg = EXYNOS5_WDT_DISABLE_REG_OFFSET, | 162 | .disable_reg = EXYNOS5_WDT_DISABLE_REG_OFFSET, |
163 | .mask_reset_reg = EXYNOS5_WDT_MASK_RESET_REG_OFFSET, | 163 | .mask_reset_reg = EXYNOS5_WDT_MASK_RESET_REG_OFFSET, |
164 | .mask_bit = 0, | 164 | .mask_bit = 23, |
165 | .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, | 165 | .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, |
166 | .rst_stat_bit = 23, /* A57 WDTRESET */ | 166 | .rst_stat_bit = 23, /* A57 WDTRESET */ |
167 | .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, | 167 | .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, |