sdio_release_host(func);
}
-/* Interrupts when using dedicated WLAN_IRQ pin */
-static irqreturn_t wl1251_line_irq(int irq, void *cookie)
-{
- struct wl1251 *wl = cookie;
-
- ieee80211_queue_work(wl->hw, &wl->irq_work);
-
- return IRQ_HANDLED;
-}
-
static void wl1251_enable_line_irq(struct wl1251 *wl)
{
return enable_irq(wl->irq);
.power = wl1251_sdio_set_power,
};
+static ssize_t
+wl1251_show_long_doze(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct wl1251 *wl = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n", wl->long_doze_mode);
+}
+
+static ssize_t
+wl1251_set_long_doze(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct wl1251 *wl = dev_get_drvdata(dev);
+ int val, ret;
+
+ ret = kstrtoint(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ wl->long_doze_mode = !!val;
+ return count;
+}
+
+static ssize_t
+wl1251_show_ps_rate_thr(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct wl1251 *wl = dev_get_drvdata(dev);
+ return sprintf(buf, "%u\n", wl->ps_rate_threshold);
+}
+
+static ssize_t
+wl1251_set_ps_rate_thr(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct wl1251 *wl = dev_get_drvdata(dev);
+ unsigned int val;
+ int ret;
+
+ ret = kstrtouint(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ wl->ps_rate_threshold = val;
+ return count;
+}
+
+static struct device_attribute wl1251_attrs[] = {
+ __ATTR(long_doze_mode, S_IRUGO | S_IWUGO,
+ wl1251_show_long_doze, wl1251_set_long_doze),
+ __ATTR(ps_rate_threshold, S_IRUGO | S_IWUGO,
+ wl1251_show_ps_rate_thr, wl1251_set_ps_rate_thr),
+};
+
static int wl1251_sdio_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
- int ret;
+ int ret, t;
struct wl1251 *wl;
struct ieee80211_hw *hw;
struct wl1251_sdio *wl_sdio;
if (wl->irq) {
irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
- ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
+
+ ret = request_threaded_irq(wl->irq, NULL, wl1251_irq,
+ IRQF_ONESHOT, "wl1251", wl);
if (ret < 0) {
wl1251_error("request_irq() failed: %d", ret);
goto disable;
sdio_set_drvdata(func, wl);
+ for (t = 0; t < ARRAY_SIZE(wl1251_attrs); t++) {
+ ret = device_create_file(&func->dev, &wl1251_attrs[t]);
+ if (ret) {
+ while (--t >= 0)
+ device_remove_file(&func->dev,
+ &wl1251_attrs[t]);
+ goto out_free_irq;
+ }
+ }
+
/* Tell PM core that we don't need the card to be powered now */
pm_runtime_put_noidle(&func->dev);
{
struct wl1251 *wl = sdio_get_drvdata(func);
struct wl1251_sdio *wl_sdio = wl->if_priv;
+ int t;
/* Undo decrement done above in wl1251_probe */
pm_runtime_get_noresume(&func->dev);
+ for (t = 0; t < ARRAY_SIZE(wl1251_attrs); t++)
+ device_remove_file(&func->dev, &wl1251_attrs[t]);
+
if (wl->irq)
free_irq(wl->irq, wl);
wl1251_free_hw(wl);