diff options
| -rw-r--r-- | drivers/acpi/acpi_lpss.c | 88 | ||||
| -rw-r--r-- | drivers/clk/x86/clk-lpt.c | 4 |
2 files changed, 82 insertions, 10 deletions
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 652fd5ce303c..f6d760581faa 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
| @@ -33,11 +33,19 @@ ACPI_MODULE_NAME("acpi_lpss"); | |||
| 33 | #define LPSS_SW_LTR 0x10 | 33 | #define LPSS_SW_LTR 0x10 |
| 34 | #define LPSS_AUTO_LTR 0x14 | 34 | #define LPSS_AUTO_LTR 0x14 |
| 35 | 35 | ||
| 36 | struct lpss_shared_clock { | ||
| 37 | const char *name; | ||
| 38 | unsigned long rate; | ||
| 39 | struct clk *clk; | ||
| 40 | }; | ||
| 41 | |||
| 36 | struct lpss_device_desc { | 42 | struct lpss_device_desc { |
| 37 | bool clk_required; | 43 | bool clk_required; |
| 38 | const char *clkdev_name; | 44 | const char *clkdev_name; |
| 39 | bool ltr_required; | 45 | bool ltr_required; |
| 40 | unsigned int prv_offset; | 46 | unsigned int prv_offset; |
| 47 | bool clk_gate; | ||
| 48 | struct lpss_shared_clock *shared_clock; | ||
| 41 | }; | 49 | }; |
| 42 | 50 | ||
| 43 | static struct lpss_device_desc lpss_dma_desc = { | 51 | static struct lpss_device_desc lpss_dma_desc = { |
| @@ -56,6 +64,7 @@ static struct lpss_device_desc lpt_dev_desc = { | |||
| 56 | .clk_required = true, | 64 | .clk_required = true, |
| 57 | .prv_offset = 0x800, | 65 | .prv_offset = 0x800, |
| 58 | .ltr_required = true, | 66 | .ltr_required = true, |
| 67 | .clk_gate = true, | ||
| 59 | }; | 68 | }; |
| 60 | 69 | ||
| 61 | static struct lpss_device_desc lpt_sdio_dev_desc = { | 70 | static struct lpss_device_desc lpt_sdio_dev_desc = { |
| @@ -63,6 +72,45 @@ static struct lpss_device_desc lpt_sdio_dev_desc = { | |||
| 63 | .ltr_required = true, | 72 | .ltr_required = true, |
| 64 | }; | 73 | }; |
| 65 | 74 | ||
| 75 | static struct lpss_shared_clock uart_clock = { | ||
| 76 | .name = "uart_clk", | ||
| 77 | .rate = 44236800, | ||
| 78 | }; | ||
| 79 | |||
| 80 | static struct lpss_device_desc byt_uart_dev_desc = { | ||
| 81 | .clk_required = true, | ||
| 82 | .prv_offset = 0x800, | ||
| 83 | .clk_gate = true, | ||
| 84 | .shared_clock = &uart_clock, | ||
| 85 | }; | ||
| 86 | |||
| 87 | static struct lpss_shared_clock spi_clock = { | ||
| 88 | .name = "spi_clk", | ||
| 89 | .rate = 50000000, | ||
| 90 | }; | ||
| 91 | |||
| 92 | static struct lpss_device_desc byt_spi_dev_desc = { | ||
| 93 | .clk_required = true, | ||
| 94 | .prv_offset = 0x400, | ||
| 95 | .clk_gate = true, | ||
| 96 | .shared_clock = &spi_clock, | ||
| 97 | }; | ||
| 98 | |||
| 99 | static struct lpss_device_desc byt_sdio_dev_desc = { | ||
| 100 | .clk_required = true, | ||
| 101 | }; | ||
| 102 | |||
| 103 | static struct lpss_shared_clock i2c_clock = { | ||
| 104 | .name = "i2c_clk", | ||
| 105 | .rate = 100000000, | ||
| 106 | }; | ||
| 107 | |||
| 108 | static struct lpss_device_desc byt_i2c_dev_desc = { | ||
| 109 | .clk_required = true, | ||
| 110 | .prv_offset = 0x800, | ||
| 111 | .shared_clock = &i2c_clock, | ||
| 112 | }; | ||
| 113 | |||
| 66 | static const struct acpi_device_id acpi_lpss_device_ids[] = { | 114 | static const struct acpi_device_id acpi_lpss_device_ids[] = { |
| 67 | /* Generic LPSS devices */ | 115 | /* Generic LPSS devices */ |
| 68 | { "INTL9C60", (unsigned long)&lpss_dma_desc }, | 116 | { "INTL9C60", (unsigned long)&lpss_dma_desc }, |
| @@ -77,6 +125,13 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { | |||
| 77 | { "INT33C6", (unsigned long)&lpt_sdio_dev_desc }, | 125 | { "INT33C6", (unsigned long)&lpt_sdio_dev_desc }, |
| 78 | { "INT33C7", }, | 126 | { "INT33C7", }, |
| 79 | 127 | ||
| 128 | /* BayTrail LPSS devices */ | ||
| 129 | { "80860F0A", (unsigned long)&byt_uart_dev_desc }, | ||
| 130 | { "80860F0E", (unsigned long)&byt_spi_dev_desc }, | ||
| 131 | { "80860F14", (unsigned long)&byt_sdio_dev_desc }, | ||
| 132 | { "80860F41", (unsigned long)&byt_i2c_dev_desc }, | ||
| 133 | { "INT33B2", }, | ||
| 134 | |||
| 80 | { } | 135 | { } |
| 81 | }; | 136 | }; |
| 82 | 137 | ||
| @@ -98,7 +153,10 @@ static int register_device_clock(struct acpi_device *adev, | |||
| 98 | struct lpss_private_data *pdata) | 153 | struct lpss_private_data *pdata) |
| 99 | { | 154 | { |
| 100 | const struct lpss_device_desc *dev_desc = pdata->dev_desc; | 155 | const struct lpss_device_desc *dev_desc = pdata->dev_desc; |
| 156 | struct lpss_shared_clock *shared_clock = dev_desc->shared_clock; | ||
| 157 | struct clk *clk = ERR_PTR(-ENODEV); | ||
| 101 | struct lpss_clk_data *clk_data; | 158 | struct lpss_clk_data *clk_data; |
| 159 | const char *parent; | ||
| 102 | 160 | ||
| 103 | if (!lpss_clk_dev) | 161 | if (!lpss_clk_dev) |
| 104 | lpt_register_clock_device(); | 162 | lpt_register_clock_device(); |
| @@ -117,14 +175,30 @@ static int register_device_clock(struct acpi_device *adev, | |||
| 117 | || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE) | 175 | || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE) |
| 118 | return -ENODATA; | 176 | return -ENODATA; |
| 119 | 177 | ||
| 120 | pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev), | 178 | parent = clk_data->name; |
| 121 | clk_data->name, 0, | 179 | |
| 122 | pdata->mmio_base + dev_desc->prv_offset, | 180 | if (shared_clock) { |
| 123 | 0, 0, NULL); | 181 | clk = shared_clock->clk; |
| 124 | if (IS_ERR(pdata->clk)) | 182 | if (!clk) { |
| 125 | return PTR_ERR(pdata->clk); | 183 | clk = clk_register_fixed_rate(NULL, shared_clock->name, |
| 184 | "lpss_clk", 0, | ||
| 185 | shared_clock->rate); | ||
| 186 | shared_clock->clk = clk; | ||
| 187 | } | ||
| 188 | parent = shared_clock->name; | ||
| 189 | } | ||
| 190 | |||
| 191 | if (dev_desc->clk_gate) { | ||
| 192 | clk = clk_register_gate(NULL, dev_name(&adev->dev), parent, 0, | ||
| 193 | pdata->mmio_base + dev_desc->prv_offset, | ||
| 194 | 0, 0, NULL); | ||
| 195 | pdata->clk = clk; | ||
| 196 | } | ||
| 197 | |||
| 198 | if (IS_ERR(clk)) | ||
| 199 | return PTR_ERR(clk); | ||
| 126 | 200 | ||
| 127 | clk_register_clkdev(pdata->clk, NULL, dev_name(&adev->dev)); | 201 | clk_register_clkdev(clk, NULL, dev_name(&adev->dev)); |
| 128 | return 0; | 202 | return 0; |
| 129 | } | 203 | } |
| 130 | 204 | ||
diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c index 4f45eee9e33b..812f83f8b0c6 100644 --- a/drivers/clk/x86/clk-lpt.c +++ b/drivers/clk/x86/clk-lpt.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Intel Lynxpoint LPSS clocks. | 2 | * Intel Low Power Subsystem clocks. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2013, Intel Corporation | 4 | * Copyright (C) 2013, Intel Corporation |
| 5 | * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> | 5 | * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> |
| @@ -18,8 +18,6 @@ | |||
| 18 | #include <linux/platform_data/clk-lpss.h> | 18 | #include <linux/platform_data/clk-lpss.h> |
| 19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 20 | 20 | ||
| 21 | #define PRV_CLOCK_PARAMS 0x800 | ||
| 22 | |||
| 23 | static int lpt_clk_probe(struct platform_device *pdev) | 21 | static int lpt_clk_probe(struct platform_device *pdev) |
| 24 | { | 22 | { |
| 25 | struct lpss_clk_data *drvdata; | 23 | struct lpss_clk_data *drvdata; |
