net: rfkill-bt: auto compatible for uart rts control for all uart bt chip
[firefly-linux-kernel-4.4.55.git] / net / rfkill / core.c
index 1cec5e4f3a5e62ff4503d937d78d435c1761cd52..9f843bbe8c100a96ef63134d9d6246c321640f96 100644 (file)
@@ -14,9 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/kernel.h>
@@ -51,7 +49,6 @@
 struct rfkill {
        spinlock_t              lock;
 
-       const char              *name;
        enum rfkill_type        type;
 
        unsigned long           state;
@@ -75,6 +72,7 @@ struct rfkill {
        struct delayed_work     poll_work;
        struct work_struct      uevent_work;
        struct work_struct      sync_work;
+       char                    name[];
 };
 #define to_rfkill(d)   container_of(d, struct rfkill, dev)
 
@@ -331,7 +329,7 @@ static atomic_t rfkill_input_disabled = ATOMIC_INIT(0);
 /**
  * __rfkill_switch_all - Toggle state of all switches of given type
  * @type: type of interfaces to be affected
- * @state: the new state
+ * @blocked: the new state
  *
  * This function sets the state of all switches of given type,
  * unless a specific switch is claimed by userspace (in which case,
@@ -343,7 +341,15 @@ static void __rfkill_switch_all(const enum rfkill_type type, bool blocked)
 {
        struct rfkill *rfkill;
 
-       rfkill_global_states[type].cur = blocked;
+       if (type == RFKILL_TYPE_ALL) {
+               int i;
+
+               for (i = 0; i < NUM_RFKILL_TYPES; i++)
+                       rfkill_global_states[i].cur = blocked;
+       } else {
+               rfkill_global_states[type].cur = blocked;
+       }
+
        list_for_each_entry(rfkill, &rfkill_list, node) {
                if (rfkill->type != type && type != RFKILL_TYPE_ALL)
                        continue;
@@ -355,7 +361,7 @@ static void __rfkill_switch_all(const enum rfkill_type type, bool blocked)
 /**
  * rfkill_switch_all - Toggle state of all switches of given type
  * @type: type of interfaces to be affected
- * @state: the new state
+ * @blocked: the new state
  *
  * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).
  * Please refer to __rfkill_switch_all() for details.
@@ -576,14 +582,14 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
 }
 EXPORT_SYMBOL(rfkill_set_states);
 
-static ssize_t rfkill_name_show(struct device *dev,
-                               struct device_attribute *attr,
-                               char *buf)
+static ssize_t name_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
 {
        struct rfkill *rfkill = to_rfkill(dev);
 
        return sprintf(buf, "%s\n", rfkill->name);
 }
+static DEVICE_ATTR_RO(name);
 
 static const char *rfkill_get_type_str(enum rfkill_type type)
 {
@@ -611,54 +617,52 @@ static const char *rfkill_get_type_str(enum rfkill_type type)
        }
 }
 
-static ssize_t rfkill_type_show(struct device *dev,
-                               struct device_attribute *attr,
-                               char *buf)
+static ssize_t type_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
 {
        struct rfkill *rfkill = to_rfkill(dev);
 
        return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
 }
+static DEVICE_ATTR_RO(type);
 
-static ssize_t rfkill_idx_show(struct device *dev,
-                              struct device_attribute *attr,
-                              char *buf)
+static ssize_t index_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
 {
        struct rfkill *rfkill = to_rfkill(dev);
 
        return sprintf(buf, "%d\n", rfkill->idx);
 }
+static DEVICE_ATTR_RO(index);
 
-static ssize_t rfkill_persistent_show(struct device *dev,
-                              struct device_attribute *attr,
-                              char *buf)
+static ssize_t persistent_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
 {
        struct rfkill *rfkill = to_rfkill(dev);
 
        return sprintf(buf, "%d\n", rfkill->persistent);
 }
+static DEVICE_ATTR_RO(persistent);
 
-static ssize_t rfkill_hard_show(struct device *dev,
-                                struct device_attribute *attr,
-                                char *buf)
+static ssize_t hard_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
 {
        struct rfkill *rfkill = to_rfkill(dev);
 
        return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_HW) ? 1 : 0 );
 }
+static DEVICE_ATTR_RO(hard);
 
-static ssize_t rfkill_soft_show(struct device *dev,
-                                struct device_attribute *attr,
-                                char *buf)
+static ssize_t soft_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
 {
        struct rfkill *rfkill = to_rfkill(dev);
 
        return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_SW) ? 1 : 0 );
 }
 
-static ssize_t rfkill_soft_store(struct device *dev,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t count)
+static ssize_t soft_store(struct device *dev, struct device_attribute *attr,
+                         const char *buf, size_t count)
 {
        struct rfkill *rfkill = to_rfkill(dev);
        unsigned long state;
@@ -680,6 +684,7 @@ static ssize_t rfkill_soft_store(struct device *dev,
 
        return count;
 }
+static DEVICE_ATTR_RW(soft);
 
 static u8 user_state_from_blocked(unsigned long state)
 {
@@ -691,18 +696,16 @@ static u8 user_state_from_blocked(unsigned long state)
        return RFKILL_USER_STATE_UNBLOCKED;
 }
 
-static ssize_t rfkill_state_show(struct device *dev,
-                                struct device_attribute *attr,
-                                char *buf)
+static ssize_t state_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
 {
        struct rfkill *rfkill = to_rfkill(dev);
 
        return sprintf(buf, "%d\n", user_state_from_blocked(rfkill->state));
 }
 
-static ssize_t rfkill_state_store(struct device *dev,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t count)
+static ssize_t state_store(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
 {
        struct rfkill *rfkill = to_rfkill(dev);
        unsigned long state;
@@ -725,32 +728,27 @@ static ssize_t rfkill_state_store(struct device *dev,
 
        return count;
 }
+static DEVICE_ATTR_RW(state);
 
-static ssize_t rfkill_claim_show(struct device *dev,
-                                struct device_attribute *attr,
-                                char *buf)
+static ssize_t claim_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
 {
        return sprintf(buf, "%d\n", 0);
 }
-
-static ssize_t rfkill_claim_store(struct device *dev,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t count)
-{
-       return -EOPNOTSUPP;
-}
-
-static struct device_attribute rfkill_dev_attrs[] = {
-       __ATTR(name, S_IRUGO, rfkill_name_show, NULL),
-       __ATTR(type, S_IRUGO, rfkill_type_show, NULL),
-       __ATTR(index, S_IRUGO, rfkill_idx_show, NULL),
-       __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL),
-       __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),
-       __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),
-       __ATTR(soft, S_IRUGO|S_IWUSR, rfkill_soft_show, rfkill_soft_store),
-       __ATTR(hard, S_IRUGO, rfkill_hard_show, NULL),
-       __ATTR_NULL
+static DEVICE_ATTR_RO(claim);
+
+static struct attribute *rfkill_dev_attrs[] = {
+       &dev_attr_name.attr,
+       &dev_attr_type.attr,
+       &dev_attr_index.attr,
+       &dev_attr_persistent.attr,
+       &dev_attr_state.attr,
+       &dev_attr_claim.attr,
+       &dev_attr_soft.attr,
+       &dev_attr_hard.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(rfkill_dev);
 
 static void rfkill_release(struct device *dev)
 {
@@ -799,11 +797,13 @@ void rfkill_resume_polling(struct rfkill *rfkill)
        if (!rfkill->ops->poll)
                return;
 
-       schedule_work(&rfkill->poll_work.work);
+       queue_delayed_work(system_power_efficient_wq,
+                          &rfkill->poll_work, 0);
 }
 EXPORT_SYMBOL(rfkill_resume_polling);
 
-static int rfkill_suspend(struct device *dev, pm_message_t state)
+#ifdef CONFIG_RFKILL_PM
+static int rfkill_suspend(struct device *dev)
 {
        struct rfkill *rfkill = to_rfkill(dev);
 
@@ -827,13 +827,20 @@ static int rfkill_resume(struct device *dev)
        return 0;
 }
 
+static SIMPLE_DEV_PM_OPS(rfkill_pm_ops, rfkill_suspend, rfkill_resume);
+#define RFKILL_PM_OPS (&rfkill_pm_ops)
+#else
+#define RFKILL_PM_OPS NULL
+#endif
+
 static struct class rfkill_class = {
        .name           = "rfkill",
        .dev_release    = rfkill_release,
-       .dev_attrs      = rfkill_dev_attrs,
+       .dev_groups     = rfkill_dev_groups,
        .dev_uevent     = rfkill_dev_uevent,
-       .suspend        = rfkill_suspend,
-       .resume         = rfkill_resume,
+#ifdef CONFIG_RFKILL_PM
+       .pm             = RFKILL_PM_OPS,
+#endif
 };
 
 bool rfkill_blocked(struct rfkill *rfkill)
@@ -871,14 +878,14 @@ struct rfkill * __must_check rfkill_alloc(const char *name,
        if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES))
                return NULL;
 
-       rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
+       rfkill = kzalloc(sizeof(*rfkill) + strlen(name) + 1, GFP_KERNEL);
        if (!rfkill)
                return NULL;
 
        spin_lock_init(&rfkill->lock);
        INIT_LIST_HEAD(&rfkill->node);
        rfkill->type = type;
-       rfkill->name = name;
+       strcpy(rfkill->name, name);
        rfkill->ops = ops;
        rfkill->data = ops_data;
 
@@ -904,7 +911,8 @@ static void rfkill_poll(struct work_struct *work)
         */
        rfkill->ops->poll(rfkill, rfkill->data);
 
-       schedule_delayed_work(&rfkill->poll_work,
+       queue_delayed_work(system_power_efficient_wq,
+               &rfkill->poll_work,
                round_jiffies_relative(POLL_INTERVAL));
 }
 
@@ -968,7 +976,8 @@ int __must_check rfkill_register(struct rfkill *rfkill)
        INIT_WORK(&rfkill->sync_work, rfkill_sync_work);
 
        if (rfkill->ops->poll)
-               schedule_delayed_work(&rfkill->poll_work,
+               queue_delayed_work(system_power_efficient_wq,
+                       &rfkill->poll_work,
                        round_jiffies_relative(POLL_INTERVAL));
 
        if (!rfkill->persistent || rfkill_epo_lock_active) {