brintos

brintos / linux-shallow public Read only

0
0
Text · 5.6 KiB · c7a9066 Raw
229 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * socket_sysfs.c -- most of socket-related sysfs output4 *5 * (C) 2003 - 2004		Dominik Brodowski6 */7 8#include <linux/module.h>9#include <linux/moduleparam.h>10#include <linux/init.h>11#include <linux/kernel.h>12#include <linux/string.h>13#include <linux/major.h>14#include <linux/errno.h>15#include <linux/mm.h>16#include <linux/interrupt.h>17#include <linux/timer.h>18#include <linux/ioport.h>19#include <linux/delay.h>20#include <linux/pm.h>21#include <linux/device.h>22#include <linux/mutex.h>23#include <asm/irq.h>24 25#include <pcmcia/ss.h>26#include <pcmcia/cistpl.h>27#include <pcmcia/cisreg.h>28#include <pcmcia/ds.h>29#include "cs_internal.h"30 31#define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev)32 33static ssize_t pccard_show_type(struct device *dev, struct device_attribute *attr,34				char *buf)35{36	struct pcmcia_socket *s = to_socket(dev);37 38	if (!(s->state & SOCKET_PRESENT))39		return -ENODEV;40	if (s->state & SOCKET_CARDBUS)41		return sysfs_emit(buf, "32-bit\n");42	return sysfs_emit(buf, "16-bit\n");43}44static DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL);45 46static ssize_t pccard_show_voltage(struct device *dev, struct device_attribute *attr,47				   char *buf)48{49	struct pcmcia_socket *s = to_socket(dev);50 51	if (!(s->state & SOCKET_PRESENT))52		return -ENODEV;53	if (s->socket.Vcc)54		return sysfs_emit(buf, "%d.%dV\n", s->socket.Vcc / 10,55			       s->socket.Vcc % 10);56	return sysfs_emit(buf, "X.XV\n");57}58static DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL);59 60static ssize_t pccard_show_vpp(struct device *dev, struct device_attribute *attr,61			       char *buf)62{63	struct pcmcia_socket *s = to_socket(dev);64	if (!(s->state & SOCKET_PRESENT))65		return -ENODEV;66	return sysfs_emit(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10);67}68static DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL);69 70static ssize_t pccard_show_vcc(struct device *dev, struct device_attribute *attr,71			       char *buf)72{73	struct pcmcia_socket *s = to_socket(dev);74	if (!(s->state & SOCKET_PRESENT))75		return -ENODEV;76	return sysfs_emit(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10);77}78static DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL);79 80 81static ssize_t pccard_store_insert(struct device *dev, struct device_attribute *attr,82				   const char *buf, size_t count)83{84	struct pcmcia_socket *s = to_socket(dev);85 86	if (!count)87		return -EINVAL;88 89	pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT);90 91	return count;92}93static DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert);94 95 96static ssize_t pccard_show_card_pm_state(struct device *dev,97					 struct device_attribute *attr,98					 char *buf)99{100	struct pcmcia_socket *s = to_socket(dev);101	return sysfs_emit(buf, "%s\n", s->state & SOCKET_SUSPEND ? "off" : "on");102}103 104static ssize_t pccard_store_card_pm_state(struct device *dev,105					  struct device_attribute *attr,106					  const char *buf, size_t count)107{108	struct pcmcia_socket *s = to_socket(dev);109	ssize_t ret = count;110 111	if (!count)112		return -EINVAL;113 114	if (!strncmp(buf, "off", 3))115		pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND);116	else {117		if (!strncmp(buf, "on", 2))118			pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME);119		else120			ret = -EINVAL;121	}122 123	return ret;124}125static DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state);126 127static ssize_t pccard_store_eject(struct device *dev,128				  struct device_attribute *attr,129				  const char *buf, size_t count)130{131	struct pcmcia_socket *s = to_socket(dev);132 133	if (!count)134		return -EINVAL;135 136	pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT);137 138	return count;139}140static DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject);141 142 143static ssize_t pccard_show_irq_mask(struct device *dev,144				    struct device_attribute *attr,145				    char *buf)146{147	struct pcmcia_socket *s = to_socket(dev);148	return sysfs_emit(buf, "0x%04x\n", s->irq_mask);149}150 151static ssize_t pccard_store_irq_mask(struct device *dev,152				     struct device_attribute *attr,153				     const char *buf, size_t count)154{155	ssize_t ret;156	struct pcmcia_socket *s = to_socket(dev);157	u32 mask;158 159	if (!count)160		return -EINVAL;161 162	ret = sscanf(buf, "0x%x\n", &mask);163 164	if (ret == 1) {165		mutex_lock(&s->ops_mutex);166		s->irq_mask &= mask;167		mutex_unlock(&s->ops_mutex);168		ret = 0;169	}170 171	return ret ? ret : count;172}173static DEVICE_ATTR(card_irq_mask, 0600, pccard_show_irq_mask, pccard_store_irq_mask);174 175 176static ssize_t pccard_show_resource(struct device *dev,177				    struct device_attribute *attr, char *buf)178{179	struct pcmcia_socket *s = to_socket(dev);180	return sysfs_emit(buf, "%s\n", s->resource_setup_done ? "yes" : "no");181}182 183static ssize_t pccard_store_resource(struct device *dev,184				     struct device_attribute *attr,185				     const char *buf, size_t count)186{187	struct pcmcia_socket *s = to_socket(dev);188 189	if (!count)190		return -EINVAL;191 192	mutex_lock(&s->ops_mutex);193	if (!s->resource_setup_done)194		s->resource_setup_done = 1;195	mutex_unlock(&s->ops_mutex);196 197	pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);198 199	return count;200}201static DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);202 203static struct attribute *pccard_socket_attributes[] = {204	&dev_attr_card_type.attr,205	&dev_attr_card_voltage.attr,206	&dev_attr_card_vpp.attr,207	&dev_attr_card_vcc.attr,208	&dev_attr_card_insert.attr,209	&dev_attr_card_pm_state.attr,210	&dev_attr_card_eject.attr,211	&dev_attr_card_irq_mask.attr,212	&dev_attr_available_resources_setup_done.attr,213	NULL,214};215 216static const struct attribute_group socket_attrs = {217	.attrs = pccard_socket_attributes,218};219 220int pccard_sysfs_add_socket(struct device *dev)221{222	return sysfs_create_group(&dev->kobj, &socket_attrs);223}224 225void pccard_sysfs_remove_socket(struct device *dev)226{227	sysfs_remove_group(&dev->kobj, &socket_attrs);228}229