Beispiel #1
0
static int pcmcia_device_probe(struct device * dev)
{
	struct pcmcia_device *p_dev;
	struct pcmcia_driver *p_drv;
	int ret = 0;

	dev = get_device(dev);
	if (!dev)
		return -ENODEV;

	p_dev = to_pcmcia_dev(dev);
	p_drv = to_pcmcia_drv(dev->driver);

	if (!try_module_get(p_drv->owner)) {
		ret = -EINVAL;
		goto put_dev;
	}

	if (p_drv->attach) {
		p_dev->instance = p_drv->attach();
		if ((!p_dev->instance) || (p_dev->client.state & CLIENT_UNBOUND)) {
			printk(KERN_NOTICE "ds: unable to create instance "
			       "of '%s'!\n", p_drv->drv.name);
			ret = -EINVAL;
		}
	}

	if (ret)
		module_put(p_drv->owner);
 put_dev:
	if ((ret) || !(p_drv->attach))
		put_device(dev);
	return (ret);
}
static int softingcs_enable_irq(struct platform_device *pdev, int v)
{
	struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent);

	dev_dbg(&pdev->dev, "pcmcia config [0] %02x\n", v ? 0x60 : 0);
	return pcmcia_write_config_byte(pcmcia, 0, v ? 0x60 : 0);
}
Beispiel #3
0
static int pcmcia_device_remove(struct device * dev)
{
	struct pcmcia_device *p_dev;
	struct pcmcia_driver *p_drv;
	int i;

	/* detach the "instance" */
	p_dev = to_pcmcia_dev(dev);
	p_drv = to_pcmcia_drv(dev->driver);
	if (!p_drv)
		return 0;

	if (p_drv->remove)
	       	p_drv->remove(p_dev);

	/* check for proper unloading */
	if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
		printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
		       p_drv->drv.name);

	for (i = 0; i < MAX_WIN; i++)
		if (p_dev->state & CLIENT_WIN_REQ(i))
			printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
			       p_drv->drv.name);

	/* references from pcmcia_probe_device */
	p_dev->state = CLIENT_UNBOUND;
	pcmcia_put_dev(p_dev);
	module_put(p_drv->owner);

	return 0;
}
/*
 * platformdata callbacks
 */
