aboutsummaryrefslogtreecommitdiffstats
path: root/net/rfkill/rfkill-gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rfkill/rfkill-gpio.c')
-rw-r--r--net/rfkill/rfkill-gpio.c59
1 files changed, 17 insertions, 42 deletions
diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
index bd2a5b90400c..14c98e48f261 100644
--- a/net/rfkill/rfkill-gpio.c
+++ b/net/rfkill/rfkill-gpio.c
@@ -36,8 +36,6 @@ struct rfkill_gpio_data {
36 struct gpio_desc *shutdown_gpio; 36 struct gpio_desc *shutdown_gpio;
37 37
38 struct rfkill *rfkill_dev; 38 struct rfkill *rfkill_dev;
39 char *reset_name;
40 char *shutdown_name;
41 struct clk *clk; 39 struct clk *clk;
42 40
43 bool clk_enabled; 41 bool clk_enabled;
@@ -47,17 +45,14 @@ static int rfkill_gpio_set_power(void *data, bool blocked)
47{ 45{
48 struct rfkill_gpio_data *rfkill = data; 46 struct rfkill_gpio_data *rfkill = data;
49 47
50 if (blocked) { 48 if (!blocked && !IS_ERR(rfkill->clk) && !rfkill->clk_enabled)
51 gpiod_set_value(rfkill->shutdown_gpio, 0); 49 clk_enable(rfkill->clk);
52 gpiod_set_value(rfkill->reset_gpio, 0); 50
53 if (!IS_ERR(rfkill->clk) && rfkill->clk_enabled) 51 gpiod_set_value_cansleep(rfkill->shutdown_gpio, !blocked);
54 clk_disable(rfkill->clk); 52 gpiod_set_value_cansleep(rfkill->reset_gpio, !blocked);
55 } else { 53
56 if (!IS_ERR(rfkill->clk) && !rfkill->clk_enabled) 54 if (blocked && !IS_ERR(rfkill->clk) && rfkill->clk_enabled)
57 clk_enable(rfkill->clk); 55 clk_disable(rfkill->clk);
58 gpiod_set_value(rfkill->reset_gpio, 1);
59 gpiod_set_value(rfkill->shutdown_gpio, 1);
60 }
61 56
62 rfkill->clk_enabled = blocked; 57 rfkill->clk_enabled = blocked;
63 58
@@ -87,10 +82,8 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
87{ 82{
88 struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data; 83 struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data;
89 struct rfkill_gpio_data *rfkill; 84 struct rfkill_gpio_data *rfkill;
90 const char *clk_name = NULL;
91 struct gpio_desc *gpio; 85 struct gpio_desc *gpio;
92 int ret; 86 int ret;
93 int len;
94 87
95 rfkill = devm_kzalloc(&pdev->dev, sizeof(*rfkill), GFP_KERNEL); 88 rfkill = devm_kzalloc(&pdev->dev, sizeof(*rfkill), GFP_KERNEL);
96 if (!rfkill) 89 if (!rfkill)
@@ -101,28 +94,15 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
101 if (ret) 94 if (ret)
102 return ret; 95 return ret;
103 } else if (pdata) { 96 } else if (pdata) {
104 clk_name = pdata->power_clk_name;
105 rfkill->name = pdata->name; 97 rfkill->name = pdata->name;
106 rfkill->type = pdata->type; 98 rfkill->type = pdata->type;
107 } else { 99 } else {
108 return -ENODEV; 100 return -ENODEV;
109 } 101 }
110 102
111 len = strlen(rfkill->name); 103 rfkill->clk = devm_clk_get(&pdev->dev, NULL);
112 rfkill->reset_name = devm_kzalloc(&pdev->dev, len + 7, GFP_KERNEL);
113 if (!rfkill->reset_name)
114 return -ENOMEM;
115
116 rfkill->shutdown_name = devm_kzalloc(&pdev->dev, len + 10, GFP_KERNEL);
117 if (!rfkill->shutdown_name)
118 return -ENOMEM;
119 104
120 snprintf(rfkill->reset_name, len + 6 , "%s_reset", rfkill->name); 105 gpio = devm_gpiod_get_index(&pdev->dev, "reset", 0);
121 snprintf(rfkill->shutdown_name, len + 9, "%s_shutdown", rfkill->name);
122
123 rfkill->clk = devm_clk_get(&pdev->dev, clk_name);
124
125 gpio = devm_gpiod_get_index(&pdev->dev, rfkill->reset_name, 0);
126 if (!IS_ERR(gpio)) { 106 if (!IS_ERR(gpio)) {
127 ret = gpiod_direction_output(gpio, 0); 107 ret = gpiod_direction_output(gpio, 0);
128 if (ret) 108 if (ret)
@@ -130,7 +110,7 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
130 rfkill->reset_gpio = gpio; 110 rfkill->reset_gpio = gpio;
131 } 111 }
132 112
133 gpio = devm_gpiod_get_index(&pdev->dev, rfkill->shutdown_name, 1); 113 gpio = devm_gpiod_get_index(&pdev->dev, "shutdown", 1);
134 if (!IS_ERR(gpio)) { 114 if (!IS_ERR(gpio)) {
135 ret = gpiod_direction_output(gpio, 0); 115 ret = gpiod_direction_output(gpio, 0);
136 if (ret) 116 if (ret)
@@ -146,14 +126,6 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
146 return -EINVAL; 126 return -EINVAL;
147 } 127 }
148 128
149 if (pdata && pdata->gpio_runtime_setup) {
150 ret = pdata->gpio_runtime_setup(pdev);
151 if (ret) {
152 dev_err(&pdev->dev, "can't set up gpio\n");
153 return ret;
154 }
155 }
156
157 rfkill->rfkill_dev = rfkill_alloc(rfkill->name, &pdev->dev, 129 rfkill->rfkill_dev = rfkill_alloc(rfkill->name, &pdev->dev,
158 rfkill->type, &rfkill_gpio_ops, 130 rfkill->type, &rfkill_gpio_ops,
159 rfkill); 131 rfkill);
@@ -174,20 +146,23 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
174static int rfkill_gpio_remove(struct platform_device *pdev) 146static int rfkill_gpio_remove(struct platform_device *pdev)
175{ 147{
176 struct rfkill_gpio_data *rfkill = platform_get_drvdata(pdev); 148 struct rfkill_gpio_data *rfkill = platform_get_drvdata(pdev);
177 struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data;
178 149
179 if (pdata && pdata->gpio_runtime_close)
180 pdata->gpio_runtime_close(pdev);
181 rfkill_unregister(rfkill->rfkill_dev); 150 rfkill_unregister(rfkill->rfkill_dev);
182 rfkill_destroy(rfkill->rfkill_dev); 151 rfkill_destroy(rfkill->rfkill_dev);
183 152
184 return 0; 153 return 0;
185} 154}
186 155
156#ifdef CONFIG_ACPI
187static const struct acpi_device_id rfkill_acpi_match[] = { 157static const struct acpi_device_id rfkill_acpi_match[] = {
158 { "BCM2E1A", RFKILL_TYPE_BLUETOOTH },
159 { "BCM2E39", RFKILL_TYPE_BLUETOOTH },
160 { "BCM2E3D", RFKILL_TYPE_BLUETOOTH },
188 { "BCM4752", RFKILL_TYPE_GPS }, 161 { "BCM4752", RFKILL_TYPE_GPS },
162 { "LNV4752", RFKILL_TYPE_GPS },
189 { }, 163 { },
190}; 164};
165#endif
191 166
192static struct platform_driver rfkill_gpio_driver = { 167static struct platform_driver rfkill_gpio_driver = {
193 .probe = rfkill_gpio_probe, 168 .probe = rfkill_gpio_probe,