static int softingcs_reset(struct platform_device *pdev, int v)
{
	struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent);

	dev_dbg(&pdev->dev, "pcmcia config [2] %02x\n", v ? 0 : 0x20);
	return pcmcia_write_config_byte(pcmcia, 2, v ? 0 : 0x20);
}
Beispiel #5
0
static void pcmcia_release_dev(struct device *dev)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	ds_dbg(1, "releasing dev %p\n", p_dev);
	pcmcia_put_bus_socket(p_dev->socket->pcmcia);
	kfree(p_dev);
}
Beispiel #6
0
struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev)
{
	struct device *tmp_dev;
	tmp_dev = get_device(&p_dev->dev);
	if (!tmp_dev)
		return NULL;
	return to_pcmcia_dev(tmp_dev);
}
Beispiel #7
0
static int pcmcia_requery(struct device *dev, void * _data)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	if (!p_dev->dev.driver)
		pcmcia_device_query(p_dev);

	return 0;
}
Beispiel #8
0
static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);

	if (p_dev->dev.power.power_state.event != PM_EVENT_ON)
		return sprintf(buf, "off\n");
	else
		return sprintf(buf, "on\n");
}
Beispiel #9
0
static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
	struct pcmcia_device * p_dev = to_pcmcia_dev(dev);
	struct pcmcia_driver * p_drv = to_pcmcia_drv(drv);

	/* matching by cardmgr */
	if (p_dev->cardmgr == p_drv)
		return 1;

	return 0;
}
Beispiel #10
0
static int pcmcia_bus_suspend_callback(struct device *dev, void * _data)
{
	struct pcmcia_socket *skt = _data;
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);

	if (p_dev->socket != skt)
		return 0;

	return dpm_runtime_suspend(dev, PMSG_SUSPEND);
}
Beispiel #11
0
static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
{
	struct pcmcia_socket *skt = _data;
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);

	if (p_dev->socket != skt)
		return 0;

	dpm_runtime_resume(dev);

	return 0;
}
Beispiel #12
0
static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
			     char *buffer, int buffer_size)
{
	struct pcmcia_device *p_dev;
	int i, length = 0;
	u32 hash[4] = { 0, 0, 0, 0};

	if (!dev)
		return -ENODEV;

	p_dev = to_pcmcia_dev(dev);

	/* calculate hashes */
	for (i=0; i<4; i++) {
		if (!p_dev->prod_id[i])
			continue;
		hash[i] = crc32(0, p_dev->prod_id[i], strlen(p_dev->prod_id[i]));
	}

	i = 0;

	if (add_uevent_var(envp, num_envp, &i,
			   buffer, buffer_size, &length,
			   "SOCKET_NO=%u",
			   p_dev->socket->sock))
		return -ENOMEM;

	if (add_uevent_var(envp, num_envp, &i,
			   buffer, buffer_size, &length,
			   "DEVICE_NO=%02X",
			   p_dev->device_no))
		return -ENOMEM;

	if (add_uevent_var(envp, num_envp, &i,
			   buffer, buffer_size, &length,
			   "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
			   "pa%08Xpb%08Xpc%08Xpd%08X",
			   p_dev->has_manf_id ? p_dev->manf_id : 0,
			   p_dev->has_card_id ? p_dev->card_id : 0,
			   p_dev->has_func_id ? p_dev->func_id : 0,
			   p_dev->func,
			   p_dev->device_no,
			   hash[0],
			   hash[1],
			   hash[2],
			   hash[3]))
		return -ENOMEM;

	envp[i] = NULL;

	return 0;
}
Beispiel #13
0
static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	struct pcmcia_driver *p_drv = NULL;

	if (dev->driver)
		p_drv = to_pcmcia_drv(dev->driver);

	if (p_drv && p_drv->suspend)
		return p_drv->suspend(p_dev);

	return 0;
}
Beispiel #14
0
static int pcmcia_dev_resume(struct device * dev)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
        struct pcmcia_driver *p_drv = NULL;

	if (dev->driver)
		p_drv = to_pcmcia_drv(dev->driver);

	if (p_drv && p_drv->resume)
		return p_drv->resume(p_dev);

	return 0;
}
Beispiel #15
0
static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);

	if (!count)
		return -EINVAL;

	down(&p_dev->socket->skt_sem);
	p_dev->allow_func_id_match = 1;
	up(&p_dev->socket->skt_sem);

	bus_rescan_devices(&pcmcia_bus_type);

	return count;
}
Beispiel #16
0
static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
	struct pcmcia_device * p_dev = to_pcmcia_dev(dev);
	struct pcmcia_driver * p_drv = to_pcmcia_drv(drv);
	struct pcmcia_device_id *did = p_drv->id_table;

	/* matching by cardmgr */
	if (p_dev->cardmgr == p_drv)
		return 1;

	while (did && did->match_flags) {
		if (pcmcia_devmatch(p_dev, did))
			return 1;
		did++;
	}

	return 0;
}
Beispiel #17
0
static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute *attr,
				     const char *buf, size_t count)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	int ret = 0;

        if (!count)
                return -EINVAL;

	if ((p_dev->dev.power.power_state.event == PM_EVENT_ON) &&
	    (!strncmp(buf, "off", 3)))
		ret = dpm_runtime_suspend(dev, PMSG_SUSPEND);
	else if ((p_dev->dev.power.power_state.event != PM_EVENT_ON) &&
		 (!strncmp(buf, "on", 2)))
		dpm_runtime_resume(dev);

	return ret ? ret : count;
}
Beispiel #18
0
static int send_event_callback(struct device *dev, void * _data)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	struct send_event_data *data = _data;

	/* we get called for all sockets, but may only pass the event
	 * for drivers _on the affected socket_ */
	if (p_dev->socket != data->skt)
		return 0;

	if (p_dev->client.state & (CLIENT_UNBOUND|CLIENT_STALE))
		return 0;

	if (p_dev->client.EventMask & data->event)
		return EVENT(&p_dev->client, data->event, data->priority);

	return 0;
}
Beispiel #19
0
static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	int i;
	u32 hash[4] = { 0, 0, 0, 0};

	/* calculate hashes */
	for (i=0; i<4; i++) {
		if (!p_dev->prod_id[i])
			continue;
		hash[i] = crc32(0,p_dev->prod_id[i],strlen(p_dev->prod_id[i]));
	}
	return sprintf(buf, "pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
				"pa%08Xpb%08Xpc%08Xpd%08X\n",
				p_dev->has_manf_id ? p_dev->manf_id : 0,
				p_dev->has_card_id ? p_dev->card_id : 0,
				p_dev->has_func_id ? p_dev->func_id : 0,
				p_dev->func, p_dev->device_no,
				hash[0], hash[1], hash[2], hash[3]);
}
Beispiel #20
0
static int pcmcia_device_remove(struct device * dev)
{
	struct pcmcia_device *p_dev;
	struct pcmcia_driver *p_drv;

	/* detach the "instance" */
	p_dev = to_pcmcia_dev(dev);
	p_drv = to_pcmcia_drv(dev->driver);

	if (p_drv) {
		if ((p_drv->detach) && (p_dev->instance)) {
			p_drv->detach(p_dev->instance);
			/* from pcmcia_probe_device */
			put_device(&p_dev->dev);
		}
		module_put(p_drv->owner);
	}

	return 0;
}
/**
 * comedi_to_pcmcia_dev() - comedi_device pointer to pcmcia_device pointer.
 * @dev: comedi_device struct
 */
struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *dev)
{
	return dev->hw_dev ? to_pcmcia_dev(dev->hw_dev) : NULL;
}
Beispiel #22
0
static int pcmcia_device_probe(struct device * dev)
{
	struct pcmcia_device *p_dev;
	struct pcmcia_driver *p_drv;
	struct pcmcia_device_id *did;
	struct pcmcia_socket *s;
	int ret = 0;

	dev = get_device(dev);
	if (!dev)
		return -ENODEV;

	p_dev = to_pcmcia_dev(dev);
	p_drv = to_pcmcia_drv(dev->driver);
	s = p_dev->socket;

	if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) {
		ret = -EINVAL;
		goto put_dev;
	}

	p_dev->state &= ~CLIENT_UNBOUND;

	/* set up the device configuration, if it hasn't been done before */
	if (!s->functions) {
		cistpl_longlink_mfc_t mfc;
		if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC,
				      &mfc) == CS_SUCCESS)
			s->functions = mfc.nfn;
		else
			s->functions = 1;
		s->config = kzalloc(sizeof(config_t) * s->functions,
				    GFP_KERNEL);
		if (!s->config) {
			ret = -ENOMEM;
			goto put_module;
		}
	}

	ret = p_drv->probe(p_dev);
	if (ret)
		goto put_module;

	/* handle pseudo multifunction devices:
	 * there are at most two pseudo multifunction devices.
	 * if we're matching against the first, schedule a
	 * call which will then check whether there are two
	 * pseudo devices, and if not, add the second one.
	 */
	did = (struct pcmcia_device_id *) p_dev->dev.driver_data;
	if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
	    (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
		pcmcia_add_pseudo_device(p_dev->socket);

 put_module:
	if (ret)
		module_put(p_drv->owner);
 put_dev:
	if (ret)
		put_device(dev);
	return (ret);
}